diff --git a/.editorconfig b/.editorconfig index db08c67e2..1eaf77ae6 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,6 +5,9 @@ root = true #### Core EditorConfig Options #### +# Set default charset +charset = utf-8 + # Indentation and spacing indent_size = 4 indent_style = space @@ -14,8 +17,8 @@ tab_width = 4 end_of_line = lf insert_final_newline = true -# JSON files -[*.json] +# Markdown, JSON, YAML, props and csproj files +[*.{md,json,yml,props,csproj}] # Indentation and spacing indent_size = 2 diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 1516f8a7d..491676acb 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -13,7 +13,7 @@ updates: - package-ecosystem: nuget directory: / - open-pull-requests-limit: 5 + open-pull-requests-limit: 10 schedule: interval: daily labels: @@ -22,3 +22,19 @@ updates: - marysaka commit-message: prefix: nuget + groups: + Avalonia: + patterns: + - "*Avalonia*" + Silk.NET: + patterns: + - "Silk.NET*" + OpenTK: + patterns: + - "OpenTK*" + SixLabors: + patterns: + - "SixLabors*" + NUnit: + patterns: + - "NUnit*" diff --git a/.github/labeler.yml b/.github/labeler.yml index 587830be1..027448437 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -1,33 +1,35 @@ -audio: 'src/Ryujinx.Audio*/**' +audio: +- changed-files: + - any-glob-to-any-file: 'src/Ryujinx.Audio*/**' cpu: - - 'src/ARMeilleure/**' - - 'src/Ryujinx.Cpu/**' - - 'src/Ryujinx.Memory/**' +- changed-files: + - any-glob-to-any-file: ['src/ARMeilleure/**', 'src/Ryujinx.Cpu/**', 'src/Ryujinx.Memory/**'] gpu: - - 'src/Ryujinx.Graphics.*/**' - - 'src/Spv.Generator/**' - - 'src/Ryujinx.ShaderTools/**' +- changed-files: + - any-glob-to-any-file: ['src/Ryujinx.Graphics.*/**', 'src/Spv.Generator/**', 'src/Ryujinx.ShaderTools/**'] + +'graphics-backend:opengl': +- changed-files: + - any-glob-to-any-file: 'src/Ryujinx.Graphics.OpenGL/**' -'graphics-backend:opengl': 'src/Ryujinx.Graphics.OpenGL/**' 'graphics-backend:vulkan': - - 'src/Ryujinx.Graphics.Vulkan/**' - - 'src/Spv.Generator/**' +- changed-files: + - any-glob-to-any-file: ['src/Ryujinx.Graphics.Vulkan/**', 'src/Spv.Generator/**'] gui: - - 'src/Ryujinx/**' - - 'src/Ryujinx.Ui.Common/**' - - 'src/Ryujinx.Ui.LocaleGenerator/**' - - 'src/Ryujinx.Ava/**' +- changed-files: + - any-glob-to-any-file: ['src/Ryujinx/**', 'src/Ryujinx.Ui.Common/**', 'src/Ryujinx.Ui.LocaleGenerator/**', 'src/Ryujinx.Ava/**'] horizon: - - 'src/Ryujinx.HLE/**' - - 'src/Ryujinx.Horizon*/**' +- changed-files: + - any-glob-to-any-file: ['src/Ryujinx.HLE/**', 'src/Ryujinx.Horizon/**'] -kernel: 'src/Ryujinx.HLE/HOS/Kernel/**' +kernel: +- changed-files: + - any-glob-to-any-file: 'src/Ryujinx.HLE/HOS/Kernel/**' infra: - - '.github/**' - - 'distribution/**' - - 'Directory.Packages.props' \ No newline at end of file +- changed-files: + - any-glob-to-any-file: ['.github/**', 'distribution/**', 'Directory.Packages.props'] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7d46adc2c..6124ae513 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,10 +37,10 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-dotnet@v3 + - uses: actions/setup-dotnet@v4 with: global-json-file: global.json - + - name: Overwrite csc problem matcher run: echo "::add-matcher::.github/csc.json" @@ -49,6 +49,16 @@ jobs: run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT shell: bash + - name: Change config filename + run: sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/PRConfig\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs + shell: bash + if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest' + + - name: Change config filename for macOS + run: sed -r -i '' 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/PRConfig\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs + shell: bash + if: github.event_name == 'pull_request' && matrix.os == 'macOS-latest' + - name: Build run: dotnet build -c "${{ matrix.configuration }}" -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER @@ -79,21 +89,21 @@ jobs: if: github.event_name == 'pull_request' && matrix.os == 'ubuntu-latest' - name: Upload Ryujinx artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }} path: publish if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest' - name: Upload Ryujinx.Headless.SDL2 artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }} path: publish_sdl2_headless if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest' - name: Upload Ryujinx.Ava artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }} path: publish_ava @@ -110,7 +120,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-dotnet@v3 + - uses: actions/setup-dotnet@v4 with: global-json-file: global.json @@ -135,6 +145,11 @@ jobs: id: git_short_hash run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT + - name: Change config filename + run: sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/PRConfig\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs + shell: bash + if: github.event_name == 'pull_request' + - name: Publish macOS Ryujinx.Ava run: | ./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER" @@ -144,14 +159,14 @@ jobs: ./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER" - name: Upload Ryujinx.Ava artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal path: "publish_ava/*.tar.gz" if: github.event_name == 'pull_request' - name: Upload Ryujinx.Headless.SDL2 artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal path: "publish_headless/*.tar.gz" diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 2c982d506..2bef2d8e0 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -8,7 +8,7 @@ on: - '!.github/**' - '!*.yml' - '!*.config' - - '!README.md' + - '!*.md' - '.github/workflows/*.yml' permissions: @@ -27,7 +27,7 @@ jobs: with: fetch-depth: 0 - - uses: actions/setup-dotnet@v3 + - uses: actions/setup-dotnet@v4 with: global-json-file: global.json @@ -63,7 +63,7 @@ jobs: - name: Upload report if: failure() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: dotnet-format path: ./*-report.json diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml index c1ae9fe8f..f529bea03 100644 --- a/.github/workflows/flatpak.yml +++ b/.github/workflows/flatpak.yml @@ -28,7 +28,7 @@ jobs: with: path: Ryujinx - - uses: actions/setup-dotnet@v3 + - uses: actions/setup-dotnet@v4 with: global-json-file: Ryujinx/global.json diff --git a/.github/workflows/mako.yml b/.github/workflows/mako.yml new file mode 100644 index 000000000..19165fb04 --- /dev/null +++ b/.github/workflows/mako.yml @@ -0,0 +1,41 @@ +name: Mako +on: + discussion: + types: [created, edited, answered, unanswered, category_changed] + discussion_comment: + types: [created, edited] + gollum: + issue_comment: + types: [created, edited] + issues: + types: [opened, edited, reopened, pinned, milestoned, demilestoned, assigned, unassigned, labeled, unlabeled] + pull_request_target: + types: [opened, edited, reopened, synchronize, ready_for_review, assigned, unassigned] + +jobs: + tasks: + name: Run Ryujinx tasks + permissions: + actions: read + contents: read + discussions: write + issues: write + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + if: github.event_name == 'pull_request_target' + with: + # Ensure we pin the source origin as pull_request_target run under forks. + fetch-depth: 0 + repository: Ryujinx/Ryujinx + ref: master + + - name: Run Mako command + uses: Ryujinx/Ryujinx-Mako@master + with: + command: exec-ryujinx-tasks + args: --event-name "${{ github.event_name }}" --event-path "${{ github.event_path }}" -w "${{ github.workspace }}" "${{ github.repository }}" "${{ github.run_id }}" + app_id: ${{ secrets.MAKO_APP_ID }} + private_key: ${{ secrets.MAKO_PRIVATE_KEY }} + installation_id: ${{ secrets.MAKO_INSTALLATION_ID }} diff --git a/.github/workflows/pr_triage.yml b/.github/workflows/pr_triage.yml index e1c7b8ae8..d8d66b70f 100644 --- a/.github/workflows/pr_triage.yml +++ b/.github/workflows/pr_triage.yml @@ -21,27 +21,8 @@ jobs: repository: Ryujinx/Ryujinx ref: master - - name: Checkout Ryujinx-Mako - uses: actions/checkout@v4 - with: - repository: Ryujinx/Ryujinx-Mako - ref: master - path: '.ryujinx-mako' - - - name: Setup Ryujinx-Mako - uses: ./.ryujinx-mako/.github/actions/setup-mako - - name: Update labels based on changes - uses: actions/labeler@v4 + uses: actions/labeler@v5 with: sync-labels: true dot: true - - - name: Assign reviewers - run: | - poetry -n -C .ryujinx-mako run ryujinx-mako update-reviewers ${{ github.repository }} ${{ github.event.pull_request.number }} .github/reviewers.yml - shell: bash - env: - MAKO_APP_ID: ${{ secrets.MAKO_APP_ID }} - MAKO_PRIVATE_KEY: ${{ secrets.MAKO_PRIVATE_KEY }} - MAKO_INSTALLATION_ID: ${{ secrets.MAKO_INSTALLATION_ID }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4dc1d091d..d6bcd3fa4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,7 +10,7 @@ on: - '*.yml' - '*.json' - '*.config' - - 'README.md' + - '*.md' concurrency: release @@ -64,7 +64,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-dotnet@v3 + - uses: actions/setup-dotnet@v4 with: global-json-file: global.json @@ -85,6 +85,7 @@ jobs: sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs + sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs shell: bash - name: Create output dir @@ -152,7 +153,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-dotnet@v3 + - uses: actions/setup-dotnet@v4 with: global-json-file: global.json @@ -186,6 +187,7 @@ jobs: sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs + sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs shell: bash - name: Publish macOS Ryujinx.Ava diff --git a/Directory.Packages.props b/Directory.Packages.props index 44f9b5d40..b1cebda96 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -3,34 +3,35 @@ true - - - - - - - + + + + + + + - - + + - + + - + - + - - - - + + + + @@ -45,10 +46,9 @@ - - + - + \ No newline at end of file diff --git a/README.md b/README.md index b2f95cc1f..f2f3cb001 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,21 @@ -


- Ryujinx + Ryujinx
Ryujinx
(REE-YOU-JINX)
-

- Ryujinx is an open-source Nintendo Switch emulator, created by gdkchan, written in C#. - This emulator aims at providing excellent accuracy and performance, a user-friendly interface and consistent builds. - It was written from scratch and development on the project began in September 2017. Ryujinx is available on Github under the MIT license.
- + Ryujinx is an open-source Nintendo Switch emulator, created by gdkchan, written in C#. + This emulator aims at providing excellent accuracy and performance, a user-friendly interface and consistent builds. + It was written from scratch and development on the project began in September 2017. + Ryujinx is available on Github under the MIT license. +

+

-
- -
- ## Compatibility -As of April 2023, Ryujinx has been tested on approximately 4,050 titles; over 4,000 boot past menus and into gameplay, with roughly 3,400 of those being considered playable. -You can check out the compatibility list [here](https://github.com/Ryujinx/Ryujinx-Games-List/issues). Anyone is free to submit a new game test or update an existing game test entry; simply follow the new issue template and testing guidelines, or post as a reply to the applicable game issue. Use the search function to see if a game has been tested already! +As of October 2023, Ryujinx has been tested on approximately 4,200 titles; +over 4,150 boot past menus and into gameplay, with roughly 3,500 of those being considered playable. + +You can check out the compatibility list [here](https://github.com/Ryujinx/Ryujinx-Games-List/issues). + +Anyone is free to submit a new game test or update an existing game test entry; +simply follow the new issue template and testing guidelines, or post as a reply to the applicable game issue. +Use the search function to see if a game has been tested already! ## Usage -To run this emulator, your PC must be equipped with at least 8GiB of RAM; failing to meet this requirement may result in a poor gameplay experience or unexpected crashes. +To run this emulator, your PC must be equipped with at least 8GiB of RAM; +failing to meet this requirement may result in a poor gameplay experience or unexpected crashes. See our [Setup & Configuration Guide](https://github.com/Ryujinx/Ryujinx/wiki/Ryujinx-Setup-&-Configuration-Guide) on how to set up the emulator. -For our Local Wireless and LAN builds, see our [Multiplayer: Local Play/Local Wireless Guide +For our Local Wireless (LDN) builds, see our [Multiplayer: Local Play/Local Wireless Guide ](https://github.com/Ryujinx/Ryujinx/wiki/Multiplayer-(LDN-Local-Wireless)-Guide). Avalonia UI comes with translations for various languages. See [Crowdin](https://crwd.in/ryujinx) for more information. ## Latest build -These builds are compiled automatically for each commit on the master branch. While we strive to ensure optimal stability and performance prior to pushing an update, our automated builds **may be unstable or completely broken.** +These builds are compiled automatically for each commit on the master branch. +While we strive to ensure optimal stability and performance prior to pushing an update, our automated builds **may be unstable or completely broken**. If you want to see details on updates to the emulator, you can visit our [Changelog](https://github.com/Ryujinx/Ryujinx/wiki/Changelog). The latest automatic build for Windows, macOS, and Linux can be found on the [Official Website](https://ryujinx.org/download). +## Documentation + +If you are planning to contribute or just want to learn more about this project please read through our [documentation](docs/README.md). ## Building If you wish to build the emulator yourself, follow these steps: ### Step 1 -Install the X64 version of [.NET 8.0 (or higher) SDK](https://dotnet.microsoft.com/download/dotnet/8.0). + +Install the [.NET 8.0 (or higher) SDK](https://dotnet.microsoft.com/download/dotnet/8.0). +Make sure your SDK version is higher or equal to the required version specified in [global.json](global.json). ### Step 2 + Either use `git clone https://github.com/Ryujinx/Ryujinx` on the command line to clone the repository or use Code --> Download zip button to get the files. ### Step 3 -To build Ryujinx, open a command prompt inside the project directory. You can quickly access it on Windows by holding shift in File Explorer, then right clicking and selecting `Open command window here`. Then type the following command: -`dotnet build -c Release -o build` +To build Ryujinx, open a command prompt inside the project directory. +You can quickly access it on Windows by holding shift in File Explorer, then right clicking and selecting `Open command window here`. +Then type the following command: `dotnet build -c Release -o build` the built files will be found in the newly created build directory. -Ryujinx system files are stored in the `Ryujinx` folder. This folder is located in the user folder, which can be accessed by clicking `Open Ryujinx Folder` under the File menu in the GUI. - +Ryujinx system files are stored in the `Ryujinx` folder. +This folder is located in the user folder, which can be accessed by clicking `Open Ryujinx Folder` under the File menu in the GUI. ## Features - - **Audio** +- **Audio** - Audio output is entirely supported, audio input (microphone) isn't supported. We use C# wrappers for [OpenAL](https://openal-soft.org/), and [SDL2](https://www.libsdl.org/) & [libsoundio](http://libsound.io/) as fallbacks. + Audio output is entirely supported, audio input (microphone) isn't supported. + We use C# wrappers for [OpenAL](https://openal-soft.org/), and [SDL2](https://www.libsdl.org/) & [libsoundio](http://libsound.io/) as fallbacks. - **CPU** - The CPU emulator, ARMeilleure, emulates an ARMv8 CPU and currently has support for most 64-bit ARMv8 and some of the ARMv7 (and older) instructions, including partial 32-bit support. It translates the ARM code to a custom IR, performs a few optimizations, and turns that into x86 code. - There are three memory manager options available depending on the user's preference, leveraging both software-based (slower) and host-mapped modes (much faster). The fastest option (host, unchecked) is set by default. - Ryujinx also features an optional Profiled Persistent Translation Cache, which essentially caches translated functions so that they do not need to be translated every time the game loads. The net result is a significant reduction in load times (the amount of time between launching a game and arriving at the title screen) for nearly every game. NOTE: this feature is enabled by default in the Options menu > System tab. You must launch the game at least twice to the title screen or beyond before performance improvements are unlocked on the third launch! These improvements are permanent and do not require any extra launches going forward. + The CPU emulator, ARMeilleure, emulates an ARMv8 CPU and currently has support for most 64-bit ARMv8 and some of the ARMv7 (and older) instructions, including partial 32-bit support. + It translates the ARM code to a custom IR, performs a few optimizations, and turns that into x86 code. + There are three memory manager options available depending on the user's preference, leveraging both software-based (slower) and host-mapped modes (much faster). + The fastest option (host, unchecked) is set by default. + Ryujinx also features an optional Profiled Persistent Translation Cache, which essentially caches translated functions so that they do not need to be translated every time the game loads. + The net result is a significant reduction in load times (the amount of time between launching a game and arriving at the title screen) for nearly every game. + NOTE: This feature is enabled by default in the Options menu > System tab. + You must launch the game at least twice to the title screen or beyond before performance improvements are unlocked on the third launch! + These improvements are permanent and do not require any extra launches going forward. - **GPU** - The GPU emulator emulates the Switch's Maxwell GPU using either the OpenGL (version 4.5 minimum), Vulkan, or Metal (via MoltenVK) APIs through a custom build of OpenTK or Silk.NET respectively. There are currently six graphics enhancements available to the end user in Ryujinx: Disk Shader Caching, Resolution Scaling, Anti-Aliasing, Scaling Filters (including FSR), Anisotropic Filtering and Aspect Ratio Adjustment. These enhancements can be adjusted or toggled as desired in the GUI. + The GPU emulator emulates the Switch's Maxwell GPU using either the OpenGL (version 4.5 minimum), Vulkan, or Metal (via MoltenVK) APIs through a custom build of OpenTK or Silk.NET respectively. + There are currently six graphics enhancements available to the end user in Ryujinx: Disk Shader Caching, Resolution Scaling, Anti-Aliasing, Scaling Filters (including FSR), Anisotropic Filtering and Aspect Ratio Adjustment. + These enhancements can be adjusted or toggled as desired in the GUI. - **Input** - We currently have support for keyboard, mouse, touch input, JoyCon input support, and nearly all controllers. Motion controls are natively supported in most cases; for dual-JoyCon motion support, DS4Windows or BetterJoy are currently required. - In all scenarios, you can set up everything inside the input configuration menu. + We currently have support for keyboard, mouse, touch input, JoyCon input support, and nearly all controllers. + Motion controls are natively supported in most cases; for dual-JoyCon motion support, DS4Windows or BetterJoy are currently required. + In all scenarios, you can set up everything inside the input configuration menu. - **DLC & Modifications** - Ryujinx is able to manage add-on content/downloadable content through the GUI. Mods (romfs, exefs, and runtime mods such as cheats) are also supported; the GUI contains a shortcut to open the respective mods folder for a particular game. + Ryujinx is able to manage add-on content/downloadable content through the GUI. + Mods (romfs, exefs, and runtime mods such as cheats) are also supported; + the GUI contains a shortcut to open the respective mods folder for a particular game. - **Configuration** - The emulator has settings for enabling or disabling some logging, remapping controllers, and more. You can configure all of them through the graphical interface or manually through the config file, `Config.json`, found in the user folder which can be accessed by clicking `Open Ryujinx Folder` under the File menu in the GUI. - + The emulator has settings for enabling or disabling some logging, remapping controllers, and more. + You can configure all of them through the graphical interface or manually through the config file, `Config.json`, found in the user folder which can be accessed by clicking `Open Ryujinx Folder` under the File menu in the GUI. ## Contact -If you have contributions, suggestions, need emulator support or just want to get in touch with the team, join our [Discord server](https://discord.com/invite/Ryujinx). You may also review our [FAQ](https://github.com/Ryujinx/Ryujinx/wiki/Frequently-Asked-Questions). +If you have contributions, suggestions, need emulator support or just want to get in touch with the team, join our [Discord server](https://discord.com/invite/Ryujinx). +You may also review our [FAQ](https://github.com/Ryujinx/Ryujinx/wiki/Frequently-Asked-Questions). ## Donations @@ -134,9 +158,10 @@ All funds received through Patreon are considered a donation to support the proj ## License -This software is licensed under the terms of the
MIT license.
+This software is licensed under the terms of the [MIT license](LICENSE.txt). This project makes use of code authored by the libvpx project, licensed under BSD and the ffmpeg project, licensed under LGPLv3. See [LICENSE.txt](LICENSE.txt) and [THIRDPARTY.md](distribution/legal/THIRDPARTY.md) for more details. + ## Credits - [LibHac](https://github.com/Thealexbarney/LibHac) is used for our file-system. diff --git a/distribution/linux/Ryujinx.desktop b/distribution/linux/Ryujinx.desktop index a4550d104..44f05bf3f 100644 --- a/distribution/linux/Ryujinx.desktop +++ b/distribution/linux/Ryujinx.desktop @@ -4,7 +4,7 @@ Name=Ryujinx Type=Application Icon=Ryujinx Exec=Ryujinx.sh %f -Comment=Plays Nintendo Switch applications +Comment=A Nintendo Switch Emulator GenericName=Nintendo Switch Emulator Terminal=false Categories=Game;Emulator; diff --git a/distribution/linux/Ryujinx.sh b/distribution/linux/Ryujinx.sh old mode 100644 new mode 100755 index f356cad01..a80cdcaec --- a/distribution/linux/Ryujinx.sh +++ b/distribution/linux/Ryujinx.sh @@ -17,4 +17,4 @@ if command -v gamemoderun > /dev/null 2>&1; then COMMAND="$COMMAND gamemoderun" fi -$COMMAND "$SCRIPT_DIR/$RYUJINX_BIN" "$@" \ No newline at end of file +$COMMAND "$SCRIPT_DIR/$RYUJINX_BIN" "$@" diff --git a/distribution/macos/Info.plist b/distribution/macos/Info.plist index 51c71eaa1..53929f95e 100644 --- a/distribution/macos/Info.plist +++ b/distribution/macos/Info.plist @@ -10,14 +10,25 @@ Ryujinx CFBundleIconFile Ryujinx.icns - CFBundleTypeExtensions - - nca - nro - nso - nsp - xci - + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + nca + nro + nso + nsp + xci + + CFBundleTypeName + Nintendo Switch File + CFBundleTypeRole + Viewer + LSHandlerRank + Default + + CFBundleIdentifier org.ryujinx.Ryujinx CFBundleInfoDictionaryVersion diff --git a/distribution/macos/shortcut-launch-script.sh b/distribution/macos/shortcut-launch-script.sh new file mode 100644 index 000000000..784d780aa --- /dev/null +++ b/distribution/macos/shortcut-launch-script.sh @@ -0,0 +1,8 @@ +#!/bin/sh +launch_arch="$(uname -m)" +if [ "$(sysctl -in sysctl.proc_translated)" = "1" ] +then + launch_arch="arm64" +fi + +arch -$launch_arch {0} {1} diff --git a/src/ARMeilleure/Allocators.cs b/src/ARMeilleure/Allocators.cs index ba782b99a..fba302657 100644 --- a/src/ARMeilleure/Allocators.cs +++ b/src/ARMeilleure/Allocators.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Common; +using ARMeilleure.Common; using System; using System.Runtime.CompilerServices; diff --git a/src/ARMeilleure/CodeGen/Linking/Symbol.cs b/src/ARMeilleure/CodeGen/Linking/Symbol.cs index 39e0c3eb1..5559afe09 100644 --- a/src/ARMeilleure/CodeGen/Linking/Symbol.cs +++ b/src/ARMeilleure/CodeGen/Linking/Symbol.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace ARMeilleure.CodeGen.Linking { diff --git a/src/ARMeilleure/CodeGen/Linking/SymbolType.cs b/src/ARMeilleure/CodeGen/Linking/SymbolType.cs index ed348751b..29011a762 100644 --- a/src/ARMeilleure/CodeGen/Linking/SymbolType.cs +++ b/src/ARMeilleure/CodeGen/Linking/SymbolType.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.CodeGen.Linking +namespace ARMeilleure.CodeGen.Linking { /// /// Types of . diff --git a/src/ARMeilleure/CodeGen/Optimizations/BlockPlacement.cs b/src/ARMeilleure/CodeGen/Optimizations/BlockPlacement.cs index 9e243d378..5f0e37721 100644 --- a/src/ARMeilleure/CodeGen/Optimizations/BlockPlacement.cs +++ b/src/ARMeilleure/CodeGen/Optimizations/BlockPlacement.cs @@ -1,4 +1,4 @@ -using ARMeilleure.IntermediateRepresentation; +using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; using System.Diagnostics; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; diff --git a/src/ARMeilleure/CodeGen/Optimizations/TailMerge.cs b/src/ARMeilleure/CodeGen/Optimizations/TailMerge.cs index e94df159c..e63c4da0d 100644 --- a/src/ARMeilleure/CodeGen/Optimizations/TailMerge.cs +++ b/src/ARMeilleure/CodeGen/Optimizations/TailMerge.cs @@ -1,4 +1,4 @@ -using ARMeilleure.IntermediateRepresentation; +using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; using static ARMeilleure.IntermediateRepresentation.Operation.Factory; diff --git a/src/ARMeilleure/CodeGen/RegisterAllocators/LiveIntervalList.cs b/src/ARMeilleure/CodeGen/RegisterAllocators/LiveIntervalList.cs index d999d767b..84b892f42 100644 --- a/src/ARMeilleure/CodeGen/RegisterAllocators/LiveIntervalList.cs +++ b/src/ARMeilleure/CodeGen/RegisterAllocators/LiveIntervalList.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace ARMeilleure.CodeGen.RegisterAllocators { diff --git a/src/ARMeilleure/CodeGen/RegisterAllocators/UseList.cs b/src/ARMeilleure/CodeGen/RegisterAllocators/UseList.cs index a945eccf4..806002f83 100644 --- a/src/ARMeilleure/CodeGen/RegisterAllocators/UseList.cs +++ b/src/ARMeilleure/CodeGen/RegisterAllocators/UseList.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace ARMeilleure.CodeGen.RegisterAllocators { diff --git a/src/ARMeilleure/CodeGen/X86/AssemblerTable.cs b/src/ARMeilleure/CodeGen/X86/AssemblerTable.cs index e4114a335..8910e8891 100644 --- a/src/ARMeilleure/CodeGen/X86/AssemblerTable.cs +++ b/src/ARMeilleure/CodeGen/X86/AssemblerTable.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics.CodeAnalysis; namespace ARMeilleure.CodeGen.X86 diff --git a/src/ARMeilleure/CodeGen/X86/CodeGenCommon.cs b/src/ARMeilleure/CodeGen/X86/CodeGenCommon.cs index 237ecee4e..ae83ea80c 100644 --- a/src/ARMeilleure/CodeGen/X86/CodeGenCommon.cs +++ b/src/ARMeilleure/CodeGen/X86/CodeGenCommon.cs @@ -1,4 +1,4 @@ -using ARMeilleure.IntermediateRepresentation; +using ARMeilleure.IntermediateRepresentation; namespace ARMeilleure.CodeGen.X86 { diff --git a/src/ARMeilleure/CodeGen/X86/Mxcsr.cs b/src/ARMeilleure/CodeGen/X86/Mxcsr.cs index 83d7a5845..719afe59e 100644 --- a/src/ARMeilleure/CodeGen/X86/Mxcsr.cs +++ b/src/ARMeilleure/CodeGen/X86/Mxcsr.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace ARMeilleure.CodeGen.X86 { diff --git a/src/ARMeilleure/CodeGen/X86/X86Optimizer.cs b/src/ARMeilleure/CodeGen/X86/X86Optimizer.cs index 9d23f9ada..690ca5043 100644 --- a/src/ARMeilleure/CodeGen/X86/X86Optimizer.cs +++ b/src/ARMeilleure/CodeGen/X86/X86Optimizer.cs @@ -1,4 +1,4 @@ -using ARMeilleure.CodeGen.Optimizations; +using ARMeilleure.CodeGen.Optimizations; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; using System.Collections.Generic; diff --git a/src/ARMeilleure/Common/AddressTable.cs b/src/ARMeilleure/Common/AddressTable.cs index 9db2d00de..fcab3a202 100644 --- a/src/ARMeilleure/Common/AddressTable.cs +++ b/src/ARMeilleure/Common/AddressTable.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Diagnostics; +using ARMeilleure.Diagnostics; using System; using System.Collections.Generic; using System.Runtime.InteropServices; @@ -9,7 +9,7 @@ namespace ARMeilleure.Common /// Represents a table of guest address to a value. /// /// Type of the value - unsafe class AddressTable : IDisposable where TEntry : unmanaged + public unsafe class AddressTable : IDisposable where TEntry : unmanaged { /// /// Represents a level in an . diff --git a/src/ARMeilleure/Common/Allocator.cs b/src/ARMeilleure/Common/Allocator.cs index 247a8e8bc..6905a614f 100644 --- a/src/ARMeilleure/Common/Allocator.cs +++ b/src/ARMeilleure/Common/Allocator.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace ARMeilleure.Common { diff --git a/src/ARMeilleure/Common/ArenaAllocator.cs b/src/ARMeilleure/Common/ArenaAllocator.cs index f810c2abd..ce8e33913 100644 --- a/src/ARMeilleure/Common/ArenaAllocator.cs +++ b/src/ARMeilleure/Common/ArenaAllocator.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Runtime.CompilerServices; diff --git a/src/ARMeilleure/Common/Counter.cs b/src/ARMeilleure/Common/Counter.cs index d7210d159..6db9561ca 100644 --- a/src/ARMeilleure/Common/Counter.cs +++ b/src/ARMeilleure/Common/Counter.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace ARMeilleure.Common { diff --git a/src/ARMeilleure/Common/EntryTable.cs b/src/ARMeilleure/Common/EntryTable.cs index 6f2057979..625e3f73f 100644 --- a/src/ARMeilleure/Common/EntryTable.cs +++ b/src/ARMeilleure/Common/EntryTable.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Numerics; diff --git a/src/ARMeilleure/Common/NativeAllocator.cs b/src/ARMeilleure/Common/NativeAllocator.cs index 71c04a9b1..93c48adda 100644 --- a/src/ARMeilleure/Common/NativeAllocator.cs +++ b/src/ARMeilleure/Common/NativeAllocator.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; namespace ARMeilleure.Common diff --git a/src/ARMeilleure/Decoders/DecoderMode.cs b/src/ARMeilleure/Decoders/DecoderMode.cs index 280ebb649..708d5c8fb 100644 --- a/src/ARMeilleure/Decoders/DecoderMode.cs +++ b/src/ARMeilleure/Decoders/DecoderMode.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { enum DecoderMode { diff --git a/src/ARMeilleure/Decoders/IOpCode32AluBf.cs b/src/ARMeilleure/Decoders/IOpCode32AluBf.cs index 206c2965e..d1fe59039 100644 --- a/src/ARMeilleure/Decoders/IOpCode32AluBf.cs +++ b/src/ARMeilleure/Decoders/IOpCode32AluBf.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32AluBf { diff --git a/src/ARMeilleure/Decoders/IOpCode32AluImm.cs b/src/ARMeilleure/Decoders/IOpCode32AluImm.cs index 9d49a440d..b89990187 100644 --- a/src/ARMeilleure/Decoders/IOpCode32AluImm.cs +++ b/src/ARMeilleure/Decoders/IOpCode32AluImm.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32AluImm : IOpCode32Alu { diff --git a/src/ARMeilleure/Decoders/IOpCode32AluReg.cs b/src/ARMeilleure/Decoders/IOpCode32AluReg.cs index 1612cc5c9..1a35e664c 100644 --- a/src/ARMeilleure/Decoders/IOpCode32AluReg.cs +++ b/src/ARMeilleure/Decoders/IOpCode32AluReg.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32AluReg : IOpCode32Alu { diff --git a/src/ARMeilleure/Decoders/IOpCode32AluRsImm.cs b/src/ARMeilleure/Decoders/IOpCode32AluRsImm.cs index 8b976b58f..37a2c1000 100644 --- a/src/ARMeilleure/Decoders/IOpCode32AluRsImm.cs +++ b/src/ARMeilleure/Decoders/IOpCode32AluRsImm.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32AluRsImm : IOpCode32Alu { diff --git a/src/ARMeilleure/Decoders/IOpCode32AluRsReg.cs b/src/ARMeilleure/Decoders/IOpCode32AluRsReg.cs index e8c33c2b1..ed9859fc0 100644 --- a/src/ARMeilleure/Decoders/IOpCode32AluRsReg.cs +++ b/src/ARMeilleure/Decoders/IOpCode32AluRsReg.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32AluRsReg : IOpCode32Alu { diff --git a/src/ARMeilleure/Decoders/IOpCode32AluUx.cs b/src/ARMeilleure/Decoders/IOpCode32AluUx.cs index d03c7e219..d390f6b81 100644 --- a/src/ARMeilleure/Decoders/IOpCode32AluUx.cs +++ b/src/ARMeilleure/Decoders/IOpCode32AluUx.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32AluUx : IOpCode32AluReg { diff --git a/src/ARMeilleure/Decoders/IOpCode32Exception.cs b/src/ARMeilleure/Decoders/IOpCode32Exception.cs index 4c1fc231c..c38af9078 100644 --- a/src/ARMeilleure/Decoders/IOpCode32Exception.cs +++ b/src/ARMeilleure/Decoders/IOpCode32Exception.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32Exception { diff --git a/src/ARMeilleure/Decoders/IOpCode32HasSetFlags.cs b/src/ARMeilleure/Decoders/IOpCode32HasSetFlags.cs index 772e1080f..fd9337d9b 100644 --- a/src/ARMeilleure/Decoders/IOpCode32HasSetFlags.cs +++ b/src/ARMeilleure/Decoders/IOpCode32HasSetFlags.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32HasSetFlags { diff --git a/src/ARMeilleure/Decoders/IOpCode32MemEx.cs b/src/ARMeilleure/Decoders/IOpCode32MemEx.cs index aca7200a5..5f6b9321e 100644 --- a/src/ARMeilleure/Decoders/IOpCode32MemEx.cs +++ b/src/ARMeilleure/Decoders/IOpCode32MemEx.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32MemEx : IOpCode32Mem { diff --git a/src/ARMeilleure/Decoders/IOpCode32MemReg.cs b/src/ARMeilleure/Decoders/IOpCode32MemReg.cs index f356e4d7c..6a63f7f69 100644 --- a/src/ARMeilleure/Decoders/IOpCode32MemReg.cs +++ b/src/ARMeilleure/Decoders/IOpCode32MemReg.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32MemReg : IOpCode32Mem { diff --git a/src/ARMeilleure/Decoders/IOpCode32Simd.cs b/src/ARMeilleure/Decoders/IOpCode32Simd.cs index 687254d92..0dccd2679 100644 --- a/src/ARMeilleure/Decoders/IOpCode32Simd.cs +++ b/src/ARMeilleure/Decoders/IOpCode32Simd.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32Simd : IOpCode32, IOpCodeSimd { } } diff --git a/src/ARMeilleure/Decoders/IOpCode32SimdImm.cs b/src/ARMeilleure/Decoders/IOpCode32SimdImm.cs index a0cb669c7..a8e646092 100644 --- a/src/ARMeilleure/Decoders/IOpCode32SimdImm.cs +++ b/src/ARMeilleure/Decoders/IOpCode32SimdImm.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32SimdImm : IOpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32AluBf.cs b/src/ARMeilleure/Decoders/OpCode32AluBf.cs index 0cee34e6d..c34784428 100644 --- a/src/ARMeilleure/Decoders/OpCode32AluBf.cs +++ b/src/ARMeilleure/Decoders/OpCode32AluBf.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32AluBf : OpCode32, IOpCode32AluBf { diff --git a/src/ARMeilleure/Decoders/OpCode32AluImm16.cs b/src/ARMeilleure/Decoders/OpCode32AluImm16.cs index e24edeb41..2af35bd51 100644 --- a/src/ARMeilleure/Decoders/OpCode32AluImm16.cs +++ b/src/ARMeilleure/Decoders/OpCode32AluImm16.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32AluImm16 : OpCode32Alu, IOpCode32AluImm16 { diff --git a/src/ARMeilleure/Decoders/OpCode32AluMla.cs b/src/ARMeilleure/Decoders/OpCode32AluMla.cs index 2cd2b9dcc..bc5d23908 100644 --- a/src/ARMeilleure/Decoders/OpCode32AluMla.cs +++ b/src/ARMeilleure/Decoders/OpCode32AluMla.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32AluMla : OpCode32, IOpCode32AluMla { diff --git a/src/ARMeilleure/Decoders/OpCode32AluReg.cs b/src/ARMeilleure/Decoders/OpCode32AluReg.cs index 493a977f0..9ef7571cf 100644 --- a/src/ARMeilleure/Decoders/OpCode32AluReg.cs +++ b/src/ARMeilleure/Decoders/OpCode32AluReg.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32AluReg : OpCode32Alu, IOpCode32AluReg { diff --git a/src/ARMeilleure/Decoders/OpCode32AluRsReg.cs b/src/ARMeilleure/Decoders/OpCode32AluRsReg.cs index 04740d086..6379b3bde 100644 --- a/src/ARMeilleure/Decoders/OpCode32AluRsReg.cs +++ b/src/ARMeilleure/Decoders/OpCode32AluRsReg.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32AluRsReg : OpCode32Alu, IOpCode32AluRsReg { diff --git a/src/ARMeilleure/Decoders/OpCode32AluUmull.cs b/src/ARMeilleure/Decoders/OpCode32AluUmull.cs index bf80df3ff..44b7ea154 100644 --- a/src/ARMeilleure/Decoders/OpCode32AluUmull.cs +++ b/src/ARMeilleure/Decoders/OpCode32AluUmull.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32AluUmull : OpCode32, IOpCode32AluUmull { diff --git a/src/ARMeilleure/Decoders/OpCode32AluUx.cs b/src/ARMeilleure/Decoders/OpCode32AluUx.cs index 57068675d..68da302fc 100644 --- a/src/ARMeilleure/Decoders/OpCode32AluUx.cs +++ b/src/ARMeilleure/Decoders/OpCode32AluUx.cs @@ -1,4 +1,4 @@ -using ARMeilleure.State; +using ARMeilleure.State; namespace ARMeilleure.Decoders { diff --git a/src/ARMeilleure/Decoders/OpCode32Exception.cs b/src/ARMeilleure/Decoders/OpCode32Exception.cs index b4edcc100..51a535e43 100644 --- a/src/ARMeilleure/Decoders/OpCode32Exception.cs +++ b/src/ARMeilleure/Decoders/OpCode32Exception.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32Exception : OpCode32, IOpCode32Exception { diff --git a/src/ARMeilleure/Decoders/OpCode32MemLdEx.cs b/src/ARMeilleure/Decoders/OpCode32MemLdEx.cs index 520113f46..0f0b37eac 100644 --- a/src/ARMeilleure/Decoders/OpCode32MemLdEx.cs +++ b/src/ARMeilleure/Decoders/OpCode32MemLdEx.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32MemLdEx : OpCode32Mem, IOpCode32MemEx { diff --git a/src/ARMeilleure/Decoders/OpCode32MemReg.cs b/src/ARMeilleure/Decoders/OpCode32MemReg.cs index 786f37fab..d8f1c29b2 100644 --- a/src/ARMeilleure/Decoders/OpCode32MemReg.cs +++ b/src/ARMeilleure/Decoders/OpCode32MemReg.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32MemReg : OpCode32Mem, IOpCode32MemReg { diff --git a/src/ARMeilleure/Decoders/OpCode32MemRsImm.cs b/src/ARMeilleure/Decoders/OpCode32MemRsImm.cs index e1284cf7e..b0e5aa4b9 100644 --- a/src/ARMeilleure/Decoders/OpCode32MemRsImm.cs +++ b/src/ARMeilleure/Decoders/OpCode32MemRsImm.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32MemRsImm : OpCode32Mem, IOpCode32MemRsImm { diff --git a/src/ARMeilleure/Decoders/OpCode32MemStEx.cs b/src/ARMeilleure/Decoders/OpCode32MemStEx.cs index dcf93b224..180a9b5ac 100644 --- a/src/ARMeilleure/Decoders/OpCode32MemStEx.cs +++ b/src/ARMeilleure/Decoders/OpCode32MemStEx.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32MemStEx : OpCode32Mem, IOpCode32MemEx { diff --git a/src/ARMeilleure/Decoders/OpCode32MsrReg.cs b/src/ARMeilleure/Decoders/OpCode32MsrReg.cs index 7186ebf74..dcd06aa01 100644 --- a/src/ARMeilleure/Decoders/OpCode32MsrReg.cs +++ b/src/ARMeilleure/Decoders/OpCode32MsrReg.cs @@ -1,4 +1,4 @@ -using ARMeilleure.State; +using ARMeilleure.State; namespace ARMeilleure.Decoders { diff --git a/src/ARMeilleure/Decoders/OpCode32Simd.cs b/src/ARMeilleure/Decoders/OpCode32Simd.cs index 636aa0a82..1e69b2341 100644 --- a/src/ARMeilleure/Decoders/OpCode32Simd.cs +++ b/src/ARMeilleure/Decoders/OpCode32Simd.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32Simd : OpCode32SimdBase { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdBase.cs b/src/ARMeilleure/Decoders/OpCode32SimdBase.cs index 2361ac1eb..d0634a0e1 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdBase.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdBase.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace ARMeilleure.Decoders { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdBinary.cs b/src/ARMeilleure/Decoders/OpCode32SimdBinary.cs index ba190de96..c0c8277a9 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdBinary.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdBinary.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { /// /// A special alias that always runs in 64 bit int, to speed up binary ops a little. diff --git a/src/ARMeilleure/Decoders/OpCode32SimdCmpZ.cs b/src/ARMeilleure/Decoders/OpCode32SimdCmpZ.cs index 445e67819..d8bc109e7 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdCmpZ.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdCmpZ.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdCmpZ : OpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdCvtFFixed.cs b/src/ARMeilleure/Decoders/OpCode32SimdCvtFFixed.cs index 32faad1ec..200df73ad 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdCvtFFixed.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdCvtFFixed.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdCvtFFixed : OpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdCvtFI.cs b/src/ARMeilleure/Decoders/OpCode32SimdCvtFI.cs index 41cf4d884..ee8f94a4e 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdCvtFI.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdCvtFI.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdCvtFI : OpCode32SimdS { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdDupElem.cs b/src/ARMeilleure/Decoders/OpCode32SimdDupElem.cs index c455b5b4e..b6cdff088 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdDupElem.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdDupElem.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdDupElem : OpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdDupGP.cs b/src/ARMeilleure/Decoders/OpCode32SimdDupGP.cs index 31546ea31..57adea5e6 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdDupGP.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdDupGP.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdDupGP : OpCode32, IOpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdExt.cs b/src/ARMeilleure/Decoders/OpCode32SimdExt.cs index 6dbb5b662..4fe9f25db 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdExt.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdExt.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdExt : OpCode32SimdReg { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdImm.cs b/src/ARMeilleure/Decoders/OpCode32SimdImm.cs index bf0ca527d..9e931e791 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdImm.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdImm.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdImm : OpCode32SimdBase, IOpCode32SimdImm { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdImm44.cs b/src/ARMeilleure/Decoders/OpCode32SimdImm44.cs index fa00a935a..55df1ba6e 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdImm44.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdImm44.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdImm44 : OpCode32, IOpCode32SimdImm { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdLong.cs b/src/ARMeilleure/Decoders/OpCode32SimdLong.cs index 558771a38..5c068de16 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdLong.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdLong.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdLong : OpCode32SimdBase { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdMemImm.cs b/src/ARMeilleure/Decoders/OpCode32SimdMemImm.cs index c933a5ad2..86870dfea 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdMemImm.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdMemImm.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdMemImm : OpCode32, IOpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdMemMult.cs b/src/ARMeilleure/Decoders/OpCode32SimdMemMult.cs index a16a03d3b..c3b8670f8 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdMemMult.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdMemMult.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdMemMult : OpCode32 { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdMemPair.cs b/src/ARMeilleure/Decoders/OpCode32SimdMemPair.cs index 325be4ece..6a18211c6 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdMemPair.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdMemPair.cs @@ -1,4 +1,4 @@ -using ARMeilleure.State; +using ARMeilleure.State; namespace ARMeilleure.Decoders { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdMemSingle.cs b/src/ARMeilleure/Decoders/OpCode32SimdMemSingle.cs index 35dd41c29..5df45000f 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdMemSingle.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdMemSingle.cs @@ -1,4 +1,4 @@ -using ARMeilleure.State; +using ARMeilleure.State; namespace ARMeilleure.Decoders { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdMovGp.cs b/src/ARMeilleure/Decoders/OpCode32SimdMovGp.cs index 5afd34883..35b8cc9f1 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdMovGp.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdMovGp.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdMovGp : OpCode32, IOpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdMovGpDouble.cs b/src/ARMeilleure/Decoders/OpCode32SimdMovGpDouble.cs index 2d6931199..4399fb3c0 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdMovGpDouble.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdMovGpDouble.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdMovGpDouble : OpCode32, IOpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdMovGpElem.cs b/src/ARMeilleure/Decoders/OpCode32SimdMovGpElem.cs index 7816665f3..f6fce7d99 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdMovGpElem.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdMovGpElem.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdMovGpElem : OpCode32, IOpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdReg.cs b/src/ARMeilleure/Decoders/OpCode32SimdReg.cs index 1c46b0e01..eaf17b8c6 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdReg.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdReg.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdReg : OpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdRegElem.cs b/src/ARMeilleure/Decoders/OpCode32SimdRegElem.cs index 173c52652..147de44ba 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdRegElem.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdRegElem.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdRegElem : OpCode32SimdReg { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdRegElemLong.cs b/src/ARMeilleure/Decoders/OpCode32SimdRegElemLong.cs index b87ac4130..8aea44cb0 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdRegElemLong.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdRegElemLong.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdRegElemLong : OpCode32SimdRegElem { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdRegLong.cs b/src/ARMeilleure/Decoders/OpCode32SimdRegLong.cs index 110693835..1349fb479 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdRegLong.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdRegLong.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdRegLong : OpCode32SimdReg { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdRegS.cs b/src/ARMeilleure/Decoders/OpCode32SimdRegS.cs index 8168e83fd..2dfb0074d 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdRegS.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdRegS.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdRegS : OpCode32SimdS { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdRegWide.cs b/src/ARMeilleure/Decoders/OpCode32SimdRegWide.cs index fd2b3bf1d..6f9c639f9 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdRegWide.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdRegWide.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdRegWide : OpCode32SimdReg { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdRev.cs b/src/ARMeilleure/Decoders/OpCode32SimdRev.cs index cb64765f4..26d8be2b9 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdRev.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdRev.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdRev : OpCode32SimdCmpZ { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdS.cs b/src/ARMeilleure/Decoders/OpCode32SimdS.cs index 63c03c019..0bb62cb52 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdS.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdS.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdS : OpCode32, IOpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdSel.cs b/src/ARMeilleure/Decoders/OpCode32SimdSel.cs index cb28418c3..a6667ba19 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdSel.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdSel.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdSel : OpCode32SimdRegS { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdShImm.cs b/src/ARMeilleure/Decoders/OpCode32SimdShImm.cs index 55ddc3958..040dce6f1 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdShImm.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdShImm.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdShImm : OpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdShImmLong.cs b/src/ARMeilleure/Decoders/OpCode32SimdShImmLong.cs index 6b1b0ad1e..13d89ca42 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdShImmLong.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdShImmLong.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdShImmLong : OpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdShImmNarrow.cs b/src/ARMeilleure/Decoders/OpCode32SimdShImmNarrow.cs index 5351e65ff..ce1e79069 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdShImmNarrow.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdShImmNarrow.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdShImmNarrow : OpCode32SimdShImm { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdSpecial.cs b/src/ARMeilleure/Decoders/OpCode32SimdSpecial.cs index 61a9f3870..9b6f47321 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdSpecial.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdSpecial.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdSpecial : OpCode32 { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdSqrte.cs b/src/ARMeilleure/Decoders/OpCode32SimdSqrte.cs index 5b715535a..8f8fa4b03 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdSqrte.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdSqrte.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdSqrte : OpCode32Simd { diff --git a/src/ARMeilleure/Decoders/OpCode32SimdTbl.cs b/src/ARMeilleure/Decoders/OpCode32SimdTbl.cs index c4fb4b9ce..fcac9e014 100644 --- a/src/ARMeilleure/Decoders/OpCode32SimdTbl.cs +++ b/src/ARMeilleure/Decoders/OpCode32SimdTbl.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdTbl : OpCode32SimdReg { diff --git a/src/ARMeilleure/Decoders/OpCode32System.cs b/src/ARMeilleure/Decoders/OpCode32System.cs index 89e93349b..f6f5e0f96 100644 --- a/src/ARMeilleure/Decoders/OpCode32System.cs +++ b/src/ARMeilleure/Decoders/OpCode32System.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32System : OpCode32 { diff --git a/src/ARMeilleure/Decoders/OpCodeSimdHelper.cs b/src/ARMeilleure/Decoders/OpCodeSimdHelper.cs index d900ed9ba..b006cc954 100644 --- a/src/ARMeilleure/Decoders/OpCodeSimdHelper.cs +++ b/src/ARMeilleure/Decoders/OpCodeSimdHelper.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { public static class OpCodeSimdHelper { diff --git a/src/ARMeilleure/Decoders/OpCodeT16AddSubImm3.cs b/src/ARMeilleure/Decoders/OpCodeT16AddSubImm3.cs index cefb50e4a..683d638a8 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16AddSubImm3.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16AddSubImm3.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16AddSubImm3 : OpCodeT16, IOpCode32AluImm { diff --git a/src/ARMeilleure/Decoders/OpCodeT16AddSubReg.cs b/src/ARMeilleure/Decoders/OpCodeT16AddSubReg.cs index 2a407b2d2..201fc8aab 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16AddSubReg.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16AddSubReg.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16AddSubReg : OpCodeT16, IOpCode32AluReg { diff --git a/src/ARMeilleure/Decoders/OpCodeT16AluImm8.cs b/src/ARMeilleure/Decoders/OpCodeT16AluImm8.cs index 673a46045..122698d7e 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16AluImm8.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16AluImm8.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16AluImm8 : OpCodeT16, IOpCode32AluImm { diff --git a/src/ARMeilleure/Decoders/OpCodeT16AluImmZero.cs b/src/ARMeilleure/Decoders/OpCodeT16AluImmZero.cs index b23f8fe03..f67a75f96 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16AluImmZero.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16AluImmZero.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16AluImmZero : OpCodeT16, IOpCode32AluImm { diff --git a/src/ARMeilleure/Decoders/OpCodeT16AluRegHigh.cs b/src/ARMeilleure/Decoders/OpCodeT16AluRegHigh.cs index 6d5ac8fd3..5458f65f2 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16AluRegHigh.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16AluRegHigh.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16AluRegHigh : OpCodeT16, IOpCode32AluReg { diff --git a/src/ARMeilleure/Decoders/OpCodeT16AluRegLow.cs b/src/ARMeilleure/Decoders/OpCodeT16AluRegLow.cs index b37b4f661..f86f48bd4 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16AluRegLow.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16AluRegLow.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16AluRegLow : OpCodeT16, IOpCode32AluReg { diff --git a/src/ARMeilleure/Decoders/OpCodeT16BImm11.cs b/src/ARMeilleure/Decoders/OpCodeT16BImm11.cs index fab098a8f..5ed8a4e6c 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16BImm11.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16BImm11.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16BImm11 : OpCodeT16, IOpCode32BImm { diff --git a/src/ARMeilleure/Decoders/OpCodeT16BImm8.cs b/src/ARMeilleure/Decoders/OpCodeT16BImm8.cs index edfa86ba5..85318e5be 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16BImm8.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16BImm8.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16BImm8 : OpCodeT16, IOpCode32BImm { diff --git a/src/ARMeilleure/Decoders/OpCodeT16BReg.cs b/src/ARMeilleure/Decoders/OpCodeT16BReg.cs index 3122cd07e..da2a007a5 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16BReg.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16BReg.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16BReg : OpCodeT16, IOpCode32BReg { diff --git a/src/ARMeilleure/Decoders/OpCodeT16Exception.cs b/src/ARMeilleure/Decoders/OpCodeT16Exception.cs index bb0050834..8ccdf09ba 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16Exception.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16Exception.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16Exception : OpCodeT16, IOpCode32Exception { diff --git a/src/ARMeilleure/Decoders/OpCodeT16IfThen.cs b/src/ARMeilleure/Decoders/OpCodeT16IfThen.cs index 8c3de689e..ea435a79b 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16IfThen.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16IfThen.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace ARMeilleure.Decoders { diff --git a/src/ARMeilleure/Decoders/OpCodeT16MemImm5.cs b/src/ARMeilleure/Decoders/OpCodeT16MemImm5.cs index 873c63b93..e9b383989 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16MemImm5.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16MemImm5.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Instructions; +using ARMeilleure.Instructions; using System; namespace ARMeilleure.Decoders diff --git a/src/ARMeilleure/Decoders/OpCodeT16MemLit.cs b/src/ARMeilleure/Decoders/OpCodeT16MemLit.cs index f8c16e299..63a452ad3 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16MemLit.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16MemLit.cs @@ -1,4 +1,4 @@ -using ARMeilleure.State; +using ARMeilleure.State; namespace ARMeilleure.Decoders { diff --git a/src/ARMeilleure/Decoders/OpCodeT16MemMult.cs b/src/ARMeilleure/Decoders/OpCodeT16MemMult.cs index 3f3057acd..92b027a6e 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16MemMult.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16MemMult.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Instructions; +using ARMeilleure.Instructions; using System; using System.Numerics; diff --git a/src/ARMeilleure/Decoders/OpCodeT16MemReg.cs b/src/ARMeilleure/Decoders/OpCodeT16MemReg.cs index 71100112e..17d6966b2 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16MemReg.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16MemReg.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16MemReg : OpCodeT16, IOpCode32MemReg { diff --git a/src/ARMeilleure/Decoders/OpCodeT16MemSp.cs b/src/ARMeilleure/Decoders/OpCodeT16MemSp.cs index a038b915b..ed42679a5 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16MemSp.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16MemSp.cs @@ -1,4 +1,4 @@ -using ARMeilleure.State; +using ARMeilleure.State; namespace ARMeilleure.Decoders { diff --git a/src/ARMeilleure/Decoders/OpCodeT16MemStack.cs b/src/ARMeilleure/Decoders/OpCodeT16MemStack.cs index 9d7b0d203..28d5db4d9 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16MemStack.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16MemStack.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Instructions; +using ARMeilleure.Instructions; using ARMeilleure.State; using System; using System.Numerics; diff --git a/src/ARMeilleure/Decoders/OpCodeT16ShiftImm.cs b/src/ARMeilleure/Decoders/OpCodeT16ShiftImm.cs index 8f35e4391..18e7b9e2e 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16ShiftImm.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16ShiftImm.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16ShiftImm : OpCodeT16, IOpCode32AluRsImm { diff --git a/src/ARMeilleure/Decoders/OpCodeT16ShiftReg.cs b/src/ARMeilleure/Decoders/OpCodeT16ShiftReg.cs index 9f8982814..ce47dfb5d 100644 --- a/src/ARMeilleure/Decoders/OpCodeT16ShiftReg.cs +++ b/src/ARMeilleure/Decoders/OpCodeT16ShiftReg.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT16ShiftReg : OpCodeT16, IOpCode32AluRsReg { diff --git a/src/ARMeilleure/Decoders/OpCodeT32.cs b/src/ARMeilleure/Decoders/OpCodeT32.cs index 5ccbd6a27..87a0520d9 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT32 : OpCode32 { diff --git a/src/ARMeilleure/Decoders/OpCodeT32Alu.cs b/src/ARMeilleure/Decoders/OpCodeT32Alu.cs index 1f92f7558..cdef007a9 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32Alu.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32Alu.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT32Alu : OpCodeT32, IOpCode32Alu { diff --git a/src/ARMeilleure/Decoders/OpCodeT32AluImm.cs b/src/ARMeilleure/Decoders/OpCodeT32AluImm.cs index 863d14bda..ce88964c9 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32AluImm.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32AluImm.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Common; +using ARMeilleure.Common; using System.Runtime.Intrinsics; namespace ARMeilleure.Decoders diff --git a/src/ARMeilleure/Decoders/OpCodeT32AluRsImm.cs b/src/ARMeilleure/Decoders/OpCodeT32AluRsImm.cs index edf0298df..dad0d9575 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32AluRsImm.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32AluRsImm.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT32AluRsImm : OpCodeT32Alu, IOpCode32AluRsImm { diff --git a/src/ARMeilleure/Decoders/OpCodeT32BImm20.cs b/src/ARMeilleure/Decoders/OpCodeT32BImm20.cs index 13256ee54..793f82627 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32BImm20.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32BImm20.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT32BImm20 : OpCodeT32, IOpCode32BImm { diff --git a/src/ARMeilleure/Decoders/OpCodeT32BImm24.cs b/src/ARMeilleure/Decoders/OpCodeT32BImm24.cs index d7c606619..d35ab8a45 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32BImm24.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32BImm24.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Instructions; +using ARMeilleure.Instructions; namespace ARMeilleure.Decoders { diff --git a/src/ARMeilleure/Decoders/OpCodeT32MemImm12.cs b/src/ARMeilleure/Decoders/OpCodeT32MemImm12.cs index 4977cdf50..aac8dbfba 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32MemImm12.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32MemImm12.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT32MemImm12 : OpCodeT32, IOpCode32Mem { diff --git a/src/ARMeilleure/Decoders/OpCodeT32MemImm8.cs b/src/ARMeilleure/Decoders/OpCodeT32MemImm8.cs index f84e41400..d80ce86c5 100644 --- a/src/ARMeilleure/Decoders/OpCodeT32MemImm8.cs +++ b/src/ARMeilleure/Decoders/OpCodeT32MemImm8.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCodeT32MemImm8 : OpCodeT32, IOpCode32Mem { diff --git a/src/ARMeilleure/Decoders/OpCodeTable.cs b/src/ARMeilleure/Decoders/OpCodeTable.cs index 9e13bd9b5..edc004125 100644 --- a/src/ARMeilleure/Decoders/OpCodeTable.cs +++ b/src/ARMeilleure/Decoders/OpCodeTable.cs @@ -517,7 +517,10 @@ namespace ARMeilleure.Decoders SetA64("0x00111100>>>xxx100111xxxxxxxxxx", InstName.Sqrshrn_V, InstEmit.Sqrshrn_V, OpCodeSimdShImm.Create); SetA64("0111111100>>>xxx100011xxxxxxxxxx", InstName.Sqrshrun_S, InstEmit.Sqrshrun_S, OpCodeSimdShImm.Create); SetA64("0x10111100>>>xxx100011xxxxxxxxxx", InstName.Sqrshrun_V, InstEmit.Sqrshrun_V, OpCodeSimdShImm.Create); + SetA64("010111110>>>>xxx011101xxxxxxxxxx", InstName.Sqshl_Si, InstEmit.Sqshl_Si, OpCodeSimdShImm.Create); SetA64("0>001110<<1xxxxx010011xxxxxxxxxx", InstName.Sqshl_V, InstEmit.Sqshl_V, OpCodeSimdReg.Create); + SetA64("0000111100>>>xxx011101xxxxxxxxxx", InstName.Sqshl_Vi, InstEmit.Sqshl_Vi, OpCodeSimdShImm.Create); + SetA64("010011110>>>>xxx011101xxxxxxxxxx", InstName.Sqshl_Vi, InstEmit.Sqshl_Vi, OpCodeSimdShImm.Create); SetA64("0101111100>>>xxx100101xxxxxxxxxx", InstName.Sqshrn_S, InstEmit.Sqshrn_S, OpCodeSimdShImm.Create); SetA64("0x00111100>>>xxx100101xxxxxxxxxx", InstName.Sqshrn_V, InstEmit.Sqshrn_V, OpCodeSimdShImm.Create); SetA64("0111111100>>>xxx100001xxxxxxxxxx", InstName.Sqshrun_S, InstEmit.Sqshrun_S, OpCodeSimdShImm.Create); @@ -872,6 +875,7 @@ namespace ARMeilleure.Decoders SetVfp("<<<<11100x10xxxxxxxx101xx1x0xxxx", InstName.Vnmul, InstEmit32.Vnmul_S, OpCode32SimdRegS.Create, OpCode32SimdRegS.CreateT32); SetVfp("111111101x1110xxxxxx101x01x0xxxx", InstName.Vrint, InstEmit32.Vrint_RM, OpCode32SimdS.Create, OpCode32SimdS.CreateT32); SetVfp("<<<<11101x110110xxxx101x11x0xxxx", InstName.Vrint, InstEmit32.Vrint_Z, OpCode32SimdS.Create, OpCode32SimdS.CreateT32); + SetVfp("<<<<11101x110110xxxx101x01x0xxxx", InstName.Vrintr, InstEmit32.Vrintr_S, OpCode32SimdS.Create, OpCode32SimdS.CreateT32); SetVfp("<<<<11101x110111xxxx101x01x0xxxx", InstName.Vrintx, InstEmit32.Vrintx_S, OpCode32SimdS.Create, OpCode32SimdS.CreateT32); SetVfp("<<<<11101x110001xxxx101x11x0xxxx", InstName.Vsqrt, InstEmit32.Vsqrt_S, OpCode32SimdS.Create, OpCode32SimdS.CreateT32); SetVfp("111111100xxxxxxxxxxx101xx0x0xxxx", InstName.Vsel, InstEmit32.Vsel, OpCode32SimdSel.Create, OpCode32SimdSel.CreateT32); @@ -992,6 +996,7 @@ namespace ARMeilleure.Decoders SetAsimd("1111001x1x000xxxxxxx< context.Add(context.Add(op1, op2), op3), op.Opc != 1); + } + public static void Vpaddl(ArmEmitterContext context) { OpCode32Simd op = (OpCode32Simd)context.CurrOp; diff --git a/src/ARMeilleure/Instructions/InstEmitSimdCmp32.cs b/src/ARMeilleure/Instructions/InstEmitSimdCmp32.cs index a990e057d..1d68bce6b 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdCmp32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdCmp32.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Decoders; +using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; diff --git a/src/ARMeilleure/Instructions/InstEmitSimdCrypto32.cs b/src/ARMeilleure/Instructions/InstEmitSimdCrypto32.cs index 24fd7c87e..7a0c981e7 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdCrypto32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdCrypto32.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Decoders; +using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; diff --git a/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs b/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs index b03855910..8eef6b14d 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Decoders; +using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; @@ -578,6 +578,22 @@ namespace ARMeilleure.Instructions } } + // VRINTR (floating-point). + public static void Vrintr_S(ArmEmitterContext context) + { + if (Optimizations.UseAdvSimd) + { + InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, Intrinsic.Arm64FrintiS); + } + else + { + EmitScalarUnaryOpF32(context, (op1) => + { + return EmitRoundByRMode(context, op1); + }); + } + } + // VRINTZ (floating-point). public static void Vrint_Z(ArmEmitterContext context) { diff --git a/src/ARMeilleure/Instructions/InstEmitSimdHelper32.cs b/src/ARMeilleure/Instructions/InstEmitSimdHelper32.cs index c1c59b87b..2f021a1a1 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdHelper32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdHelper32.cs @@ -673,6 +673,35 @@ namespace ARMeilleure.Instructions context.Copy(GetVecA32(op.Qd), res); } + public static void EmitVectorPairwiseTernaryLongOpI32(ArmEmitterContext context, Func3I emit, bool signed) + { + OpCode32Simd op = (OpCode32Simd)context.CurrOp; + + int elems = op.GetBytesCount() >> op.Size; + int pairs = elems >> 1; + + Operand res = GetVecA32(op.Qd); + + for (int index = 0; index < pairs; index++) + { + int pairIndex = index * 2; + Operand m1 = EmitVectorExtract32(context, op.Qm, op.Im + pairIndex, op.Size, signed); + Operand m2 = EmitVectorExtract32(context, op.Qm, op.Im + pairIndex + 1, op.Size, signed); + + if (op.Size == 2) + { + m1 = signed ? context.SignExtend32(OperandType.I64, m1) : context.ZeroExtend32(OperandType.I64, m1); + m2 = signed ? context.SignExtend32(OperandType.I64, m2) : context.ZeroExtend32(OperandType.I64, m2); + } + + Operand d1 = EmitVectorExtract32(context, op.Qd, op.Id + index, op.Size + 1, signed); + + res = EmitVectorInsert(context, res, emit(m1, m2, d1), op.Id + index, op.Size + 1); + } + + context.Copy(GetVecA32(op.Qd), res); + } + // Narrow public static void EmitVectorUnaryNarrowOp32(ArmEmitterContext context, Func1I emit, bool signed = false) diff --git a/src/ARMeilleure/Instructions/InstEmitSimdLogical32.cs b/src/ARMeilleure/Instructions/InstEmitSimdLogical32.cs index 747acb101..26d093447 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdLogical32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdLogical32.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Decoders; +using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; diff --git a/src/ARMeilleure/Instructions/InstEmitSimdMemory32.cs b/src/ARMeilleure/Instructions/InstEmitSimdMemory32.cs index b774bd061..35c6dd328 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdMemory32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdMemory32.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Decoders; +using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; diff --git a/src/ARMeilleure/Instructions/InstEmitSimdMove32.cs b/src/ARMeilleure/Instructions/InstEmitSimdMove32.cs index 050d35e9d..9fa740997 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdMove32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdMove32.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Decoders; +using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; using System; diff --git a/src/ARMeilleure/Instructions/InstEmitSimdShift.cs b/src/ARMeilleure/Instructions/InstEmitSimdShift.cs index be0670645..94e912579 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdShift.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdShift.cs @@ -116,7 +116,7 @@ namespace ARMeilleure.Instructions } else if (shift >= eSize) { - if ((op.RegisterSize == RegisterSize.Simd64)) + if (op.RegisterSize == RegisterSize.Simd64) { Operand res = context.VectorZeroUpper64(GetVec(op.Rd)); @@ -359,6 +359,16 @@ namespace ARMeilleure.Instructions } } + public static void Sqshl_Si(ArmEmitterContext context) + { + EmitShlImmOp(context, signedDst: true, ShlRegFlags.Signed | ShlRegFlags.Scalar | ShlRegFlags.Saturating); + } + + public static void Sqshl_Vi(ArmEmitterContext context) + { + EmitShlImmOp(context, signedDst: true, ShlRegFlags.Signed | ShlRegFlags.Saturating); + } + public static void Sqshrn_S(ArmEmitterContext context) { if (Optimizations.UseAdvSimd) @@ -1593,6 +1603,99 @@ namespace ARMeilleure.Instructions Saturating = 1 << 3, } + private static void EmitShlImmOp(ArmEmitterContext context, bool signedDst, ShlRegFlags flags = ShlRegFlags.None) + { + bool scalar = flags.HasFlag(ShlRegFlags.Scalar); + bool signed = flags.HasFlag(ShlRegFlags.Signed); + bool saturating = flags.HasFlag(ShlRegFlags.Saturating); + + OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp; + + Operand res = context.VectorZero(); + + int elems = !scalar ? op.GetBytesCount() >> op.Size : 1; + + for (int index = 0; index < elems; index++) + { + Operand ne = EmitVectorExtract(context, op.Rn, index, op.Size, signed); + + Operand e = !saturating + ? EmitShlImm(context, ne, GetImmShl(op), op.Size) + : EmitShlImmSatQ(context, ne, GetImmShl(op), op.Size, signed, signedDst); + + res = EmitVectorInsert(context, res, e, index, op.Size); + } + + context.Copy(GetVec(op.Rd), res); + } + + private static Operand EmitShlImm(ArmEmitterContext context, Operand op, int shiftLsB, int size) + { + int eSize = 8 << size; + + Debug.Assert(op.Type == OperandType.I64); + Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64); + + Operand res = context.AllocateLocal(OperandType.I64); + + if (shiftLsB >= eSize) + { + Operand shl = context.ShiftLeft(op, Const(shiftLsB)); + context.Copy(res, shl); + } + else + { + Operand zeroL = Const(0L); + context.Copy(res, zeroL); + } + + return res; + } + + private static Operand EmitShlImmSatQ(ArmEmitterContext context, Operand op, int shiftLsB, int size, bool signedSrc, bool signedDst) + { + int eSize = 8 << size; + + Debug.Assert(op.Type == OperandType.I64); + Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64); + + Operand lblEnd = Label(); + + Operand res = context.Copy(context.AllocateLocal(OperandType.I64), op); + + if (shiftLsB >= eSize) + { + context.Copy(res, signedSrc + ? EmitSignedSignSatQ(context, op, size) + : EmitUnsignedSignSatQ(context, op, size)); + } + else + { + Operand shl = context.ShiftLeft(op, Const(shiftLsB)); + if (eSize == 64) + { + Operand sarOrShr = signedSrc + ? context.ShiftRightSI(shl, Const(shiftLsB)) + : context.ShiftRightUI(shl, Const(shiftLsB)); + context.Copy(res, shl); + context.BranchIf(lblEnd, sarOrShr, op, Comparison.Equal); + context.Copy(res, signedSrc + ? EmitSignedSignSatQ(context, op, size) + : EmitUnsignedSignSatQ(context, op, size)); + } + else + { + context.Copy(res, signedSrc + ? EmitSignedSrcSatQ(context, shl, size, signedDst) + : EmitUnsignedSrcSatQ(context, shl, size, signedDst)); + } + } + + context.MarkLabel(lblEnd); + + return res; + } + private static void EmitShlRegOp(ArmEmitterContext context, ShlRegFlags flags = ShlRegFlags.None) { bool scalar = flags.HasFlag(ShlRegFlags.Scalar); diff --git a/src/ARMeilleure/Instructions/InstEmitSimdShift32.cs b/src/ARMeilleure/Instructions/InstEmitSimdShift32.cs index 5c7d48287..e40600a47 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdShift32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdShift32.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Decoders; +using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; diff --git a/src/ARMeilleure/Instructions/InstEmitSystem32.cs b/src/ARMeilleure/Instructions/InstEmitSystem32.cs index 82e625715..74d6169c6 100644 --- a/src/ARMeilleure/Instructions/InstEmitSystem32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSystem32.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Decoders; +using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; diff --git a/src/ARMeilleure/Instructions/InstName.cs b/src/ARMeilleure/Instructions/InstName.cs index 32ae38dad..457abbf49 100644 --- a/src/ARMeilleure/Instructions/InstName.cs +++ b/src/ARMeilleure/Instructions/InstName.cs @@ -384,7 +384,9 @@ namespace ARMeilleure.Instructions Sqrshrn_V, Sqrshrun_S, Sqrshrun_V, + Sqshl_Si, Sqshl_V, + Sqshl_Vi, Sqshrn_S, Sqshrn_V, Sqshrun_S, @@ -635,6 +637,7 @@ namespace ARMeilleure.Instructions Vorn, Vorr, Vpadd, + Vpadal, Vpaddl, Vpmax, Vpmin, @@ -654,6 +657,7 @@ namespace ARMeilleure.Instructions Vrintm, Vrintn, Vrintp, + Vrintr, Vrintx, Vrshr, Vrshrn, diff --git a/src/ARMeilleure/IntermediateRepresentation/BasicBlockFrequency.cs b/src/ARMeilleure/IntermediateRepresentation/BasicBlockFrequency.cs index 74aaea6b1..e4f7ae809 100644 --- a/src/ARMeilleure/IntermediateRepresentation/BasicBlockFrequency.cs +++ b/src/ARMeilleure/IntermediateRepresentation/BasicBlockFrequency.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.IntermediateRepresentation +namespace ARMeilleure.IntermediateRepresentation { enum BasicBlockFrequency { diff --git a/src/ARMeilleure/IntermediateRepresentation/Comparison.cs b/src/ARMeilleure/IntermediateRepresentation/Comparison.cs index e3a68b49d..3d6a9d818 100644 --- a/src/ARMeilleure/IntermediateRepresentation/Comparison.cs +++ b/src/ARMeilleure/IntermediateRepresentation/Comparison.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.IntermediateRepresentation +namespace ARMeilleure.IntermediateRepresentation { enum Comparison { diff --git a/src/ARMeilleure/IntermediateRepresentation/IIntrusiveListNode.cs b/src/ARMeilleure/IntermediateRepresentation/IIntrusiveListNode.cs index caa9b83fe..05be8a5ae 100644 --- a/src/ARMeilleure/IntermediateRepresentation/IIntrusiveListNode.cs +++ b/src/ARMeilleure/IntermediateRepresentation/IIntrusiveListNode.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.IntermediateRepresentation +namespace ARMeilleure.IntermediateRepresentation { interface IIntrusiveListNode { diff --git a/src/ARMeilleure/IntermediateRepresentation/IntrusiveList.cs b/src/ARMeilleure/IntermediateRepresentation/IntrusiveList.cs index 184df87c8..8d300075d 100644 --- a/src/ARMeilleure/IntermediateRepresentation/IntrusiveList.cs +++ b/src/ARMeilleure/IntermediateRepresentation/IntrusiveList.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; diff --git a/src/ARMeilleure/IntermediateRepresentation/PhiOperation.cs b/src/ARMeilleure/IntermediateRepresentation/PhiOperation.cs index d2a3cf218..672c280fa 100644 --- a/src/ARMeilleure/IntermediateRepresentation/PhiOperation.cs +++ b/src/ARMeilleure/IntermediateRepresentation/PhiOperation.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Translation; +using ARMeilleure.Translation; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; namespace ARMeilleure.IntermediateRepresentation diff --git a/src/ARMeilleure/Memory/IJitMemoryAllocator.cs b/src/ARMeilleure/Memory/IJitMemoryAllocator.cs index 19b696b0a..ff64bf13e 100644 --- a/src/ARMeilleure/Memory/IJitMemoryAllocator.cs +++ b/src/ARMeilleure/Memory/IJitMemoryAllocator.cs @@ -1,10 +1,8 @@ -namespace ARMeilleure.Memory +namespace ARMeilleure.Memory { public interface IJitMemoryAllocator { IJitMemoryBlock Allocate(ulong size); IJitMemoryBlock Reserve(ulong size); - - ulong GetPageSize(); } } diff --git a/src/ARMeilleure/Memory/IJitMemoryBlock.cs b/src/ARMeilleure/Memory/IJitMemoryBlock.cs index e94b0a60d..c103fe8d1 100644 --- a/src/ARMeilleure/Memory/IJitMemoryBlock.cs +++ b/src/ARMeilleure/Memory/IJitMemoryBlock.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace ARMeilleure.Memory { @@ -8,6 +8,7 @@ namespace ARMeilleure.Memory void Commit(ulong offset, ulong size); + void MapAsRw(ulong offset, ulong size); void MapAsRx(ulong offset, ulong size); void MapAsRwx(ulong offset, ulong size); } diff --git a/src/ARMeilleure/Memory/IMemoryManager.cs b/src/ARMeilleure/Memory/IMemoryManager.cs index ec5b81ebe..952cd2b4f 100644 --- a/src/ARMeilleure/Memory/IMemoryManager.cs +++ b/src/ARMeilleure/Memory/IMemoryManager.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace ARMeilleure.Memory { diff --git a/src/ARMeilleure/Memory/MemoryManagerType.cs b/src/ARMeilleure/Memory/MemoryManagerType.cs index e897a038f..b1cdbb069 100644 --- a/src/ARMeilleure/Memory/MemoryManagerType.cs +++ b/src/ARMeilleure/Memory/MemoryManagerType.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.Memory +namespace ARMeilleure.Memory { /// /// Indicates the type of a memory manager and the method it uses for memory mapping @@ -31,7 +31,7 @@ HostMappedUnsafe, } - static class MemoryManagerTypeExtensions + public static class MemoryManagerTypeExtensions { public static bool IsHostMapped(this MemoryManagerType type) { diff --git a/src/ARMeilleure/Memory/ReservedRegion.cs b/src/ARMeilleure/Memory/ReservedRegion.cs index 2197afad9..3870d4c84 100644 --- a/src/ARMeilleure/Memory/ReservedRegion.cs +++ b/src/ARMeilleure/Memory/ReservedRegion.cs @@ -1,8 +1,8 @@ -using System; +using System; namespace ARMeilleure.Memory { - class ReservedRegion + public class ReservedRegion { public const int DefaultGranularity = 65536; // Mapping granularity in Windows. diff --git a/src/ARMeilleure/Native/JitSupportDarwin.cs b/src/ARMeilleure/Native/JitSupportDarwin.cs index ed347b9cf..339460397 100644 --- a/src/ARMeilleure/Native/JitSupportDarwin.cs +++ b/src/ARMeilleure/Native/JitSupportDarwin.cs @@ -5,7 +5,7 @@ using System.Runtime.Versioning; namespace ARMeilleure.Native { [SupportedOSPlatform("macos")] - internal static partial class JitSupportDarwin + static partial class JitSupportDarwin { [LibraryImport("libarmeilleure-jitsupport", EntryPoint = "armeilleure_jit_memcpy")] public static partial void Copy(IntPtr dst, IntPtr src, ulong n); diff --git a/src/ARMeilleure/Signal/NativeSignalHandler.cs b/src/ARMeilleure/Signal/NativeSignalHandlerGenerator.cs similarity index 61% rename from src/ARMeilleure/Signal/NativeSignalHandler.cs rename to src/ARMeilleure/Signal/NativeSignalHandlerGenerator.cs index 3f0e9e4bf..c5e708e16 100644 --- a/src/ARMeilleure/Signal/NativeSignalHandler.cs +++ b/src/ARMeilleure/Signal/NativeSignalHandlerGenerator.cs @@ -1,63 +1,14 @@ -using ARMeilleure.IntermediateRepresentation; -using ARMeilleure.Memory; +using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; -using ARMeilleure.Translation.Cache; using System; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; namespace ARMeilleure.Signal { - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct SignalHandlerRange + public static class NativeSignalHandlerGenerator { - public int IsActive; - public nuint RangeAddress; - public nuint RangeEndAddress; - public IntPtr ActionPointer; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct SignalHandlerConfig - { - /// - /// The byte offset of the faulting address in the SigInfo or ExceptionRecord struct. - /// - public int StructAddressOffset; - - /// - /// The byte offset of the write flag in the SigInfo or ExceptionRecord struct. - /// - public int StructWriteOffset; - - /// - /// The sigaction handler that was registered before this one. (unix only) - /// - public nuint UnixOldSigaction; - - /// - /// The type of the previous sigaction. True for the 3 argument variant. (unix only) - /// - public int UnixOldSigaction3Arg; - - public SignalHandlerRange Range0; - public SignalHandlerRange Range1; - public SignalHandlerRange Range2; - public SignalHandlerRange Range3; - public SignalHandlerRange Range4; - public SignalHandlerRange Range5; - public SignalHandlerRange Range6; - public SignalHandlerRange Range7; - } - - public static class NativeSignalHandler - { - private delegate void UnixExceptionHandler(int sig, IntPtr info, IntPtr ucontext); - [UnmanagedFunctionPointer(CallingConvention.Winapi)] - private delegate int VectoredExceptionHandler(IntPtr exceptionInfo); - - private const int MaxTrackedRanges = 8; + public const int MaxTrackedRanges = 8; private const int StructAddressOffset = 0; private const int StructWriteOffset = 4; @@ -70,125 +21,10 @@ namespace ARMeilleure.Signal private const uint EXCEPTION_ACCESS_VIOLATION = 0xc0000005; - private static ulong _pageSize; - private static ulong _pageMask; - - private static readonly IntPtr _handlerConfig; - private static IntPtr _signalHandlerPtr; - private static IntPtr _signalHandlerHandle; - - private static readonly object _lock = new(); - private static bool _initialized; - - static NativeSignalHandler() + private static Operand EmitGenericRegionCheck(EmitterContext context, IntPtr signalStructPtr, Operand faultAddress, Operand isWrite, int rangeStructSize, ulong pageSize) { - _handlerConfig = Marshal.AllocHGlobal(Unsafe.SizeOf()); - ref SignalHandlerConfig config = ref GetConfigRef(); + ulong pageMask = pageSize - 1; - config = new SignalHandlerConfig(); - } - - public static void Initialize(IJitMemoryAllocator allocator) - { - JitCache.Initialize(allocator); - } - - public static void InitializeSignalHandler(ulong pageSize, Func customSignalHandlerFactory = null) - { - if (_initialized) - { - return; - } - - lock (_lock) - { - if (_initialized) - { - return; - } - - _pageSize = pageSize; - _pageMask = pageSize - 1; - - ref SignalHandlerConfig config = ref GetConfigRef(); - - if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) - { - _signalHandlerPtr = Marshal.GetFunctionPointerForDelegate(GenerateUnixSignalHandler(_handlerConfig)); - - if (customSignalHandlerFactory != null) - { - _signalHandlerPtr = customSignalHandlerFactory(UnixSignalHandlerRegistration.GetSegfaultExceptionHandler().sa_handler, _signalHandlerPtr); - } - - var old = UnixSignalHandlerRegistration.RegisterExceptionHandler(_signalHandlerPtr); - - config.UnixOldSigaction = (nuint)(ulong)old.sa_handler; - config.UnixOldSigaction3Arg = old.sa_flags & 4; - } - else - { - config.StructAddressOffset = 40; // ExceptionInformation1 - config.StructWriteOffset = 32; // ExceptionInformation0 - - _signalHandlerPtr = Marshal.GetFunctionPointerForDelegate(GenerateWindowsSignalHandler(_handlerConfig)); - - if (customSignalHandlerFactory != null) - { - _signalHandlerPtr = customSignalHandlerFactory(IntPtr.Zero, _signalHandlerPtr); - } - - _signalHandlerHandle = WindowsSignalHandlerRegistration.RegisterExceptionHandler(_signalHandlerPtr); - } - - _initialized = true; - } - } - - private static unsafe ref SignalHandlerConfig GetConfigRef() - { - return ref Unsafe.AsRef((void*)_handlerConfig); - } - - public static unsafe bool AddTrackedRegion(nuint address, nuint endAddress, IntPtr action) - { - var ranges = &((SignalHandlerConfig*)_handlerConfig)->Range0; - - for (int i = 0; i < MaxTrackedRanges; i++) - { - if (ranges[i].IsActive == 0) - { - ranges[i].RangeAddress = address; - ranges[i].RangeEndAddress = endAddress; - ranges[i].ActionPointer = action; - ranges[i].IsActive = 1; - - return true; - } - } - - return false; - } - - public static unsafe bool RemoveTrackedRegion(nuint address) - { - var ranges = &((SignalHandlerConfig*)_handlerConfig)->Range0; - - for (int i = 0; i < MaxTrackedRanges; i++) - { - if (ranges[i].IsActive == 1 && ranges[i].RangeAddress == address) - { - ranges[i].IsActive = 0; - - return true; - } - } - - return false; - } - - private static Operand EmitGenericRegionCheck(EmitterContext context, IntPtr signalStructPtr, Operand faultAddress, Operand isWrite) - { Operand inRegionLocal = context.AllocateLocal(OperandType.I32); context.Copy(inRegionLocal, Const(0)); @@ -196,7 +32,7 @@ namespace ARMeilleure.Signal for (int i = 0; i < MaxTrackedRanges; i++) { - ulong rangeBaseOffset = (ulong)(RangeOffset + i * Unsafe.SizeOf()); + ulong rangeBaseOffset = (ulong)(RangeOffset + i * rangeStructSize); Operand nextLabel = Label(); @@ -210,13 +46,12 @@ namespace ARMeilleure.Signal // Is the fault address within this tracked region? Operand inRange = context.BitwiseAnd( context.ICompare(faultAddress, rangeAddress, Comparison.GreaterOrEqualUI), - context.ICompare(faultAddress, rangeEndAddress, Comparison.LessUI) - ); + context.ICompare(faultAddress, rangeEndAddress, Comparison.LessUI)); // Only call tracking if in range. context.BranchIfFalse(nextLabel, inRange, BasicBlockFrequency.Cold); - Operand offset = context.BitwiseAnd(context.Subtract(faultAddress, rangeAddress), Const(~_pageMask)); + Operand offset = context.BitwiseAnd(context.Subtract(faultAddress, rangeAddress), Const(~pageMask)); // Call the tracking action, with the pointer's relative offset to the base address. Operand trackingActionPtr = context.Load(OperandType.I64, Const((ulong)signalStructPtr + rangeBaseOffset + 20)); @@ -227,7 +62,7 @@ namespace ARMeilleure.Signal // Tracking action should be non-null to call it, otherwise assume false return. context.BranchIfFalse(skipActionLabel, trackingActionPtr); - Operand result = context.Call(trackingActionPtr, OperandType.I32, offset, Const(_pageSize), isWrite); + Operand result = context.Call(trackingActionPtr, OperandType.I32, offset, Const(pageSize), isWrite); context.Copy(inRegionLocal, result); context.MarkLabel(skipActionLabel); @@ -269,8 +104,7 @@ namespace ARMeilleure.Signal Operand esr = context.Load(OperandType.I64, context.Add(ctxPtr, Const(EsrOffset))); return context.BitwiseAnd(esr, Const(0x40ul)); } - - if (RuntimeInformation.ProcessArchitecture == Architecture.X64) + else if (RuntimeInformation.ProcessArchitecture == Architecture.X64) { const ulong ErrOffset = 4; // __es.__err Operand err = context.Load(OperandType.I64, context.Add(ctxPtr, Const(ErrOffset))); @@ -310,8 +144,7 @@ namespace ARMeilleure.Signal Operand esr = context.Load(OperandType.I64, context.Add(auxPtr, Const(8ul))); return context.BitwiseAnd(esr, Const(0x40ul)); } - - if (RuntimeInformation.ProcessArchitecture == Architecture.X64) + else if (RuntimeInformation.ProcessArchitecture == Architecture.X64) { const int ErrOffset = 192; // uc_mcontext.gregs[REG_ERR] Operand err = context.Load(OperandType.I64, context.Add(ucontextPtr, Const(ErrOffset))); @@ -322,7 +155,7 @@ namespace ARMeilleure.Signal throw new PlatformNotSupportedException(); } - private static UnixExceptionHandler GenerateUnixSignalHandler(IntPtr signalStructPtr) + public static byte[] GenerateUnixSignalHandler(IntPtr signalStructPtr, int rangeStructSize, ulong pageSize) { EmitterContext context = new(); @@ -335,7 +168,7 @@ namespace ARMeilleure.Signal Operand isWrite = context.ICompareNotEqual(writeFlag, Const(0L)); // Normalize to 0/1. - Operand isInRegion = EmitGenericRegionCheck(context, signalStructPtr, faultAddress, isWrite); + Operand isInRegion = EmitGenericRegionCheck(context, signalStructPtr, faultAddress, isWrite, rangeStructSize, pageSize); Operand endLabel = Label(); @@ -367,10 +200,10 @@ namespace ARMeilleure.Signal OperandType[] argTypes = new OperandType[] { OperandType.I32, OperandType.I64, OperandType.I64 }; - return Compiler.Compile(cfg, argTypes, OperandType.None, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map(); + return Compiler.Compile(cfg, argTypes, OperandType.None, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Code; } - private static VectoredExceptionHandler GenerateWindowsSignalHandler(IntPtr signalStructPtr) + public static byte[] GenerateWindowsSignalHandler(IntPtr signalStructPtr, int rangeStructSize, ulong pageSize) { EmitterContext context = new(); @@ -399,7 +232,7 @@ namespace ARMeilleure.Signal Operand isWrite = context.ICompareNotEqual(writeFlag, Const(0L)); // Normalize to 0/1. - Operand isInRegion = EmitGenericRegionCheck(context, signalStructPtr, faultAddress, isWrite); + Operand isInRegion = EmitGenericRegionCheck(context, signalStructPtr, faultAddress, isWrite, rangeStructSize, pageSize); Operand endLabel = Label(); @@ -421,7 +254,7 @@ namespace ARMeilleure.Signal OperandType[] argTypes = new OperandType[] { OperandType.I64 }; - return Compiler.Compile(cfg, argTypes, OperandType.I32, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map(); + return Compiler.Compile(cfg, argTypes, OperandType.I32, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Code; } } } diff --git a/src/ARMeilleure/Signal/TestMethods.cs b/src/ARMeilleure/Signal/TestMethods.cs index ec228c850..0a8b3f5ff 100644 --- a/src/ARMeilleure/Signal/TestMethods.cs +++ b/src/ARMeilleure/Signal/TestMethods.cs @@ -1,4 +1,4 @@ -using ARMeilleure.IntermediateRepresentation; +using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; using System; using System.Runtime.InteropServices; diff --git a/src/ARMeilleure/Signal/WindowsPartialUnmapHandler.cs b/src/ARMeilleure/Signal/WindowsPartialUnmapHandler.cs index 4da1b32dc..3bf6a4498 100644 --- a/src/ARMeilleure/Signal/WindowsPartialUnmapHandler.cs +++ b/src/ARMeilleure/Signal/WindowsPartialUnmapHandler.cs @@ -1,8 +1,8 @@ -using ARMeilleure.IntermediateRepresentation; +using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; using Ryujinx.Common.Memory.PartialUnmaps; using System; - +using System.Runtime.InteropServices; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; namespace ARMeilleure.Signal @@ -10,8 +10,28 @@ namespace ARMeilleure.Signal /// /// Methods to handle signals caused by partial unmaps. See the structs for C# implementations of the methods. /// - internal static class WindowsPartialUnmapHandler + internal static partial class WindowsPartialUnmapHandler { + [LibraryImport("kernel32.dll", SetLastError = true, EntryPoint = "LoadLibraryA")] + private static partial IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName); + + [LibraryImport("kernel32.dll", SetLastError = true)] + private static partial IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string procName); + + private static IntPtr _getCurrentThreadIdPtr; + + public static IntPtr GetCurrentThreadIdFunc() + { + if (_getCurrentThreadIdPtr == IntPtr.Zero) + { + IntPtr handle = LoadLibrary("kernel32.dll"); + + _getCurrentThreadIdPtr = GetProcAddress(handle, "GetCurrentThreadId"); + } + + return _getCurrentThreadIdPtr; + } + public static Operand EmitRetryFromAccessViolation(EmitterContext context) { IntPtr partialRemapStatePtr = PartialUnmapState.GlobalState; @@ -20,7 +40,7 @@ namespace ARMeilleure.Signal // Get the lock first. EmitNativeReaderLockAcquire(context, IntPtr.Add(partialRemapStatePtr, PartialUnmapState.PartialUnmapLockOffset)); - IntPtr getCurrentThreadId = WindowsSignalHandlerRegistration.GetCurrentThreadIdFunc(); + IntPtr getCurrentThreadId = GetCurrentThreadIdFunc(); Operand threadId = context.Call(Const((ulong)getCurrentThreadId), OperandType.I32); Operand threadIndex = EmitThreadLocalMapIntGetOrReserve(context, localCountsPtr, threadId, Const(0)); @@ -137,17 +157,6 @@ namespace ARMeilleure.Signal return context.Add(structsPtr, context.SignExtend32(OperandType.I64, offset)); } -#pragma warning disable IDE0051 // Remove unused private member - private static void EmitThreadLocalMapIntRelease(EmitterContext context, IntPtr threadLocalMapPtr, Operand threadId, Operand index) - { - Operand offset = context.Multiply(index, Const(sizeof(int))); - Operand idsPtr = Const((ulong)IntPtr.Add(threadLocalMapPtr, ThreadLocalMap.ThreadIdsOffset)); - Operand idPtr = context.Add(idsPtr, context.SignExtend32(OperandType.I64, offset)); - - context.CompareAndSwap(idPtr, threadId, Const(0)); - } -#pragma warning restore IDE0051 - private static void EmitAtomicAddI32(EmitterContext context, Operand ptr, Operand additive) { Operand loop = Label(); diff --git a/src/ARMeilleure/Signal/WindowsSignalHandlerRegistration.cs b/src/ARMeilleure/Signal/WindowsSignalHandlerRegistration.cs deleted file mode 100644 index 3219e015d..000000000 --- a/src/ARMeilleure/Signal/WindowsSignalHandlerRegistration.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace ARMeilleure.Signal -{ - unsafe partial class WindowsSignalHandlerRegistration - { - [LibraryImport("kernel32.dll")] - private static partial IntPtr AddVectoredExceptionHandler(uint first, IntPtr handler); - - [LibraryImport("kernel32.dll")] - private static partial ulong RemoveVectoredExceptionHandler(IntPtr handle); - - [LibraryImport("kernel32.dll", SetLastError = true, EntryPoint = "LoadLibraryA")] - private static partial IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName); - - [LibraryImport("kernel32.dll", SetLastError = true)] - private static partial IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string procName); - - private static IntPtr _getCurrentThreadIdPtr; - - public static IntPtr RegisterExceptionHandler(IntPtr action) - { - return AddVectoredExceptionHandler(1, action); - } - - public static bool RemoveExceptionHandler(IntPtr handle) - { - return RemoveVectoredExceptionHandler(handle) != 0; - } - - public static IntPtr GetCurrentThreadIdFunc() - { - if (_getCurrentThreadIdPtr == IntPtr.Zero) - { - IntPtr handle = LoadLibrary("kernel32.dll"); - - _getCurrentThreadIdPtr = GetProcAddress(handle, "GetCurrentThreadId"); - } - - return _getCurrentThreadIdPtr; - } - } -} diff --git a/src/ARMeilleure/State/FPState.cs b/src/ARMeilleure/State/FPState.cs index 027272eee..e76f48240 100644 --- a/src/ARMeilleure/State/FPState.cs +++ b/src/ARMeilleure/State/FPState.cs @@ -1,4 +1,4 @@ -namespace ARMeilleure.State +namespace ARMeilleure.State { public enum FPState { diff --git a/src/ARMeilleure/Translation/Cache/CacheMemoryAllocator.cs b/src/ARMeilleure/Translation/Cache/CacheMemoryAllocator.cs index dd67e4201..f36bf7a3d 100644 --- a/src/ARMeilleure/Translation/Cache/CacheMemoryAllocator.cs +++ b/src/ARMeilleure/Translation/Cache/CacheMemoryAllocator.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; diff --git a/src/ARMeilleure/Translation/DispatcherFunction.cs b/src/ARMeilleure/Translation/DispatcherFunction.cs index 7d5a3388e..649fa0f50 100644 --- a/src/ARMeilleure/Translation/DispatcherFunction.cs +++ b/src/ARMeilleure/Translation/DispatcherFunction.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace ARMeilleure.Translation { diff --git a/src/ARMeilleure/Translation/IntervalTree.cs b/src/ARMeilleure/Translation/IntervalTree.cs index da29d6a68..a5f9b5d5e 100644 --- a/src/ARMeilleure/Translation/IntervalTree.cs +++ b/src/ARMeilleure/Translation/IntervalTree.cs @@ -8,7 +8,7 @@ namespace ARMeilleure.Translation /// /// Key /// Value - class IntervalTree where TK : IComparable + public class IntervalTree where TK : IComparable { private const int ArrayGrowthSize = 32; diff --git a/src/ARMeilleure/Translation/Translator.cs b/src/ARMeilleure/Translation/Translator.cs index dc18038ba..014b12035 100644 --- a/src/ARMeilleure/Translation/Translator.cs +++ b/src/ARMeilleure/Translation/Translator.cs @@ -57,9 +57,6 @@ namespace ARMeilleure.Translation private Thread[] _backgroundTranslationThreads; private volatile int _threadCount; - // FIXME: Remove this once the init logic of the emulator will be redone. - public static readonly ManualResetEvent IsReadyForTranslation = new(false); - public Translator(IJitMemoryAllocator allocator, IMemoryManager memory, bool for64Bits) { _allocator = allocator; @@ -76,14 +73,9 @@ namespace ARMeilleure.Translation CountTable = new EntryTable(); Functions = new TranslatorCache(); FunctionTable = new AddressTable(for64Bits ? _levels64Bit : _levels32Bit); - Stubs = new TranslatorStubs(this); + Stubs = new TranslatorStubs(FunctionTable); FunctionTable.Fill = (ulong)Stubs.SlowDispatchStub; - - if (memory.Type.IsHostMapped()) - { - NativeSignalHandler.InitializeSignalHandler(allocator.GetPageSize()); - } } public IPtcLoadState LoadDiskCache(string titleIdText, string displayVersion, bool enabled) @@ -105,8 +97,6 @@ namespace ARMeilleure.Translation { if (Interlocked.Increment(ref _threadCount) == 1) { - IsReadyForTranslation.WaitOne(); - if (_ptc.State == PtcState.Enabled) { Debug.Assert(Functions.Count == 0); diff --git a/src/ARMeilleure/Translation/TranslatorQueue.cs b/src/ARMeilleure/Translation/TranslatorQueue.cs index fc0aa64f2..cee2f9080 100644 --- a/src/ARMeilleure/Translation/TranslatorQueue.cs +++ b/src/ARMeilleure/Translation/TranslatorQueue.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Diagnostics; +using ARMeilleure.Diagnostics; using ARMeilleure.State; using System; using System.Collections.Generic; diff --git a/src/ARMeilleure/Translation/TranslatorStubs.cs b/src/ARMeilleure/Translation/TranslatorStubs.cs index eceb1b742..d80823a8b 100644 --- a/src/ARMeilleure/Translation/TranslatorStubs.cs +++ b/src/ARMeilleure/Translation/TranslatorStubs.cs @@ -1,4 +1,5 @@ -using ARMeilleure.Instructions; +using ARMeilleure.Common; +using ARMeilleure.Instructions; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation.Cache; @@ -14,11 +15,11 @@ namespace ARMeilleure.Translation /// class TranslatorStubs : IDisposable { - private static readonly Lazy _slowDispatchStub = new(GenerateSlowDispatchStub, isThreadSafe: true); + private readonly Lazy _slowDispatchStub; private bool _disposed; - private readonly Translator _translator; + private readonly AddressTable _functionTable; private readonly Lazy _dispatchStub; private readonly Lazy _dispatchLoop; private readonly Lazy _contextWrapper; @@ -83,13 +84,14 @@ namespace ARMeilleure.Translation /// Initializes a new instance of the class with the specified /// instance. /// - /// instance to use + /// Function table used to store pointers to the functions that the guest code will call /// is null - public TranslatorStubs(Translator translator) + public TranslatorStubs(AddressTable functionTable) { - ArgumentNullException.ThrowIfNull(translator); + ArgumentNullException.ThrowIfNull(functionTable); - _translator = translator; + _functionTable = functionTable; + _slowDispatchStub = new(GenerateSlowDispatchStub, isThreadSafe: true); _dispatchStub = new(GenerateDispatchStub, isThreadSafe: true); _dispatchLoop = new(GenerateDispatchLoop, isThreadSafe: true); _contextWrapper = new(GenerateContextWrapper, isThreadSafe: true); @@ -151,15 +153,15 @@ namespace ARMeilleure.Translation context.Add(nativeContext, Const((ulong)NativeContext.GetDispatchAddressOffset()))); // Check if guest address is within range of the AddressTable. - Operand masked = context.BitwiseAnd(guestAddress, Const(~_translator.FunctionTable.Mask)); + Operand masked = context.BitwiseAnd(guestAddress, Const(~_functionTable.Mask)); context.BranchIfTrue(lblFallback, masked); Operand index = default; - Operand page = Const((long)_translator.FunctionTable.Base); + Operand page = Const((long)_functionTable.Base); - for (int i = 0; i < _translator.FunctionTable.Levels.Length; i++) + for (int i = 0; i < _functionTable.Levels.Length; i++) { - ref var level = ref _translator.FunctionTable.Levels[i]; + ref var level = ref _functionTable.Levels[i]; // level.Mask is not used directly because it is more often bigger than 32-bits, so it will not // be encoded as an immediate on x86's bitwise and operation. @@ -167,7 +169,7 @@ namespace ARMeilleure.Translation index = context.BitwiseAnd(context.ShiftRightUI(guestAddress, Const(level.Index)), mask); - if (i < _translator.FunctionTable.Levels.Length - 1) + if (i < _functionTable.Levels.Length - 1) { page = context.Load(OperandType.I64, context.Add(page, context.ShiftLeft(index, Const(3)))); context.BranchIfFalse(lblFallback, page); @@ -196,7 +198,7 @@ namespace ARMeilleure.Translation /// Generates a . /// /// Generated - private static IntPtr GenerateSlowDispatchStub() + private IntPtr GenerateSlowDispatchStub() { var context = new EmitterContext(); @@ -205,8 +207,7 @@ namespace ARMeilleure.Translation Operand guestAddress = context.Load(OperandType.I64, context.Add(nativeContext, Const((ulong)NativeContext.GetDispatchAddressOffset()))); - MethodInfo getFuncAddress = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)); - Operand hostAddress = context.Call(getFuncAddress, guestAddress); + Operand hostAddress = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress); context.Tailcall(hostAddress, nativeContext); var cfg = context.GetControlFlowGraph(); diff --git a/src/ARMeilleure/Translation/TranslatorTestMethods.cs b/src/ARMeilleure/Translation/TranslatorTestMethods.cs index 35cd8dc56..8cc7a3cf8 100644 --- a/src/ARMeilleure/Translation/TranslatorTestMethods.cs +++ b/src/ARMeilleure/Translation/TranslatorTestMethods.cs @@ -1,4 +1,4 @@ -using ARMeilleure.CodeGen.X86; +using ARMeilleure.CodeGen.X86; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using System; diff --git a/src/Ryujinx.Audio.Backends.OpenAL/OpenALAudioBuffer.cs b/src/Ryujinx.Audio.Backends.OpenAL/OpenALAudioBuffer.cs index 050b52a9f..bd7a9c25c 100644 --- a/src/Ryujinx.Audio.Backends.OpenAL/OpenALAudioBuffer.cs +++ b/src/Ryujinx.Audio.Backends.OpenAL/OpenALAudioBuffer.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Audio.Backends.OpenAL +namespace Ryujinx.Audio.Backends.OpenAL { class OpenALAudioBuffer { diff --git a/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceDriver.cs b/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceDriver.cs index 86a2efa40..744a4bc56 100644 --- a/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceDriver.cs +++ b/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceDriver.cs @@ -1,4 +1,4 @@ -using OpenTK.Audio.OpenAL; +using OpenTK.Audio.OpenAL; using Ryujinx.Audio.Common; using Ryujinx.Audio.Integration; using Ryujinx.Memory; diff --git a/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceSession.cs b/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceSession.cs index ee177c311..a52821616 100644 --- a/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceSession.cs +++ b/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceSession.cs @@ -1,4 +1,4 @@ -using OpenTK.Audio.OpenAL; +using OpenTK.Audio.OpenAL; using Ryujinx.Audio.Backends.Common; using Ryujinx.Audio.Common; using Ryujinx.Memory; diff --git a/src/Ryujinx.Audio.Backends.SDL2/SDL2AudioBuffer.cs b/src/Ryujinx.Audio.Backends.SDL2/SDL2AudioBuffer.cs index 71ef414a9..a390c5467 100644 --- a/src/Ryujinx.Audio.Backends.SDL2/SDL2AudioBuffer.cs +++ b/src/Ryujinx.Audio.Backends.SDL2/SDL2AudioBuffer.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Audio.Backends.SDL2 +namespace Ryujinx.Audio.Backends.SDL2 { class SDL2AudioBuffer { diff --git a/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceDriver.cs b/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceDriver.cs index f1de42b01..b83e63dbc 100644 --- a/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceDriver.cs +++ b/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceDriver.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Common; +using Ryujinx.Audio.Common; using Ryujinx.Audio.Integration; using Ryujinx.Common.Logging; using Ryujinx.Memory; diff --git a/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceSession.cs b/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceSession.cs index 0bd73f3c7..7a683f4ed 100644 --- a/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceSession.cs +++ b/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceSession.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Backends.Common; +using Ryujinx.Audio.Backends.Common; using Ryujinx.Audio.Common; using Ryujinx.Common.Logging; using Ryujinx.Memory; diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIo.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIo.cs index 31af3e9d3..7fdb1fc04 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIo.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoBackend.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoBackend.cs index 7094b7d5b..d91eca488 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoBackend.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoBackend.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Audio.Backends.SoundIo.Native +namespace Ryujinx.Audio.Backends.SoundIo.Native { public enum SoundIoBackend { diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoChannelId.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoChannelId.cs index 70346e0bf..c1a14e1ea 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoChannelId.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoChannelId.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Audio.Backends.SoundIo.Native +namespace Ryujinx.Audio.Backends.SoundIo.Native { public enum SoundIoChannelId { diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoContext.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoContext.cs index afa86befa..f2e91fcd7 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoContext.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoContext.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceAim.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceAim.cs index a1943810d..58bdce394 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceAim.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceAim.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Audio.Backends.SoundIo.Native +namespace Ryujinx.Audio.Backends.SoundIo.Native { public enum SoundIoDeviceAim { diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceContext.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceContext.cs index 42bcc6e3b..7923e9b17 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceContext.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceContext.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo; diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoError.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoError.cs index 9e33fa194..64329450c 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoError.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoError.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Audio.Backends.SoundIo.Native +namespace Ryujinx.Audio.Backends.SoundIo.Native { public enum SoundIoError { diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoException.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoException.cs index a033356e8..1a33472da 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoException.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoException.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo; diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoFormat.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoFormat.cs index 0eee97804..7e8c22a9f 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoFormat.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoFormat.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Audio.Backends.SoundIo.Native +namespace Ryujinx.Audio.Backends.SoundIo.Native { public enum SoundIoFormat { diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoOutStreamContext.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoOutStreamContext.cs index 2e432b311..4148ea0dd 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoOutStreamContext.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoOutStreamContext.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo; diff --git a/src/Ryujinx.Audio.Backends.SoundIo/SoundIoAudioBuffer.cs b/src/Ryujinx.Audio.Backends.SoundIo/SoundIoAudioBuffer.cs index 7f32b9533..e1a62de75 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/SoundIoAudioBuffer.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/SoundIoAudioBuffer.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Audio.Backends.SoundIo +namespace Ryujinx.Audio.Backends.SoundIo { class SoundIoAudioBuffer { diff --git a/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs b/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs index 9dac0992c..ff0392882 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Backends.SoundIo.Native; +using Ryujinx.Audio.Backends.SoundIo.Native; using Ryujinx.Audio.Common; using Ryujinx.Audio.Integration; using Ryujinx.Memory; diff --git a/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs b/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs index 0aa13e7ed..123cfd27a 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Backends.Common; +using Ryujinx.Audio.Backends.Common; using Ryujinx.Audio.Backends.SoundIo.Native; using Ryujinx.Audio.Common; using Ryujinx.Memory; diff --git a/src/Ryujinx.Audio/Backends/CompatLayer/Downmixing.cs b/src/Ryujinx.Audio/Backends/CompatLayer/Downmixing.cs index ffd427a5e..7a5ea0deb 100644 --- a/src/Ryujinx.Audio/Backends/CompatLayer/Downmixing.cs +++ b/src/Ryujinx.Audio/Backends/CompatLayer/Downmixing.cs @@ -31,7 +31,7 @@ namespace Ryujinx.Audio.Backends.CompatLayer private const int Minus6dBInQ15 = (int)(0.501f * RawQ15One); private const int Minus12dBInQ15 = (int)(0.251f * RawQ15One); - private static readonly int[] _defaultSurroundToStereoCoefficients = new int[4] + private static readonly long[] _defaultSurroundToStereoCoefficients = new long[4] { RawQ15One, Minus3dBInQ15, @@ -39,7 +39,7 @@ namespace Ryujinx.Audio.Backends.CompatLayer Minus3dBInQ15, }; - private static readonly int[] _defaultStereoToMonoCoefficients = new int[2] + private static readonly long[] _defaultStereoToMonoCoefficients = new long[2] { Minus6dBInQ15, Minus6dBInQ15, @@ -62,19 +62,23 @@ namespace Ryujinx.Audio.Backends.CompatLayer } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static short DownMixStereoToMono(ReadOnlySpan coefficients, short left, short right) + private static short DownMixStereoToMono(ReadOnlySpan coefficients, short left, short right) { - return (short)((left * coefficients[0] + right * coefficients[1]) >> Q15Bits); + return (short)Math.Clamp((left * coefficients[0] + right * coefficients[1]) >> Q15Bits, short.MinValue, short.MaxValue); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static short DownMixSurroundToStereo(ReadOnlySpan coefficients, short back, short lfe, short center, short front) + private static short DownMixSurroundToStereo(ReadOnlySpan coefficients, short back, short lfe, short center, short front) { - return (short)((coefficients[3] * back + coefficients[2] * lfe + coefficients[1] * center + coefficients[0] * front + RawQ15HalfOne) >> Q15Bits); + return (short)Math.Clamp( + (coefficients[3] * back + + coefficients[2] * lfe + + coefficients[1] * center + + coefficients[0] * front + RawQ15HalfOne) >> Q15Bits, short.MinValue, short.MaxValue); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static short[] DownMixSurroundToStereo(ReadOnlySpan coefficients, ReadOnlySpan data) + private static short[] DownMixSurroundToStereo(ReadOnlySpan coefficients, ReadOnlySpan data) { int samplePerChannelCount = data.Length / SurroundChannelCount; @@ -94,7 +98,7 @@ namespace Ryujinx.Audio.Backends.CompatLayer } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static short[] DownMixStereoToMono(ReadOnlySpan coefficients, ReadOnlySpan data) + private static short[] DownMixStereoToMono(ReadOnlySpan coefficients, ReadOnlySpan data) { int samplePerChannelCount = data.Length / StereoChannelCount; diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/CompressorCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/CompressorCommand.cs index 1d5917bbe..09f415d20 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/CompressorCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/CompressorCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Renderer.Dsp.Effect; +using Ryujinx.Audio.Renderer.Dsp.Effect; using Ryujinx.Audio.Renderer.Dsp.State; using Ryujinx.Audio.Renderer.Parameter.Effect; using Ryujinx.Audio.Renderer.Server.Effect; diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Effect/ExponentialMovingAverage.cs b/src/Ryujinx.Audio/Renderer/Dsp/Effect/ExponentialMovingAverage.cs index 253400a5a..d44aec0ae 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Effect/ExponentialMovingAverage.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Effect/ExponentialMovingAverage.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Audio.Renderer.Dsp.Effect +namespace Ryujinx.Audio.Renderer.Dsp.Effect { public struct ExponentialMovingAverage { diff --git a/src/Ryujinx.Audio/Renderer/Dsp/State/CompressorState.cs b/src/Ryujinx.Audio/Renderer/Dsp/State/CompressorState.cs index 9ee573205..5ca8cd20a 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/State/CompressorState.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/State/CompressorState.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Renderer.Dsp.Effect; +using Ryujinx.Audio.Renderer.Dsp.Effect; using Ryujinx.Audio.Renderer.Parameter.Effect; namespace Ryujinx.Audio.Renderer.Dsp.State diff --git a/src/Ryujinx.Audio/Renderer/Parameter/Effect/CompressorParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/Effect/CompressorParameter.cs index 1a936b0df..b403f1370 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/Effect/CompressorParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/Effect/CompressorParameter.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Renderer.Server.Effect; +using Ryujinx.Audio.Renderer.Server.Effect; using Ryujinx.Common.Memory; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Audio/Renderer/Server/Effect/CompressorEffect.cs b/src/Ryujinx.Audio/Renderer/Server/Effect/CompressorEffect.cs index 32162abcd..826c32cb0 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Effect/CompressorEffect.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Effect/CompressorEffect.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Renderer.Common; +using Ryujinx.Audio.Renderer.Common; using Ryujinx.Audio.Renderer.Dsp.State; using Ryujinx.Audio.Renderer.Parameter; using Ryujinx.Audio.Renderer.Parameter.Effect; diff --git a/src/Ryujinx.Ava/App.axaml.cs b/src/Ryujinx.Ava/App.axaml.cs index c1a3ab3e2..54e61c67c 100644 --- a/src/Ryujinx.Ava/App.axaml.cs +++ b/src/Ryujinx.Ava/App.axaml.cs @@ -12,7 +12,6 @@ using Ryujinx.Ui.Common.Configuration; using Ryujinx.Ui.Common.Helper; using System; using System.Diagnostics; -using System.IO; namespace Ryujinx.Ava { @@ -90,8 +89,6 @@ namespace Ryujinx.Ava try { string baseStyle = ConfigurationState.Instance.Ui.BaseStyle; - string themePath = ConfigurationState.Instance.Ui.CustomThemePath; - bool enableCustomTheme = ConfigurationState.Instance.Ui.EnableCustomTheme; if (string.IsNullOrWhiteSpace(baseStyle)) { @@ -106,24 +103,6 @@ namespace Ryujinx.Ava "Dark" => ThemeVariant.Dark, _ => ThemeVariant.Default, }; - - if (enableCustomTheme) - { - if (!string.IsNullOrWhiteSpace(themePath)) - { - try - { - var themeContent = File.ReadAllText(themePath); - var customStyle = AvaloniaRuntimeXamlLoader.Parse(themeContent); - - Styles.Add(customStyle); - } - catch (Exception ex) - { - Logger.Error?.Print(LogClass.Application, $"Failed to Apply Custom Theme. Error: {ex.Message}"); - } - } - } } catch (Exception) { diff --git a/src/Ryujinx.Ava/AppHost.cs b/src/Ryujinx.Ava/AppHost.cs index 4d751e2a9..696a4046f 100644 --- a/src/Ryujinx.Ava/AppHost.cs +++ b/src/Ryujinx.Ava/AppHost.cs @@ -1,4 +1,3 @@ -using ARMeilleure.Translation; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; @@ -346,16 +345,9 @@ namespace Ryujinx.Ava _viewModel.IsGameRunning = true; - var activeProcess = Device.Processes.ActiveApplication; - - string titleNameSection = string.IsNullOrWhiteSpace(activeProcess.Name) ? string.Empty : $" {activeProcess.Name}"; - string titleVersionSection = string.IsNullOrWhiteSpace(activeProcess.DisplayVersion) ? string.Empty : $" v{activeProcess.DisplayVersion}"; - string titleIdSection = $" ({activeProcess.ProgramIdText.ToUpper()})"; - string titleArchSection = activeProcess.Is64Bit ? " (64-bit)" : " (32-bit)"; - Dispatcher.UIThread.InvokeAsync(() => { - _viewModel.Title = $"Ryujinx {Program.Version} -{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}"; + _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device.Processes.ActiveApplication, Program.Version); }); _viewModel.SetUiProgressHandlers(Device); @@ -727,6 +719,8 @@ namespace Ryujinx.Ava Device?.System.TogglePauseEmulation(false); _viewModel.IsPaused = false; + _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version); + Logger.Info?.Print(LogClass.Emulation, "Emulation was resumed"); } internal void Pause() @@ -734,6 +728,8 @@ namespace Ryujinx.Ava Device?.System.TogglePauseEmulation(true); _viewModel.IsPaused = true; + _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, LocaleManager.Instance[LocaleKeys.Paused]); + Logger.Info?.Print(LogClass.Emulation, "Emulation was paused"); } private void InitializeSwitchInstance() @@ -919,7 +915,6 @@ namespace Ryujinx.Ava { Device.Gpu.SetGpuThread(); Device.Gpu.InitializeShaderCache(_gpuCancellationTokenSource.Token); - Translator.IsReadyForTranslation.Set(); _renderer.Window.ChangeVSyncMode(Device.EnableDeviceVsync); @@ -983,7 +978,7 @@ namespace Ryujinx.Ava ConfigurationState.Instance.Graphics.AspectRatio.Value.ToText(), LocaleManager.Instance[LocaleKeys.Game] + $": {Device.Statistics.GetGameFrameRate():00.00} FPS ({Device.Statistics.GetGameFrameTime():00.00} ms)", $"FIFO: {Device.Statistics.GetFifoPercent():00.00} %", - $"GPU: {_renderer.GetHardwareInfo().GpuVendor}")); + $"GPU: {_renderer.GetHardwareInfo().GpuDriver}")); } public async Task ShowExitPrompt() @@ -1091,10 +1086,11 @@ namespace Ryujinx.Ava case KeyboardHotkeyState.ToggleMute: if (Device.IsAudioMuted()) { - Device.SetVolume(ConfigurationState.Instance.System.AudioVolume); + Device.SetVolume(_viewModel.VolumeBeforeMute); } else { + _viewModel.VolumeBeforeMute = Device.GetVolume(); Device.SetVolume(0); } diff --git a/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConLeft.svg b/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConLeft.svg new file mode 100644 index 000000000..cf78cf120 --- /dev/null +++ b/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConLeft.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConPair.svg b/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConPair.svg new file mode 100644 index 000000000..8097762df --- /dev/null +++ b/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConPair.svg @@ -0,0 +1,341 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConRight.svg b/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConRight.svg new file mode 100644 index 000000000..adb6e1e18 --- /dev/null +++ b/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConRight.svg @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Ryujinx.Ava/Assets/Icons/Controller_ProCon.svg b/src/Ryujinx.Ava/Assets/Icons/Controller_ProCon.svg new file mode 100644 index 000000000..53eef82c2 --- /dev/null +++ b/src/Ryujinx.Ava/Assets/Icons/Controller_ProCon.svg @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Ryujinx.Ava/Assets/Locales/en_US.json b/src/Ryujinx.Ava/Assets/Locales/en_US.json index dde252750..65b0e2046 100644 --- a/src/Ryujinx.Ava/Assets/Locales/en_US.json +++ b/src/Ryujinx.Ava/Assets/Locales/en_US.json @@ -54,8 +54,6 @@ "GameListContextMenuManageTitleUpdatesToolTip": "Opens the Title Update management window", "GameListContextMenuManageDlc": "Manage DLC", "GameListContextMenuManageDlcToolTip": "Opens the DLC management window", - "GameListContextMenuOpenModsDirectory": "Open Mods Directory", - "GameListContextMenuOpenModsDirectoryToolTip": "Opens the directory which contains Application's Mods", "GameListContextMenuCacheManagement": "Cache Management", "GameListContextMenuCacheManagementPurgePptc": "Queue PPTC Rebuild", "GameListContextMenuCacheManagementPurgePptcToolTip": "Trigger PPTC to rebuild at boot time on the next game launch", @@ -74,6 +72,7 @@ "GameListContextMenuExtractDataLogoToolTip": "Extract the Logo section from Application's current config (including updates)", "GameListContextMenuCreateShortcut": "Create Application Shortcut", "GameListContextMenuCreateShortcutToolTip": "Create a Desktop Shortcut that launches the selected Application", + "GameListContextMenuCreateShortcutToolTipMacOS": "Create a shortcut in macOS's Applications folder that launches the selected Application", "StatusBarGamesLoaded": "{0}/{1} Games Loaded", "StatusBarSystemVersion": "System Version: {0}", "LinuxVmMaxMapCountDialogTitle": "Low limit for memory mappings detected", @@ -295,13 +294,9 @@ "GameListContextMenuRunApplication": "Run Application", "GameListContextMenuToggleFavorite": "Toggle Favorite", "GameListContextMenuToggleFavoriteToolTip": "Toggle Favorite status of Game", - "SettingsTabGeneralTheme": "Theme", - "SettingsTabGeneralThemeCustomTheme": "Custom Theme Path", - "SettingsTabGeneralThemeBaseStyle": "Base Style", - "SettingsTabGeneralThemeBaseStyleDark": "Dark", - "SettingsTabGeneralThemeBaseStyleLight": "Light", - "SettingsTabGeneralThemeEnableCustomTheme": "Enable Custom Theme", - "ButtonBrowse": "Browse", + "SettingsTabGeneralTheme": "Theme:", + "SettingsTabGeneralThemeDark": "Dark", + "SettingsTabGeneralThemeLight": "Light", "ControllerSettingsConfigureGeneral": "Configure", "ControllerSettingsRumble": "Rumble", "ControllerSettingsRumbleStrongMultiplier": "Strong Rumble Multiplier", @@ -388,7 +383,10 @@ "DialogUserProfileUnsavedChangesSubMessage": "Do you want to discard your changes?", "DialogControllerSettingsModifiedConfirmMessage": "The current controller settings has been updated.", "DialogControllerSettingsModifiedConfirmSubMessage": "Do you want to save?", - "DialogLoadNcaErrorMessage": "{0}. Errored File: {1}", + "DialogLoadFileErrorMessage": "{0}. Errored File: {1}", + "DialogModAlreadyExistsMessage": "Mod already exists", + "DialogModInvalidMessage": "The specified directory does not contain a mod!", + "DialogModDeleteNoParentMessage": "Failed to Delete: Could not find the parent directory for mod \"{0}\"!", "DialogDlcNoDlcErrorMessage": "The specified file does not contain a DLC for the selected title!", "DialogPerformanceCheckLoggingEnabledMessage": "You have trace logging enabled, which is designed to be used by developers only.", "DialogPerformanceCheckLoggingEnabledConfirmMessage": "For optimal performance, it's recommended to disable trace logging. Would you like to disable trace logging now?", @@ -399,6 +397,8 @@ "DialogUpdateAddUpdateErrorMessage": "The specified file does not contain an update for the selected title!", "DialogSettingsBackendThreadingWarningTitle": "Warning - Backend Threading", "DialogSettingsBackendThreadingWarningMessage": "Ryujinx must be restarted after changing this option for it to apply fully. Depending on your platform, you may need to manually disable your driver's own multithreading when using Ryujinx's.", + "DialogModManagerDeletionWarningMessage": "You are about to delete the mod: {0}\n\nAre you sure you want to proceed?", + "DialogModManagerDeletionAllWarningMessage": "You are about to delete all mods for this title.\n\nAre you sure you want to proceed?", "SettingsTabGraphicsFeaturesOptions": "Features", "SettingsTabGraphicsBackendMultithreading": "Graphics Backend Multithreading:", "CommonAuto": "Auto", @@ -433,6 +433,7 @@ "DlcManagerRemoveAllButton": "Remove All", "DlcManagerEnableAllButton": "Enable All", "DlcManagerDisableAllButton": "Disable All", + "ModManagerDeleteAllButton": "Delete All", "MenuBarOptionsChangeLanguage": "Change Language", "MenuBarShowFileTypes": "Show File Types", "CommonSort": "Sort", @@ -508,6 +509,8 @@ "EnableInternetAccessTooltip": "Allows the emulated application to connect to the Internet.\n\nGames with a LAN mode can connect to each other when this is enabled and the systems are connected to the same access point. This includes real consoles as well.\n\nDoes NOT allow connecting to Nintendo servers. May cause crashing in certain games that try to connect to the Internet.\n\nLeave OFF if unsure.", "GameListContextMenuManageCheatToolTip": "Manage Cheats", "GameListContextMenuManageCheat": "Manage Cheats", + "GameListContextMenuManageModToolTip": "Manage Mods", + "GameListContextMenuManageMod": "Manage Mods", "ControllerSettingsStickRange": "Range:", "DialogStopEmulationTitle": "Ryujinx - Stop Emulation", "DialogStopEmulationMessage": "Are you sure you want to stop emulation?", @@ -519,8 +522,6 @@ "SettingsTabCpuMemory": "CPU Mode", "DialogUpdaterFlatpakNotSupportedMessage": "Please update Ryujinx via FlatHub.", "UpdaterDisabledWarningTitle": "Updater Disabled!", - "GameListContextMenuOpenSdModsDirectory": "Open Atmosphere Mods Directory", - "GameListContextMenuOpenSdModsDirectoryToolTip": "Opens the alternative SD card Atmosphere directory which contains Application's Mods. Useful for mods that are packaged for real hardware.", "ControllerSettingsRotate90": "Rotate 90° Clockwise", "IconSize": "Icon Size", "IconSizeTooltip": "Change the size of game icons", @@ -551,9 +552,10 @@ "SoftwareKeyboardModeNumeric": "Must be 0-9 or '.' only", "SoftwareKeyboardModeAlphabet": "Must be non CJK-characters only", "SoftwareKeyboardModeASCII": "Must be ASCII text only", - "DialogControllerAppletMessagePlayerRange": "Application requests {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.", - "DialogControllerAppletMessage": "Application requests exactly {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.", - "DialogControllerAppletDockModeSet": "Docked mode set. Handheld is also invalid.\n\n", + "ControllerAppletControllers": "Supported Controllers:", + "ControllerAppletPlayers": "Players:", + "ControllerAppletDescription": "Your current configuration is invalid. Open settings and reconfigure your inputs.", + "ControllerAppletDocked": "Docked mode set. Handheld control should be disabled.", "UpdaterRenaming": "Renaming Old Files...", "UpdaterRenameFailed": "Updater was unable to rename file: {0}", "UpdaterAddingFiles": "Adding New Files...", @@ -591,6 +593,7 @@ "Writable": "Writable", "SelectDlcDialogTitle": "Select DLC files", "SelectUpdateDialogTitle": "Select update files", + "SelectModDialogTitle": "Select mod directory", "UserProfileWindowTitle": "User Profiles Manager", "CheatWindowTitle": "Cheats Manager", "DlcWindowTitle": "Manage Downloadable Content for {0} ({1})", @@ -598,10 +601,12 @@ "CheatWindowHeading": "Cheats Available for {0} [{1}]", "BuildId": "BuildId:", "DlcWindowHeading": "{0} Downloadable Content(s)", + "ModWindowHeading": "{0} Mod(s)", "UserProfilesEditProfile": "Edit Selected", "Cancel": "Cancel", "Save": "Save", "Discard": "Discard", + "Paused": "Paused", "UserProfilesSetProfileImage": "Set Profile Image", "UserProfileEmptyNameError": "Name is required", "UserProfileNoImageError": "Profile image must be set", diff --git a/src/Ryujinx.Ava/Common/KeyboardHotkeyState.cs b/src/Ryujinx.Ava/Common/KeyboardHotkeyState.cs index 1d7f0b9ce..b24016404 100644 --- a/src/Ryujinx.Ava/Common/KeyboardHotkeyState.cs +++ b/src/Ryujinx.Ava/Common/KeyboardHotkeyState.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Ava.Common +namespace Ryujinx.Ava.Common { public enum KeyboardHotkeyState { diff --git a/src/Ryujinx.Ava/Common/Locale/LocaleExtension.cs b/src/Ryujinx.Ava/Common/Locale/LocaleExtension.cs index 8d345ae08..40661bf3a 100644 --- a/src/Ryujinx.Ava/Common/Locale/LocaleExtension.cs +++ b/src/Ryujinx.Ava/Common/Locale/LocaleExtension.cs @@ -1,4 +1,4 @@ -using Avalonia.Data.Core; +using Avalonia.Data.Core; using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml.MarkupExtensions; using Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings; diff --git a/src/Ryujinx.Ava/Common/Locale/LocaleManager.cs b/src/Ryujinx.Ava/Common/Locale/LocaleManager.cs index 583619fe5..0e613838d 100644 --- a/src/Ryujinx.Ava/Common/Locale/LocaleManager.cs +++ b/src/Ryujinx.Ava/Common/Locale/LocaleManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Ava.UI.ViewModels; +using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Common; using Ryujinx.Common.Utilities; using Ryujinx.Ui.Common.Configuration; @@ -16,8 +16,10 @@ namespace Ryujinx.Ava.Common.Locale private readonly Dictionary _localeStrings; private Dictionary _localeDefaultStrings; private readonly ConcurrentDictionary _dynamicValues; + private string _localeLanguageCode; public static LocaleManager Instance { get; } = new(); + public event Action LocaleChanged; public LocaleManager() { @@ -104,6 +106,15 @@ namespace Ryujinx.Ava.Common.Locale } } + public bool IsRTL() + { + return _localeLanguageCode switch + { + "he_IL" => true, + _ => false + }; + } + public string UpdateAndGetDynamicValue(LocaleKeys key, params object[] values) { _dynamicValues[key] = values; @@ -124,6 +135,9 @@ namespace Ryujinx.Ava.Common.Locale { this[item.Key] = item.Value; } + + _localeLanguageCode = languageCode; + LocaleChanged?.Invoke(); } private static Dictionary LoadJsonLanguage(string languageCode = DefaultLanguageCode) diff --git a/src/Ryujinx.Ava/Input/AvaloniaKeyboard.cs b/src/Ryujinx.Ava/Input/AvaloniaKeyboard.cs index d07c81340..fbaaaabab 100644 --- a/src/Ryujinx.Ava/Input/AvaloniaKeyboard.cs +++ b/src/Ryujinx.Ava/Input/AvaloniaKeyboard.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Configuration.Hid; +using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid.Keyboard; using Ryujinx.Input; using System; diff --git a/src/Ryujinx.Ava/Input/AvaloniaKeyboardDriver.cs b/src/Ryujinx.Ava/Input/AvaloniaKeyboardDriver.cs index bff24a81e..e9e71b99b 100644 --- a/src/Ryujinx.Ava/Input/AvaloniaKeyboardDriver.cs +++ b/src/Ryujinx.Ava/Input/AvaloniaKeyboardDriver.cs @@ -1,4 +1,4 @@ -using Avalonia.Controls; +using Avalonia.Controls; using Avalonia.Input; using Ryujinx.Ava.Common.Locale; using Ryujinx.Input; diff --git a/src/Ryujinx.Ava/Input/AvaloniaKeyboardMappingHelper.cs b/src/Ryujinx.Ava/Input/AvaloniaKeyboardMappingHelper.cs index d30a7566a..97ebd721d 100644 --- a/src/Ryujinx.Ava/Input/AvaloniaKeyboardMappingHelper.cs +++ b/src/Ryujinx.Ava/Input/AvaloniaKeyboardMappingHelper.cs @@ -1,4 +1,4 @@ -using Ryujinx.Input; +using Ryujinx.Input; using System; using System.Collections.Generic; using AvaKey = Avalonia.Input.Key; diff --git a/src/Ryujinx.Ava/Modules/Updater/Updater.cs b/src/Ryujinx.Ava/Modules/Updater/Updater.cs index af7608d34..ad33b1013 100644 --- a/src/Ryujinx.Ava/Modules/Updater/Updater.cs +++ b/src/Ryujinx.Ava/Modules/Updater/Updater.cs @@ -665,7 +665,7 @@ namespace Ryujinx.Modules return false; } - if (Program.Version.Contains("dirty") || !ReleaseInformation.IsValid()) + if (Program.Version.Contains("dirty") || !ReleaseInformation.IsValid) { if (showWarnings) { @@ -683,7 +683,7 @@ namespace Ryujinx.Modules #else if (showWarnings) { - if (ReleaseInformation.IsFlatHubBuild()) + if (ReleaseInformation.IsFlatHubBuild) { Dispatcher.UIThread.InvokeAsync(() => ContentDialogHelper.CreateWarningDialog( diff --git a/src/Ryujinx.Ava/Program.cs b/src/Ryujinx.Ava/Program.cs index cc062a256..d85749eff 100644 --- a/src/Ryujinx.Ava/Program.cs +++ b/src/Ryujinx.Ava/Program.cs @@ -35,7 +35,7 @@ namespace Ryujinx.Ava public static void Main(string[] args) { - Version = ReleaseInformation.GetVersion(); + Version = ReleaseInformation.Version; if (OperatingSystem.IsWindows() && !OperatingSystem.IsWindowsVersionAtLeast(10, 0, 17134)) { @@ -125,8 +125,8 @@ namespace Ryujinx.Ava public static void ReloadConfig() { - string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"); - string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, "Config.json"); + string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ReleaseInformation.ConfigName); + string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, ReleaseInformation.ConfigName); // Now load the configuration as the other subsystems are now registered if (File.Exists(localConfigurationPath)) diff --git a/src/Ryujinx.Ava/Ryujinx.Ava.csproj b/src/Ryujinx.Ava/Ryujinx.Ava.csproj index 6812e57c4..b6d37a2f1 100644 --- a/src/Ryujinx.Ava/Ryujinx.Ava.csproj +++ b/src/Ryujinx.Ava/Ryujinx.Ava.csproj @@ -119,6 +119,7 @@ + @@ -132,6 +133,10 @@ + + + + @@ -139,6 +144,7 @@ + @@ -151,6 +157,10 @@ + + + + diff --git a/src/Ryujinx.Ava/UI/Applet/AvaHostUiHandler.cs b/src/Ryujinx.Ava/UI/Applet/AvaHostUiHandler.cs index 9fc7c6b6d..e11939104 100644 --- a/src/Ryujinx.Ava/UI/Applet/AvaHostUiHandler.cs +++ b/src/Ryujinx.Ava/UI/Applet/AvaHostUiHandler.cs @@ -29,14 +29,24 @@ namespace Ryujinx.Ava.UI.Applet public bool DisplayMessageDialog(ControllerAppletUiArgs args) { - string message = LocaleManager.Instance.UpdateAndGetDynamicValue( - args.PlayerCountMin == args.PlayerCountMax ? LocaleKeys.DialogControllerAppletMessage : LocaleKeys.DialogControllerAppletMessagePlayerRange, - args.PlayerCountMin == args.PlayerCountMax ? args.PlayerCountMin.ToString() : $"{args.PlayerCountMin}-{args.PlayerCountMax}", - args.SupportedStyles, - string.Join(", ", args.SupportedPlayers), - args.IsDocked ? LocaleManager.Instance[LocaleKeys.DialogControllerAppletDockModeSet] : ""); + ManualResetEvent dialogCloseEvent = new(false); - return DisplayMessageDialog(LocaleManager.Instance[LocaleKeys.DialogControllerAppletTitle], message); + bool okPressed = false; + + Dispatcher.UIThread.InvokeAsync(async () => + { + var response = await ControllerAppletDialog.ShowControllerAppletDialog(_parent, args); + if (response == UserResult.Ok) + { + okPressed = true; + } + + dialogCloseEvent.Set(); + }); + + dialogCloseEvent.WaitOne(); + + return okPressed; } public bool DisplayMessageDialog(string title, string message) @@ -75,6 +85,8 @@ namespace Ryujinx.Ava.UI.Applet await _parent.SettingsWindow.ShowDialog(window); + _parent.SettingsWindow = null; + opened = false; }); diff --git a/src/Ryujinx.Ava/UI/Applet/AvaloniaDynamicTextInputHandler.cs b/src/Ryujinx.Ava/UI/Applet/AvaloniaDynamicTextInputHandler.cs index 2fa4d54f8..2411659f7 100644 --- a/src/Ryujinx.Ava/UI/Applet/AvaloniaDynamicTextInputHandler.cs +++ b/src/Ryujinx.Ava/UI/Applet/AvaloniaDynamicTextInputHandler.cs @@ -1,4 +1,4 @@ -using Avalonia; +using Avalonia; using Avalonia.Controls; using Avalonia.Input; using Avalonia.Threading; diff --git a/src/Ryujinx.Ava/UI/Applet/AvaloniaHostUiTheme.cs b/src/Ryujinx.Ava/UI/Applet/AvaloniaHostUiTheme.cs index 3cf273347..4ee177d72 100644 --- a/src/Ryujinx.Ava/UI/Applet/AvaloniaHostUiTheme.cs +++ b/src/Ryujinx.Ava/UI/Applet/AvaloniaHostUiTheme.cs @@ -1,4 +1,4 @@ -using Avalonia.Media; +using Avalonia.Media; using Ryujinx.Ava.UI.Windows; using Ryujinx.HLE.Ui; using System; diff --git a/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml b/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml new file mode 100644 index 000000000..b2c22f6bb --- /dev/null +++ b/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs b/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs new file mode 100644 index 000000000..f7d751a66 --- /dev/null +++ b/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs @@ -0,0 +1,140 @@ +using Avalonia.Controls; +using Avalonia.Styling; +using Avalonia.Svg.Skia; +using Avalonia.Threading; +using FluentAvalonia.UI.Controls; +using Ryujinx.Ava.Common.Locale; +using Ryujinx.Ava.UI.Helpers; +using Ryujinx.Ava.UI.Windows; +using Ryujinx.Common; +using Ryujinx.HLE.HOS.Applets; +using Ryujinx.HLE.HOS.Services.Hid; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Ryujinx.Ava.UI.Applet +{ + internal partial class ControllerAppletDialog : UserControl + { + private const string ProControllerResource = "Ryujinx.Ava/Assets/Icons/Controller_ProCon.svg"; + private const string JoyConPairResource = "Ryujinx.Ava/Assets/Icons/Controller_JoyConPair.svg"; + private const string JoyConLeftResource = "Ryujinx.Ava/Assets/Icons/Controller_JoyConLeft.svg"; + private const string JoyConRightResource = "Ryujinx.Ava/Assets/Icons/Controller_JoyConRight.svg"; + + public static SvgImage ProControllerImage => GetResource(ProControllerResource); + public static SvgImage JoyconPairImage => GetResource(JoyConPairResource); + public static SvgImage JoyconLeftImage => GetResource(JoyConLeftResource); + public static SvgImage JoyconRightImage => GetResource(JoyConRightResource); + + public string PlayerCount { get; set; } = ""; + public bool SupportsProController { get; set; } + public bool SupportsLeftJoycon { get; set; } + public bool SupportsRightJoycon { get; set; } + public bool SupportsJoyconPair { get; set; } + public bool IsDocked { get; set; } + + private readonly MainWindow _mainWindow; + + public ControllerAppletDialog(MainWindow mainWindow, ControllerAppletUiArgs args) + { + if (args.PlayerCountMin == args.PlayerCountMax) + { + PlayerCount = args.PlayerCountMin.ToString(); + } + else + { + PlayerCount = $"{args.PlayerCountMin} - {args.PlayerCountMax}"; + } + + SupportsProController = (args.SupportedStyles & ControllerType.ProController) != 0; + SupportsLeftJoycon = (args.SupportedStyles & ControllerType.JoyconLeft) != 0; + SupportsRightJoycon = (args.SupportedStyles & ControllerType.JoyconRight) != 0; + SupportsJoyconPair = (args.SupportedStyles & ControllerType.JoyconPair) != 0; + + IsDocked = args.IsDocked; + + _mainWindow = mainWindow; + + DataContext = this; + + InitializeComponent(); + } + + public ControllerAppletDialog(MainWindow mainWindow) + { + _mainWindow = mainWindow; + DataContext = this; + + InitializeComponent(); + } + + public static async Task ShowControllerAppletDialog(MainWindow window, ControllerAppletUiArgs args) + { + ContentDialog contentDialog = new(); + UserResult result = UserResult.Cancel; + ControllerAppletDialog content = new(window, args); + + contentDialog.Title = LocaleManager.Instance[LocaleKeys.DialogControllerAppletTitle]; + contentDialog.Content = content; + + void Handler(ContentDialog sender, ContentDialogClosedEventArgs eventArgs) + { + if (eventArgs.Result == ContentDialogResult.Primary) + { + result = UserResult.Ok; + } + } + + contentDialog.Closed += Handler; + + Style bottomBorder = new(x => x.OfType().Name("DialogSpace").Child().OfType()); + bottomBorder.Setters.Add(new Setter(IsVisibleProperty, false)); + + contentDialog.Styles.Add(bottomBorder); + + await ContentDialogHelper.ShowAsync(contentDialog); + + return result; + } + + private static SvgImage GetResource(string path) + { + SvgImage image = new(); + + if (!string.IsNullOrWhiteSpace(path)) + { + SvgSource source = new(default(Uri)); + + source.Load(EmbeddedResources.GetStream(path)); + + image.Source = source; + } + + return image; + } + + public void OpenSettingsWindow() + { + if (_mainWindow.SettingsWindow == null) + { + Dispatcher.UIThread.InvokeAsync(async () => + { + _mainWindow.SettingsWindow = new SettingsWindow(_mainWindow.VirtualFileSystem, _mainWindow.ContentManager); + _mainWindow.SettingsWindow.NavPanel.Content = _mainWindow.SettingsWindow.InputPage; + _mainWindow.SettingsWindow.NavPanel.SelectedItem = _mainWindow.SettingsWindow.NavPanel.MenuItems.ElementAt(1); + + await ContentDialogHelper.ShowWindowAsync(_mainWindow.SettingsWindow, _mainWindow); + _mainWindow.SettingsWindow = null; + this.Close(); + }); + } + } + + public void Close() + { + ((ContentDialog)Parent)?.Hide(); + } + } +} + diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml b/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml index b8fe7e76f..5bdeb8ad3 100644 --- a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml +++ b/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml @@ -16,7 +16,7 @@ Click="CreateApplicationShortcut_Click" Header="{locale:Locale GameListContextMenuCreateShortcut}" IsEnabled="{Binding CreateShortcutEnabled}" - ToolTip.Tip="{locale:Locale GameListContextMenuCreateShortcutToolTip}" /> + ToolTip.Tip="{OnPlatform Default={locale:Locale GameListContextMenuCreateShortcutToolTip}, macOS={locale:Locale GameListContextMenuCreateShortcutToolTipMacOS}}" /> - + Click="OpenModManager_Click" + Header="{locale:Locale GameListContextMenuManageMod}" + ToolTip.Tip="{locale:Locale GameListContextMenuManageModToolTip}" /> @@ -110,12 +110,12 @@ ShowContentDialog( string title, @@ -310,16 +311,20 @@ namespace Ryujinx.Ava.UI.Helpers public static async Task ShowAsync(ContentDialog contentDialog) { ContentDialogResult result; - - ContentDialogOverlayWindow contentDialogOverlayWindow = null; + bool isTopDialog = true; Window parent = GetMainWindow(); + if (_contentDialogOverlayWindow != null) + { + isTopDialog = false; + } + if (parent is MainWindow window) { parent.Activate(); - contentDialogOverlayWindow = new() + _contentDialogOverlayWindow = new ContentDialogOverlayWindow { Height = parent.Bounds.Height, Width = parent.Bounds.Width, @@ -331,14 +336,14 @@ namespace Ryujinx.Ava.UI.Helpers void OverlayOnPositionChanged(object sender, PixelPointEventArgs e) { - contentDialogOverlayWindow.Position = parent.PointToScreen(new Point()); + _contentDialogOverlayWindow.Position = parent.PointToScreen(new Point()); } - contentDialogOverlayWindow.ContentDialog = contentDialog; + _contentDialogOverlayWindow.ContentDialog = contentDialog; bool opened = false; - contentDialogOverlayWindow.Opened += OverlayOnActivated; + _contentDialogOverlayWindow.Opened += OverlayOnActivated; async void OverlayOnActivated(object sender, EventArgs e) { @@ -349,12 +354,12 @@ namespace Ryujinx.Ava.UI.Helpers opened = true; - contentDialogOverlayWindow.Position = parent.PointToScreen(new Point()); + _contentDialogOverlayWindow.Position = parent.PointToScreen(new Point()); result = await ShowDialog(); } - result = await contentDialogOverlayWindow.ShowDialog(parent); + result = await _contentDialogOverlayWindow.ShowDialog(parent); } else { @@ -363,11 +368,11 @@ namespace Ryujinx.Ava.UI.Helpers async Task ShowDialog() { - if (contentDialogOverlayWindow is not null) + if (_contentDialogOverlayWindow is not null) { - result = await contentDialog.ShowAsync(contentDialogOverlayWindow); + result = await contentDialog.ShowAsync(_contentDialogOverlayWindow); - contentDialogOverlayWindow!.Close(); + _contentDialogOverlayWindow!.Close(); } else { @@ -379,15 +384,23 @@ namespace Ryujinx.Ava.UI.Helpers return result; } - if (contentDialogOverlayWindow is not null) + if (isTopDialog && _contentDialogOverlayWindow is not null) { - contentDialogOverlayWindow.Content = null; - contentDialogOverlayWindow.Close(); + _contentDialogOverlayWindow.Content = null; + _contentDialogOverlayWindow.Close(); + _contentDialogOverlayWindow = null; } return result; } + public static Task ShowWindowAsync(Window dialogWindow, Window mainWindow = null) + { + mainWindow ??= GetMainWindow(); + + return dialogWindow.ShowDialog(_contentDialogOverlayWindow ?? mainWindow); + } + private static Window GetMainWindow() { if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime al) diff --git a/src/Ryujinx.Ava/UI/Helpers/Glyph.cs b/src/Ryujinx.Ava/UI/Helpers/Glyph.cs index e30de69bb..f257dc02c 100644 --- a/src/Ryujinx.Ava/UI/Helpers/Glyph.cs +++ b/src/Ryujinx.Ava/UI/Helpers/Glyph.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Ava.UI.Helpers +namespace Ryujinx.Ava.UI.Helpers { public enum Glyph { diff --git a/src/Ryujinx.Ava/UI/Helpers/LocalizedNeverConverter.cs b/src/Ryujinx.Ava/UI/Helpers/LocalizedNeverConverter.cs index 737896986..b61a924f4 100644 --- a/src/Ryujinx.Ava/UI/Helpers/LocalizedNeverConverter.cs +++ b/src/Ryujinx.Ava/UI/Helpers/LocalizedNeverConverter.cs @@ -1,4 +1,4 @@ -using Avalonia.Data.Converters; +using Avalonia.Data.Converters; using Avalonia.Markup.Xaml; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ui.Common.Helper; diff --git a/src/Ryujinx.Ava/UI/Helpers/MiniCommand.cs b/src/Ryujinx.Ava/UI/Helpers/MiniCommand.cs index 864f53b8a..7e1bb9a68 100644 --- a/src/Ryujinx.Ava/UI/Helpers/MiniCommand.cs +++ b/src/Ryujinx.Ava/UI/Helpers/MiniCommand.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading.Tasks; using System.Windows.Input; diff --git a/src/Ryujinx.Ava/UI/Helpers/NotificationHelper.cs b/src/Ryujinx.Ava/UI/Helpers/NotificationHelper.cs index a11fb5267..656a8b52f 100644 --- a/src/Ryujinx.Ava/UI/Helpers/NotificationHelper.cs +++ b/src/Ryujinx.Ava/UI/Helpers/NotificationHelper.cs @@ -1,4 +1,4 @@ -using Avalonia; +using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Notifications; using Avalonia.Threading; diff --git a/src/Ryujinx.Ava/UI/Helpers/TimeZoneConverter.cs b/src/Ryujinx.Ava/UI/Helpers/TimeZoneConverter.cs index 4ec0ff306..876d51f71 100644 --- a/src/Ryujinx.Ava/UI/Helpers/TimeZoneConverter.cs +++ b/src/Ryujinx.Ava/UI/Helpers/TimeZoneConverter.cs @@ -1,4 +1,4 @@ -using Avalonia.Data.Converters; +using Avalonia.Data.Converters; using System; using System.Globalization; using TimeZone = Ryujinx.Ava.UI.Models.TimeZone; diff --git a/src/Ryujinx.Ava/UI/Helpers/UserErrorDialog.cs b/src/Ryujinx.Ava/UI/Helpers/UserErrorDialog.cs index afd2958c6..fc82bd6b1 100644 --- a/src/Ryujinx.Ava/UI/Helpers/UserErrorDialog.cs +++ b/src/Ryujinx.Ava/UI/Helpers/UserErrorDialog.cs @@ -1,4 +1,4 @@ -using Ryujinx.Ava.Common.Locale; +using Ryujinx.Ava.Common.Locale; using Ryujinx.Ui.Common; using Ryujinx.Ui.Common.Helper; using System.Threading.Tasks; diff --git a/src/Ryujinx.Ava/UI/Helpers/Win32NativeInterop.cs b/src/Ryujinx.Ava/UI/Helpers/Win32NativeInterop.cs index 35d16b9e0..4834df802 100644 --- a/src/Ryujinx.Ava/UI/Helpers/Win32NativeInterop.cs +++ b/src/Ryujinx.Ava/UI/Helpers/Win32NativeInterop.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Runtime.Versioning; diff --git a/src/Ryujinx.Ava/UI/Models/CheatModel.cs b/src/Ryujinx.Ava/UI/Models/CheatModel.cs deleted file mode 100644 index 4434c09f4..000000000 --- a/src/Ryujinx.Ava/UI/Models/CheatModel.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Ryujinx.Ava.UI.ViewModels; -using System; - -namespace Ryujinx.Ava.UI.Models -{ - public class CheatModel : BaseModel - { - private bool _isEnabled; - - public event EventHandler EnableToggled; - - public CheatModel(string name, string buildId, bool isEnabled) - { - Name = name; - BuildId = buildId; - IsEnabled = isEnabled; - } - - public bool IsEnabled - { - get => _isEnabled; - set - { - _isEnabled = value; - - EnableToggled?.Invoke(this, _isEnabled); - - OnPropertyChanged(); - } - } - - public string BuildId { get; } - - public string BuildIdKey => $"{BuildId}-{Name}"; - - public string Name { get; } - - public string CleanName => Name[1..^7]; - } -} diff --git a/src/Ryujinx.Ava/UI/Models/CheatNode.cs b/src/Ryujinx.Ava/UI/Models/CheatNode.cs new file mode 100644 index 000000000..8e9aee254 --- /dev/null +++ b/src/Ryujinx.Ava/UI/Models/CheatNode.cs @@ -0,0 +1,57 @@ +using Ryujinx.Ava.UI.ViewModels; +using System.Collections.ObjectModel; +using System.Collections.Specialized; +using System.Linq; + +namespace Ryujinx.Ava.UI.Models +{ + public class CheatNode : BaseModel + { + private bool _isEnabled = false; + public ObservableCollection SubNodes { get; } = new(); + public string CleanName => Name[1..^7]; + public string BuildIdKey => $"{BuildId}-{Name}"; + public bool IsRootNode { get; } + public string Name { get; } + public string BuildId { get; } + public string Path { get; } + public bool IsEnabled + { + get + { + if (SubNodes.Count > 0) + { + return SubNodes.ToList().TrueForAll(x => x.IsEnabled); + } + + return _isEnabled; + } + set + { + foreach (var cheat in SubNodes) + { + cheat.IsEnabled = value; + cheat.OnPropertyChanged(); + } + + _isEnabled = value; + } + } + + public CheatNode(string name, string buildId, string path, bool isRootNode, bool isEnabled = false) + { + Name = name; + BuildId = buildId; + Path = path; + IsEnabled = isEnabled; + IsRootNode = isRootNode; + + SubNodes.CollectionChanged += CheatsList_CollectionChanged; + } + + private void CheatsList_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + OnPropertyChanged(nameof(IsEnabled)); + } + } +} diff --git a/src/Ryujinx.Ava/UI/Models/CheatsList.cs b/src/Ryujinx.Ava/UI/Models/CheatsList.cs deleted file mode 100644 index 1cb0480c7..000000000 --- a/src/Ryujinx.Ava/UI/Models/CheatsList.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Linq; - -namespace Ryujinx.Ava.UI.Models -{ - public class CheatsList : ObservableCollection - { - public CheatsList(string buildId, string path) - { - BuildId = buildId; - Path = path; - - CollectionChanged += CheatsList_CollectionChanged; - } - - public string BuildId { get; } - public string Path { get; } - - public bool IsEnabled - { - get - { - return this.ToList().TrueForAll(x => x.IsEnabled); - } - set - { - foreach (var cheat in this) - { - cheat.IsEnabled = value; - } - - OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsEnabled))); - } - } - - private void CheatsList_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.Action == NotifyCollectionChangedAction.Add) - { - (e.NewItems[0] as CheatModel).EnableToggled += Item_EnableToggled; - } - } - - private void Item_EnableToggled(object sender, bool e) - { - OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsEnabled))); - } - } -} diff --git a/src/Ryujinx.Ava/UI/Models/ControllerModel.cs b/src/Ryujinx.Ava/UI/Models/ControllerModel.cs index 2af2d13b8..98de7757f 100644 --- a/src/Ryujinx.Ava/UI/Models/ControllerModel.cs +++ b/src/Ryujinx.Ava/UI/Models/ControllerModel.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Configuration.Hid; +using Ryujinx.Common.Configuration.Hid; namespace Ryujinx.Ava.UI.Models { diff --git a/src/Ryujinx.Ava/UI/Models/DownloadableContentModel.cs b/src/Ryujinx.Ava/UI/Models/DownloadableContentModel.cs index fedb3527b..9e400441d 100644 --- a/src/Ryujinx.Ava/UI/Models/DownloadableContentModel.cs +++ b/src/Ryujinx.Ava/UI/Models/DownloadableContentModel.cs @@ -1,4 +1,4 @@ -using Ryujinx.Ava.UI.ViewModels; +using Ryujinx.Ava.UI.ViewModels; using System.IO; namespace Ryujinx.Ava.UI.Models diff --git a/src/Ryujinx.Ava/UI/Models/ModModel.cs b/src/Ryujinx.Ava/UI/Models/ModModel.cs new file mode 100644 index 000000000..ee28ca5f5 --- /dev/null +++ b/src/Ryujinx.Ava/UI/Models/ModModel.cs @@ -0,0 +1,32 @@ +using Ryujinx.Ava.UI.ViewModels; +using System.IO; + +namespace Ryujinx.Ava.UI.Models +{ + public class ModModel : BaseModel + { + private bool _enabled; + + public bool Enabled + { + get => _enabled; + set + { + _enabled = value; + OnPropertyChanged(); + } + } + + public bool InSd { get; } + public string Path { get; } + public string Name { get; } + + public ModModel(string path, string name, bool enabled, bool inSd) + { + Path = path; + Name = name; + Enabled = enabled; + InSd = inSd; + } + } +} diff --git a/src/Ryujinx.Ava/UI/Models/PlayerModel.cs b/src/Ryujinx.Ava/UI/Models/PlayerModel.cs index f0b1bf7a8..a19852b94 100644 --- a/src/Ryujinx.Ava/UI/Models/PlayerModel.cs +++ b/src/Ryujinx.Ava/UI/Models/PlayerModel.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Configuration.Hid; +using Ryujinx.Common.Configuration.Hid; namespace Ryujinx.Ava.UI.Models { diff --git a/src/Ryujinx.Ava/UI/Models/StatusUpdatedEventArgs.cs b/src/Ryujinx.Ava/UI/Models/StatusUpdatedEventArgs.cs index cc29442d0..7f04c0eed 100644 --- a/src/Ryujinx.Ava/UI/Models/StatusUpdatedEventArgs.cs +++ b/src/Ryujinx.Ava/UI/Models/StatusUpdatedEventArgs.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Ava.UI.Models { diff --git a/src/Ryujinx.Ava/UI/Models/TitleUpdateModel.cs b/src/Ryujinx.Ava/UI/Models/TitleUpdateModel.cs index 3b44e8ee6..c270c9ed4 100644 --- a/src/Ryujinx.Ava/UI/Models/TitleUpdateModel.cs +++ b/src/Ryujinx.Ava/UI/Models/TitleUpdateModel.cs @@ -1,4 +1,4 @@ -using LibHac.Ns; +using LibHac.Ns; using Ryujinx.Ava.Common.Locale; namespace Ryujinx.Ava.UI.Models diff --git a/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml b/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml index bb96b10d2..e0b586b45 100644 --- a/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml +++ b/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml @@ -1,11 +1,12 @@ - - \ No newline at end of file + diff --git a/src/Ryujinx.Ava/UI/Renderer/SPBOpenGLContext.cs b/src/Ryujinx.Ava/UI/Renderer/SPBOpenGLContext.cs index a2c7aa279..5ff756f24 100644 --- a/src/Ryujinx.Ava/UI/Renderer/SPBOpenGLContext.cs +++ b/src/Ryujinx.Ava/UI/Renderer/SPBOpenGLContext.cs @@ -1,4 +1,4 @@ -using OpenTK.Graphics.OpenGL; +using OpenTK.Graphics.OpenGL; using Ryujinx.Graphics.OpenGL; using SPB.Graphics; using SPB.Graphics.OpenGL; diff --git a/src/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs index 83624f5f3..0e0d858a4 100644 --- a/src/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs +++ b/src/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs @@ -17,6 +17,7 @@ using System.IO; using System.Linq; using System.Net.Http; using System.Text; +using System.Text.Json; using System.Threading.Tasks; namespace Ryujinx.Ava.UI.ViewModels @@ -188,35 +189,83 @@ namespace Ryujinx.Ava.UI.ViewModels _httpClient.Dispose(); } - private async Task LoadContentAsync() + private static bool TryGetAmiiboJson(string json, out AmiiboJson amiiboJson) { - string amiiboJsonString = DefaultJson; - - if (File.Exists(_amiiboJsonPath)) + if (string.IsNullOrEmpty(json)) { - amiiboJsonString = await File.ReadAllTextAsync(_amiiboJsonPath); + amiiboJson = JsonHelper.Deserialize(DefaultJson, _serializerContext.AmiiboJson); - if (await NeedsUpdate(JsonHelper.Deserialize(amiiboJsonString, _serializerContext.AmiiboJson).LastUpdated)) - { - amiiboJsonString = await DownloadAmiiboJson(); - } + return false; } - else + + try + { + amiiboJson = JsonHelper.Deserialize(json, _serializerContext.AmiiboJson); + + return true; + } + catch (JsonException exception) + { + Logger.Error?.Print(LogClass.Application, $"Unable to deserialize amiibo data: {exception}"); + amiiboJson = JsonHelper.Deserialize(DefaultJson, _serializerContext.AmiiboJson); + + return false; + } + } + + private async Task GetMostRecentAmiiboListOrDefaultJson() + { + bool localIsValid = false; + bool remoteIsValid = false; + AmiiboJson amiiboJson = new(); + + try { try { - amiiboJsonString = await DownloadAmiiboJson(); + if (File.Exists(_amiiboJsonPath)) + { + localIsValid = TryGetAmiiboJson(await File.ReadAllTextAsync(_amiiboJsonPath), out amiiboJson); + } } - catch (Exception ex) + catch (Exception exception) { - Logger.Error?.Print(LogClass.Application, $"Failed to download amiibo data: {ex}"); + Logger.Warning?.Print(LogClass.Application, $"Unable to read data from '{_amiiboJsonPath}': {exception}"); + } + if (!localIsValid || await NeedsUpdate(amiiboJson.LastUpdated)) + { + remoteIsValid = TryGetAmiiboJson(await DownloadAmiiboJson(), out amiiboJson); + } + } + catch (Exception exception) + { + if (!(localIsValid || remoteIsValid)) + { + Logger.Error?.Print(LogClass.Application, $"Couldn't get valid amiibo data: {exception}"); + + // Neither local or remote files are valid JSON, close window. + ShowInfoDialog(); + Close(); + } + else if (!remoteIsValid) + { + Logger.Warning?.Print(LogClass.Application, $"Couldn't update amiibo data: {exception}"); + + // Only the local file is valid, the local one should be used + // but the user should be warned. ShowInfoDialog(); } } - _amiiboList = JsonHelper.Deserialize(amiiboJsonString, _serializerContext.AmiiboJson).Amiibo; - _amiiboList = _amiiboList.OrderBy(amiibo => amiibo.AmiiboSeries).ToList(); + return amiiboJson; + } + + private async Task LoadContentAsync() + { + AmiiboJson amiiboJson = await GetMostRecentAmiiboListOrDefaultJson(); + + _amiiboList = amiiboJson.Amiibo.OrderBy(amiibo => amiibo.AmiiboSeries).ToList(); ParseAmiiboData(); } @@ -364,43 +413,50 @@ namespace Ryujinx.Ava.UI.ViewModels { try { - HttpResponseMessage response = - await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, "https://amiibo.ryujinx.org/")); + HttpResponseMessage response = await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, "https://amiibo.ryujinx.org/")); if (response.IsSuccessStatusCode) { - return response.Content.Headers.LastModified != new DateTimeOffset(oldLastModified.Ticks - (oldLastModified.Ticks % TimeSpan.TicksPerSecond), TimeSpan.Zero); + return response.Content.Headers.LastModified != oldLastModified; } - - return false; } - catch (Exception ex) + catch (HttpRequestException exception) { - Logger.Error?.Print(LogClass.Application, $"Failed to check for amiibo updates: {ex}"); - - ShowInfoDialog(); - - return false; + Logger.Error?.Print(LogClass.Application, $"Unable to check for amiibo data updates: {exception}"); } + + return false; } private async Task DownloadAmiiboJson() { - HttpResponseMessage response = await _httpClient.GetAsync("https://amiibo.ryujinx.org/"); - - if (response.IsSuccessStatusCode) + try { - string amiiboJsonString = await response.Content.ReadAsStringAsync(); + HttpResponseMessage response = await _httpClient.GetAsync("https://amiibo.ryujinx.org/"); - using (FileStream amiiboJsonStream = File.Create(_amiiboJsonPath, 4096, FileOptions.WriteThrough)) + if (response.IsSuccessStatusCode) { - amiiboJsonStream.Write(Encoding.UTF8.GetBytes(amiiboJsonString)); + string amiiboJsonString = await response.Content.ReadAsStringAsync(); + + try + { + using FileStream dlcJsonStream = File.Create(_amiiboJsonPath, 4096, FileOptions.WriteThrough); + dlcJsonStream.Write(Encoding.UTF8.GetBytes(amiiboJsonString)); + } + catch (Exception exception) + { + Logger.Warning?.Print(LogClass.Application, $"Couldn't write amiibo data to file '{_amiiboJsonPath}: {exception}'"); + } + + return amiiboJsonString; } - return amiiboJsonString; + Logger.Error?.Print(LogClass.Application, $"Failed to download amiibo data. Response status code: {response.StatusCode}"); + } + catch (HttpRequestException exception) + { + Logger.Error?.Print(LogClass.Application, $"Failed to request amiibo data: {exception}"); } - - Logger.Error?.Print(LogClass.Application, $"Failed to download amiibo data. Response status code: {response.StatusCode}"); await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogAmiiboApiTitle], LocaleManager.Instance[LocaleKeys.DialogAmiiboApiFailFetchMessage], @@ -408,9 +464,7 @@ namespace Ryujinx.Ava.UI.ViewModels "", LocaleManager.Instance[LocaleKeys.RyujinxInfo]); - Close(); - - return DefaultJson; + return null; } private void Close() diff --git a/src/Ryujinx.Ava/UI/ViewModels/BaseModel.cs b/src/Ryujinx.Ava/UI/ViewModels/BaseModel.cs index 0ff72dbc4..4db9cf812 100644 --- a/src/Ryujinx.Ava/UI/ViewModels/BaseModel.cs +++ b/src/Ryujinx.Ava/UI/ViewModels/BaseModel.cs @@ -1,4 +1,4 @@ -using System.ComponentModel; +using System.ComponentModel; using System.Runtime.CompilerServices; namespace Ryujinx.Ava.UI.ViewModels diff --git a/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs index c0c625321..042803f36 100644 --- a/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs +++ b/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs @@ -180,7 +180,7 @@ namespace Ryujinx.Ava.UI.ViewModels if (!string.IsNullOrWhiteSpace(_controllerImage)) { - SvgSource source = new(); + SvgSource source = new(default(Uri)); source.Load(EmbeddedResources.GetStream(_controllerImage)); diff --git a/src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs index cdecae77d..2cd714f44 100644 --- a/src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs +++ b/src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs @@ -39,6 +39,7 @@ namespace Ryujinx.Ava.UI.ViewModels private string _search; private readonly ulong _titleId; + private readonly IStorageProvider _storageProvider; private static readonly DownloadableContentJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions()); @@ -90,8 +91,6 @@ namespace Ryujinx.Ava.UI.ViewModels get => string.Format(LocaleManager.Instance[LocaleKeys.DlcWindowHeading], DownloadableContents.Count); } - public IStorageProvider StorageProvider; - public DownloadableContentManagerViewModel(VirtualFileSystem virtualFileSystem, ulong titleId) { _virtualFileSystem = virtualFileSystem; @@ -100,7 +99,7 @@ namespace Ryujinx.Ava.UI.ViewModels if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { - StorageProvider = desktop.MainWindow.StorageProvider; + _storageProvider = desktop.MainWindow.StorageProvider; } _downloadableContentJsonPath = Path.Combine(AppDataManager.GamesDirPath, titleId.ToString("x16"), "dlc.json"); @@ -194,7 +193,7 @@ namespace Ryujinx.Ava.UI.ViewModels { Dispatcher.UIThread.InvokeAsync(async () => { - await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance[LocaleKeys.DialogLoadNcaErrorMessage], ex.Message, containerPath)); + await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance[LocaleKeys.DialogLoadFileErrorMessage], ex.Message, containerPath)); }); } @@ -203,7 +202,7 @@ namespace Ryujinx.Ava.UI.ViewModels public async void Add() { - var result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions + var result = await _storageProvider.OpenFilePickerAsync(new FilePickerOpenOptions { Title = LocaleManager.Instance[LocaleKeys.SelectDlcDialogTitle], AllowMultiple = true, diff --git a/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs index 80df5d398..2caee16cd 100644 --- a/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs @@ -90,6 +90,7 @@ namespace Ryujinx.Ava.UI.ViewModels private string _pauseKey = "F5"; private string _screenshotKey = "F8"; private float _volume; + private float _volumeBeforeMute; private string _backendText; private bool _canUpdate = true; @@ -356,7 +357,7 @@ namespace Ryujinx.Ava.UI.ViewModels public bool OpenBcatSaveDirectoryEnabled => !SelectedApplication.ControlHolder.ByteSpan.IsZeros() && SelectedApplication.ControlHolder.Value.BcatDeliveryCacheStorageSize > 0; - public bool CreateShortcutEnabled => !ReleaseInformation.IsFlatHubBuild(); + public bool CreateShortcutEnabled => !ReleaseInformation.IsFlatHubBuild; public string LoadHeading { @@ -554,6 +555,17 @@ namespace Ryujinx.Ava.UI.ViewModels } } + public float VolumeBeforeMute + { + get => _volumeBeforeMute; + set + { + _volumeBeforeMute = value; + + OnPropertyChanged(); + } + } + public bool ShowStatusSeparator { get => _showStatusSeparator; @@ -1338,7 +1350,12 @@ namespace Ryujinx.Ava.UI.ViewModels public void OpenLogsFolder() { - string logPath = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "Logs"); + string logPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs"); + + if (LoggerModule.LogDirectoryPath != null) + { + logPath = LoggerModule.LogDirectoryPath; + } new DirectoryInfo(logPath).Create(); diff --git a/src/Ryujinx.Ava/UI/ViewModels/ModManagerViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/ModManagerViewModel.cs new file mode 100644 index 000000000..8321bf894 --- /dev/null +++ b/src/Ryujinx.Ava/UI/ViewModels/ModManagerViewModel.cs @@ -0,0 +1,336 @@ +using Avalonia; +using Avalonia.Collections; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Platform.Storage; +using Avalonia.Threading; +using DynamicData; +using Ryujinx.Ava.Common.Locale; +using Ryujinx.Ava.UI.Helpers; +using Ryujinx.Ava.UI.Models; +using Ryujinx.Common.Configuration; +using Ryujinx.Common.Logging; +using Ryujinx.Common.Utilities; +using Ryujinx.HLE.HOS; +using System; +using System.IO; +using System.Linq; + +namespace Ryujinx.Ava.UI.ViewModels +{ + public class ModManagerViewModel : BaseModel + { + private readonly string _modJsonPath; + + private AvaloniaList _mods = new(); + private AvaloniaList _views = new(); + private AvaloniaList _selectedMods = new(); + + private string _search; + private readonly ulong _applicationId; + private readonly IStorageProvider _storageProvider; + + private static readonly ModMetadataJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions()); + + public AvaloniaList Mods + { + get => _mods; + set + { + _mods = value; + OnPropertyChanged(); + OnPropertyChanged(nameof(ModCount)); + Sort(); + } + } + + public AvaloniaList Views + { + get => _views; + set + { + _views = value; + OnPropertyChanged(); + } + } + + public AvaloniaList SelectedMods + { + get => _selectedMods; + set + { + _selectedMods = value; + OnPropertyChanged(); + } + } + + public string Search + { + get => _search; + set + { + _search = value; + OnPropertyChanged(); + Sort(); + } + } + + public string ModCount + { + get => string.Format(LocaleManager.Instance[LocaleKeys.ModWindowHeading], Mods.Count); + } + + public ModManagerViewModel(ulong applicationId) + { + _applicationId = applicationId; + + _modJsonPath = Path.Combine(AppDataManager.GamesDirPath, applicationId.ToString("x16"), "mods.json"); + + if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + { + _storageProvider = desktop.MainWindow.StorageProvider; + } + + LoadMods(applicationId); + } + + private void LoadMods(ulong applicationId) + { + Mods.Clear(); + SelectedMods.Clear(); + + string[] modsBasePaths = [ModLoader.GetSdModsBasePath(), ModLoader.GetModsBasePath()]; + + foreach (var path in modsBasePaths) + { + var inSd = path == ModLoader.GetSdModsBasePath(); + var modCache = new ModLoader.ModCache(); + + ModLoader.QueryContentsDir(modCache, new DirectoryInfo(Path.Combine(path, "contents")), applicationId); + + foreach (var mod in modCache.RomfsDirs) + { + var modModel = new ModModel(mod.Path.Parent.FullName, mod.Name, mod.Enabled, inSd); + if (Mods.All(x => x.Path != mod.Path.Parent.FullName)) + { + Mods.Add(modModel); + } + } + + foreach (var mod in modCache.RomfsContainers) + { + Mods.Add(new ModModel(mod.Path.FullName, mod.Name, mod.Enabled, inSd)); + } + + foreach (var mod in modCache.ExefsDirs) + { + var modModel = new ModModel(mod.Path.Parent.FullName, mod.Name, mod.Enabled, inSd); + if (Mods.All(x => x.Path != mod.Path.Parent.FullName)) + { + Mods.Add(modModel); + } + } + + foreach (var mod in modCache.ExefsContainers) + { + Mods.Add(new ModModel(mod.Path.FullName, mod.Name, mod.Enabled, inSd)); + } + } + + Sort(); + } + + public void Sort() + { + Mods.AsObservableChangeSet() + .Filter(Filter) + .Bind(out var view).AsObservableList(); + + _views.Clear(); + _views.AddRange(view); + + SelectedMods = new(Views.Where(x => x.Enabled)); + + OnPropertyChanged(nameof(ModCount)); + OnPropertyChanged(nameof(Views)); + OnPropertyChanged(nameof(SelectedMods)); + } + + private bool Filter(object arg) + { + if (arg is ModModel content) + { + return string.IsNullOrWhiteSpace(_search) || content.Name.ToLower().Contains(_search.ToLower()); + } + + return false; + } + + public void Save() + { + ModMetadata modData = new(); + + foreach (ModModel mod in Mods) + { + modData.Mods.Add(new Mod + { + Name = mod.Name, + Path = mod.Path, + Enabled = SelectedMods.Contains(mod), + }); + } + + JsonHelper.SerializeToFile(_modJsonPath, modData, _serializerContext.ModMetadata); + } + + public void Delete(ModModel model) + { + var isSubdir = true; + var pathToDelete = model.Path; + var basePath = model.InSd ? ModLoader.GetSdModsBasePath() : ModLoader.GetModsBasePath(); + var modsDir = ModLoader.GetApplicationDir(basePath, _applicationId.ToString("x16")); + + if (new DirectoryInfo(model.Path).Parent?.FullName == modsDir) + { + isSubdir = false; + } + + if (isSubdir) + { + var parentDir = String.Empty; + + foreach (var dir in Directory.GetDirectories(modsDir, "*", SearchOption.TopDirectoryOnly)) + { + if (Directory.GetDirectories(dir, "*", SearchOption.AllDirectories).Contains(model.Path)) + { + parentDir = dir; + break; + } + } + + if (parentDir == String.Empty) + { + Dispatcher.UIThread.Post(async () => + { + await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue( + LocaleKeys.DialogModDeleteNoParentMessage, + model.Path)); + }); + return; + } + } + + Logger.Info?.Print(LogClass.Application, $"Deleting mod at \"{pathToDelete}\""); + Directory.Delete(pathToDelete, true); + + Mods.Remove(model); + OnPropertyChanged(nameof(ModCount)); + Sort(); + } + + private void AddMod(DirectoryInfo directory) + { + string[] directories; + + try + { + directories = Directory.GetDirectories(directory.ToString(), "*", SearchOption.AllDirectories); + } + catch (Exception exception) + { + Dispatcher.UIThread.Post(async () => + { + await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue( + LocaleKeys.DialogLoadFileErrorMessage, + exception.ToString(), + directory)); + }); + return; + } + + var destinationDir = ModLoader.GetApplicationDir(ModLoader.GetSdModsBasePath(), _applicationId.ToString("x16")); + + // TODO: More robust checking for valid mod folders + var isDirectoryValid = true; + + if (directories.Length == 0) + { + isDirectoryValid = false; + } + + if (!isDirectoryValid) + { + Dispatcher.UIThread.Post(async () => + { + await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogModInvalidMessage]); + }); + return; + } + + foreach (var dir in directories) + { + string dirToCreate = dir.Replace(directory.Parent.ToString(), destinationDir); + + // Mod already exists + if (Directory.Exists(dirToCreate)) + { + Dispatcher.UIThread.Post(async () => + { + await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue( + LocaleKeys.DialogLoadFileErrorMessage, + LocaleManager.Instance[LocaleKeys.DialogModAlreadyExistsMessage], + dirToCreate)); + }); + + return; + } + + Directory.CreateDirectory(dirToCreate); + } + + var files = Directory.GetFiles(directory.ToString(), "*", SearchOption.AllDirectories); + + foreach (var file in files) + { + File.Copy(file, file.Replace(directory.Parent.ToString(), destinationDir), true); + } + + LoadMods(_applicationId); + } + + public async void Add() + { + var result = await _storageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions + { + Title = LocaleManager.Instance[LocaleKeys.SelectModDialogTitle], + AllowMultiple = true, + }); + + foreach (var folder in result) + { + AddMod(new DirectoryInfo(folder.Path.LocalPath)); + } + } + + public void DeleteAll() + { + foreach (var mod in Mods) + { + Delete(mod); + } + + Mods.Clear(); + OnPropertyChanged(nameof(ModCount)); + Sort(); + } + + public void EnableAll() + { + SelectedMods = new(Mods); + } + + public void DisableAll() + { + SelectedMods.Clear(); + } + } +} diff --git a/src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs index 652ef350d..c52473c0f 100644 --- a/src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs @@ -49,7 +49,6 @@ namespace Ryujinx.Ava.UI.ViewModels private KeyboardHotkeys _keyboardHotkeys; private int _graphicsBackendIndex; private int _shadinglanguageBackendIndex; - private string _customThemePath; private int _scalingFilter; private int _scalingFilterLevel; @@ -161,7 +160,6 @@ namespace Ryujinx.Ava.UI.ViewModels public bool IsOpenAlEnabled { get; set; } public bool IsSoundIoEnabled { get; set; } public bool IsSDL2Enabled { get; set; } - public bool EnableCustomTheme { get; set; } public bool IsCustomResolutionScaleActive => _resolutionScale == 4; public bool IsScalingFilterActive => _scalingFilter == (int)Ryujinx.Common.Configuration.ScalingFilter.Fsr; @@ -173,20 +171,6 @@ namespace Ryujinx.Ava.UI.ViewModels public string TimeZone { get; set; } public string ShaderDumpPath { get; set; } - public string CustomThemePath - { - get - { - return _customThemePath; - } - set - { - _customThemePath = value; - - OnPropertyChanged(); - } - } - public int Language { get; set; } public int Region { get; set; } public int FsGlobalAccessLogMode { get; set; } @@ -448,8 +432,6 @@ namespace Ryujinx.Ava.UI.ViewModels GameDirectories.Clear(); GameDirectories.AddRange(config.Ui.GameDirs.Value); - EnableCustomTheme = config.Ui.EnableCustomTheme; - CustomThemePath = config.Ui.CustomThemePath; BaseStyleIndex = config.Ui.BaseStyle == "Light" ? 0 : 1; // Input @@ -538,8 +520,6 @@ namespace Ryujinx.Ava.UI.ViewModels config.Ui.GameDirs.Value = gameDirs; } - config.Ui.EnableCustomTheme.Value = EnableCustomTheme; - config.Ui.CustomThemePath.Value = CustomThemePath; config.Ui.BaseStyle.Value = BaseStyleIndex == 0 ? "Light" : "Dark"; // Input diff --git a/src/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs index 5090a8c70..8a287ecac 100644 --- a/src/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs +++ b/src/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs @@ -192,7 +192,7 @@ namespace Ryujinx.Ava.UI.ViewModels } catch (Exception ex) { - Dispatcher.UIThread.InvokeAsync(() => ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogLoadNcaErrorMessage, ex.Message, path))); + Dispatcher.UIThread.InvokeAsync(() => ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogLoadFileErrorMessage, ex.Message, path))); } } } diff --git a/src/Ryujinx.Ava/UI/ViewModels/UserSaveManagerViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/UserSaveManagerViewModel.cs index 0a13f24a8..85adef005 100644 --- a/src/Ryujinx.Ava/UI/ViewModels/UserSaveManagerViewModel.cs +++ b/src/Ryujinx.Ava/UI/ViewModels/UserSaveManagerViewModel.cs @@ -1,4 +1,4 @@ -using DynamicData; +using DynamicData; using DynamicData.Binding; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.UI.Models; diff --git a/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml b/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml index d636873a3..99f2b6b69 100644 --- a/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml +++ b/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml @@ -101,7 +101,7 @@ HorizontalAlignment="Stretch" VerticalAlignment="Center" SelectedIndex="0" - ItemsSource="{Binding ProfilesList}" + ItemsSource="{Binding ProfilesList}" Text="{Binding ProfileName, Mode=TwoWay}" /> - - - - - - - - - - - - - - - - - - - diff --git a/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml.cs b/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml.cs index ca1c40350..7f28ad352 100644 --- a/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml.cs +++ b/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml.cs @@ -1,4 +1,4 @@ -using Avalonia.Controls; +using Avalonia.Controls; using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.Layout; diff --git a/src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml b/src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml index caf7c1f3f..c587aa873 100644 --- a/src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml +++ b/src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml @@ -72,4 +72,4 @@ Click="CancelButton_Click" /> - \ No newline at end of file + diff --git a/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml b/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml index 8a5da5cc2..57d5f7eff 100644 --- a/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml +++ b/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml @@ -86,28 +86,16 @@ - - + + - - + + + - - - - - - - + LoadedCheats { get; } + public AvaloniaList LoadedCheats { get; } public string Heading { get; } public string BuildId { get; } @@ -33,7 +33,7 @@ namespace Ryujinx.Ava.UI.Windows public CheatWindow(VirtualFileSystem virtualFileSystem, string titleId, string titleName, string titlePath) { - LoadedCheats = new AvaloniaList(); + LoadedCheats = new AvaloniaList(); Heading = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.CheatWindowHeading, titleName, titleId.ToUpper()); BuildId = ApplicationData.GetApplicationBuildId(virtualFileSystem, titlePath); @@ -41,7 +41,7 @@ namespace Ryujinx.Ava.UI.Windows InitializeComponent(); string modsBasePath = ModLoader.GetModsBasePath(); - string titleModsPath = ModLoader.GetTitleDir(modsBasePath, titleId); + string titleModsPath = ModLoader.GetApplicationDir(modsBasePath, titleId); ulong titleIdValue = ulong.Parse(titleId, NumberStyles.HexNumber); _enabledCheatsPath = Path.Combine(titleModsPath, "cheats", "enabled.txt"); @@ -62,7 +62,7 @@ namespace Ryujinx.Ava.UI.Windows string currentCheatFile = string.Empty; string buildId = string.Empty; - CheatsList currentGroup = null; + CheatNode currentGroup = null; foreach (var cheat in mods.Cheats) { @@ -72,13 +72,13 @@ namespace Ryujinx.Ava.UI.Windows string parentPath = currentCheatFile.Replace(titleModsPath, ""); buildId = Path.GetFileNameWithoutExtension(currentCheatFile).ToUpper(); - currentGroup = new CheatsList(buildId, parentPath); + currentGroup = new CheatNode("", buildId, parentPath, true); LoadedCheats.Add(currentGroup); } - var model = new CheatModel(cheat.Name, buildId, enabled.Contains($"{buildId}-{cheat.Name}")); - currentGroup?.Add(model); + var model = new CheatNode(cheat.Name, buildId, "", false, enabled.Contains($"{buildId}-{cheat.Name}")); + currentGroup?.SubNodes.Add(model); cheatAdded++; } @@ -104,7 +104,7 @@ namespace Ryujinx.Ava.UI.Windows foreach (var cheats in LoadedCheats) { - foreach (var cheat in cheats) + foreach (var cheat in cheats.SubNodes) { if (cheat.IsEnabled) { diff --git a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml b/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml index 0d9a59499..4def7c281 100644 --- a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml +++ b/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml @@ -158,7 +158,7 @@ FontWeight="Bold" IsVisible="{Binding ShowLoadProgress}" Text="{Binding LoadHeading}" - TextAlignment="Left" + TextAlignment="Start" TextWrapping="Wrap" MaxWidth="500" /> @@ -202,4 +202,4 @@ Grid.Row="2" /> - \ No newline at end of file + diff --git a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs b/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs index baa80ea7c..1a3887b72 100644 --- a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs +++ b/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs @@ -263,7 +263,7 @@ namespace Ryujinx.Ava.UI.Windows } } - private void CheckLaunchState() + private async Task CheckLaunchState() { if (OperatingSystem.IsLinux() && LinuxHelper.VmMaxMapCount < LinuxHelper.RecommendedVmMaxMapCount) { @@ -271,23 +271,11 @@ namespace Ryujinx.Ava.UI.Windows if (LinuxHelper.PkExecPath is not null) { - Dispatcher.UIThread.Post(async () => - { - if (OperatingSystem.IsLinux()) - { - await ShowVmMaxMapCountDialog(); - } - }); + await Dispatcher.UIThread.InvokeAsync(ShowVmMaxMapCountDialog); } else { - Dispatcher.UIThread.Post(async () => - { - if (OperatingSystem.IsLinux()) - { - await ShowVmMaxMapCountWarning(); - } - }); + await Dispatcher.UIThread.InvokeAsync(ShowVmMaxMapCountWarning); } } @@ -304,12 +292,12 @@ namespace Ryujinx.Ava.UI.Windows { ShowKeyErrorOnLoad = false; - Dispatcher.UIThread.Post(async () => await UserErrorDialog.ShowUserErrorDialog(UserError.NoKeys)); + await Dispatcher.UIThread.InvokeAsync(async () => await UserErrorDialog.ShowUserErrorDialog(UserError.NoKeys)); } if (ConfigurationState.Instance.CheckUpdatesOnStart.Value && Updater.CanUpdate(false)) { - Updater.BeginParse(this, false).ContinueWith(task => + await Updater.BeginParse(this, false).ContinueWith(task => { Logger.Error?.Print(LogClass.Application, $"Updater Error: {task.Exception}"); }, TaskContinuationOptions.OnlyOnFaulted); @@ -404,7 +392,9 @@ namespace Ryujinx.Ava.UI.Windows LoadApplications(); +#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed CheckLaunchState(); +#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed } private void SetMainContent(Control content = null) @@ -437,10 +427,11 @@ namespace Ryujinx.Ava.UI.Windows { if (!volumeSplitButton.IsChecked) { - ViewModel.AppHost.Device.SetVolume(ConfigurationState.Instance.System.AudioVolume); + ViewModel.AppHost.Device.SetVolume(ViewModel.VolumeBeforeMute); } else { + ViewModel.VolumeBeforeMute = ViewModel.AppHost.Device.GetVolume(); ViewModel.AppHost.Device.SetVolume(0); } diff --git a/src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml b/src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml new file mode 100644 index 000000000..d9f586408 --- /dev/null +++ b/src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml @@ -0,0 +1,179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml.cs b/src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml.cs new file mode 100644 index 000000000..5de09ba0b --- /dev/null +++ b/src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml.cs @@ -0,0 +1,139 @@ +using Avalonia.Controls; +using Avalonia.Interactivity; +using Avalonia.Styling; +using FluentAvalonia.UI.Controls; +using Ryujinx.Ava.Common.Locale; +using Ryujinx.Ava.UI.Helpers; +using Ryujinx.Ava.UI.Models; +using Ryujinx.Ava.UI.ViewModels; +using Ryujinx.Ui.Common.Helper; +using System.Threading.Tasks; +using Button = Avalonia.Controls.Button; + +namespace Ryujinx.Ava.UI.Windows +{ + public partial class ModManagerWindow : UserControl + { + public ModManagerViewModel ViewModel; + + public ModManagerWindow() + { + DataContext = this; + + InitializeComponent(); + } + + public ModManagerWindow(ulong titleId) + { + DataContext = ViewModel = new ModManagerViewModel(titleId); + + InitializeComponent(); + } + + public static async Task Show(ulong titleId, string titleName) + { + ContentDialog contentDialog = new() + { + PrimaryButtonText = "", + SecondaryButtonText = "", + CloseButtonText = "", + Content = new ModManagerWindow(titleId), + Title = string.Format(LocaleManager.Instance[LocaleKeys.ModWindowHeading], titleName, titleId.ToString("X16")), + }; + + Style bottomBorder = new(x => x.OfType().Name("DialogSpace").Child().OfType()); + bottomBorder.Setters.Add(new Setter(IsVisibleProperty, false)); + + contentDialog.Styles.Add(bottomBorder); + + await contentDialog.ShowAsync(); + } + + private void SaveAndClose(object sender, RoutedEventArgs e) + { + ViewModel.Save(); + ((ContentDialog)Parent).Hide(); + } + + private void Close(object sender, RoutedEventArgs e) + { + ((ContentDialog)Parent).Hide(); + } + + private async void DeleteMod(object sender, RoutedEventArgs e) + { + if (sender is Button button) + { + if (button.DataContext is ModModel model) + { + var result = await ContentDialogHelper.CreateConfirmationDialog( + LocaleManager.Instance[LocaleKeys.DialogWarning], + LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogModManagerDeletionWarningMessage, model.Name), + LocaleManager.Instance[LocaleKeys.InputDialogYes], + LocaleManager.Instance[LocaleKeys.InputDialogNo], + LocaleManager.Instance[LocaleKeys.RyujinxConfirm]); + + if (result == UserResult.Yes) + { + ViewModel.Delete(model); + } + } + } + } + + private async void DeleteAll(object sender, RoutedEventArgs e) + { + var result = await ContentDialogHelper.CreateConfirmationDialog( + LocaleManager.Instance[LocaleKeys.DialogWarning], + LocaleManager.Instance[LocaleKeys.DialogModManagerDeletionAllWarningMessage], + LocaleManager.Instance[LocaleKeys.InputDialogYes], + LocaleManager.Instance[LocaleKeys.InputDialogNo], + LocaleManager.Instance[LocaleKeys.RyujinxConfirm]); + + if (result == UserResult.Yes) + { + ViewModel.DeleteAll(); + } + } + + private void OpenLocation(object sender, RoutedEventArgs e) + { + if (sender is Button button) + { + if (button.DataContext is ModModel model) + { + OpenHelper.OpenFolder(model.Path); + } + } + } + + private void OnSelectionChanged(object sender, SelectionChangedEventArgs e) + { + foreach (var content in e.AddedItems) + { + if (content is ModModel model) + { + var index = ViewModel.Mods.IndexOf(model); + + if (index != -1) + { + ViewModel.Mods[index].Enabled = true; + } + } + } + + foreach (var content in e.RemovedItems) + { + if (content is ModModel model) + { + var index = ViewModel.Mods.IndexOf(model); + + if (index != -1) + { + ViewModel.Mods[index].Enabled = false; + } + } + } + } + } +} diff --git a/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml b/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml index a0a75f611..40cac90dd 100644 --- a/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml +++ b/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml @@ -101,6 +101,9 @@ + - \ No newline at end of file + diff --git a/src/Ryujinx.Common/AsyncWorkQueue.cs b/src/Ryujinx.Common/AsyncWorkQueue.cs index e9f758985..abb5867b0 100644 --- a/src/Ryujinx.Common/AsyncWorkQueue.cs +++ b/src/Ryujinx.Common/AsyncWorkQueue.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Concurrent; using System.Threading; diff --git a/src/Ryujinx.Common/Collections/IntervalTree.cs b/src/Ryujinx.Common/Collections/IntervalTree.cs index baab579e7..d3a5e7fcf 100644 --- a/src/Ryujinx.Common/Collections/IntervalTree.cs +++ b/src/Ryujinx.Common/Collections/IntervalTree.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; diff --git a/src/Ryujinx.Common/Collections/TreeDictionary.cs b/src/Ryujinx.Common/Collections/TreeDictionary.cs index ff1794883..5379d353c 100644 --- a/src/Ryujinx.Common/Collections/TreeDictionary.cs +++ b/src/Ryujinx.Common/Collections/TreeDictionary.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; diff --git a/src/Ryujinx.Common/Configuration/AntiAliasing.cs b/src/Ryujinx.Common/Configuration/AntiAliasing.cs index 9ab0458cd..5e3e1b891 100644 --- a/src/Ryujinx.Common/Configuration/AntiAliasing.cs +++ b/src/Ryujinx.Common/Configuration/AntiAliasing.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System.Text.Json.Serialization; namespace Ryujinx.Common.Configuration diff --git a/src/Ryujinx.Common/Configuration/AppDataManager.cs b/src/Ryujinx.Common/Configuration/AppDataManager.cs index 2b4a594d3..35aea3c2f 100644 --- a/src/Ryujinx.Common/Configuration/AppDataManager.cs +++ b/src/Ryujinx.Common/Configuration/AppDataManager.cs @@ -1,4 +1,5 @@ using Ryujinx.Common.Logging; +using Ryujinx.Common.Utilities; using System; using System.IO; @@ -6,8 +7,8 @@ namespace Ryujinx.Common.Configuration { public static class AppDataManager { - public const string DefaultBaseDir = "Ryujinx"; - public const string DefaultPortableDir = "portable"; + private const string DefaultBaseDir = "Ryujinx"; + private const string DefaultPortableDir = "portable"; // The following 3 are always part of Base Directory private const string GamesDir = "games"; @@ -63,6 +64,17 @@ namespace Ryujinx.Common.Configuration string userProfilePath = Path.Combine(appDataPath, DefaultBaseDir); string portablePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, DefaultPortableDir); + // On macOS, check for a portable directory next to the app bundle as well. + if (OperatingSystem.IsMacOS() && !Directory.Exists(portablePath)) + { + string bundlePath = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..", "..")); + // Make sure we're actually running within an app bundle. + if (bundlePath.EndsWith(".app")) + { + portablePath = Path.GetFullPath(Path.Combine(bundlePath, "..", DefaultPortableDir)); + } + } + if (Directory.Exists(portablePath)) { BaseDirPath = portablePath; @@ -98,8 +110,7 @@ namespace Ryujinx.Common.Configuration string oldConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), DefaultBaseDir); if (Path.Exists(oldConfigPath) && !IsPathSymlink(oldConfigPath) && !Path.Exists(BaseDirPath)) { - CopyDirectory(oldConfigPath, BaseDirPath); - Directory.Delete(oldConfigPath, true); + FileSystemUtils.MoveDirectory(oldConfigPath, BaseDirPath); Directory.CreateSymbolicLink(oldConfigPath, BaseDirPath); } } @@ -116,41 +127,13 @@ namespace Ryujinx.Common.Configuration } // Check if existing old baseDirPath is a symlink, to prevent possible errors. - // Should be removed, when the existance of the old directory isn't checked anymore. + // Should be removed, when the existence of the old directory isn't checked anymore. private static bool IsPathSymlink(string path) { FileAttributes attributes = File.GetAttributes(path); return (attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint; } - private static void CopyDirectory(string sourceDir, string destinationDir) - { - var dir = new DirectoryInfo(sourceDir); - - if (!dir.Exists) - { - throw new DirectoryNotFoundException($"Source directory not found: {dir.FullName}"); - } - - DirectoryInfo[] subDirs = dir.GetDirectories(); - Directory.CreateDirectory(destinationDir); - - foreach (FileInfo file in dir.GetFiles()) - { - if (file.Name == ".DS_Store") - { - continue; - } - - file.CopyTo(Path.Combine(destinationDir, file.Name)); - } - - foreach (DirectoryInfo subDir in subDirs) - { - CopyDirectory(subDir.FullName, Path.Combine(destinationDir, subDir.Name)); - } - } - public static string GetModsPath() => CustomModsPath ?? Directory.CreateDirectory(Path.Combine(BaseDirPath, DefaultModsDir)).FullName; public static string GetSdModsPath() => CustomSdModsPath ?? Directory.CreateDirectory(Path.Combine(BaseDirPath, DefaultSdcardDir, "atmosphere")).FullName; } diff --git a/src/Ryujinx.Common/Configuration/AspectRatioExtensions.cs b/src/Ryujinx.Common/Configuration/AspectRatioExtensions.cs index c9bf24650..bae6e35de 100644 --- a/src/Ryujinx.Common/Configuration/AspectRatioExtensions.cs +++ b/src/Ryujinx.Common/Configuration/AspectRatioExtensions.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System.Text.Json.Serialization; namespace Ryujinx.Common.Configuration diff --git a/src/Ryujinx.Common/Configuration/BackendThreading.cs b/src/Ryujinx.Common/Configuration/BackendThreading.cs index 44aa422e4..4fbb56bcb 100644 --- a/src/Ryujinx.Common/Configuration/BackendThreading.cs +++ b/src/Ryujinx.Common/Configuration/BackendThreading.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System.Text.Json.Serialization; namespace Ryujinx.Common.Configuration diff --git a/src/Ryujinx.Common/Configuration/DownloadableContentContainer.cs b/src/Ryujinx.Common/Configuration/DownloadableContentContainer.cs index f9e68a3c2..6f12e9767 100644 --- a/src/Ryujinx.Common/Configuration/DownloadableContentContainer.cs +++ b/src/Ryujinx.Common/Configuration/DownloadableContentContainer.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Text.Json.Serialization; namespace Ryujinx.Common.Configuration diff --git a/src/Ryujinx.Common/Configuration/DownloadableContentJsonSerializerContext.cs b/src/Ryujinx.Common/Configuration/DownloadableContentJsonSerializerContext.cs index 0dbc0a301..cc89cb128 100644 --- a/src/Ryujinx.Common/Configuration/DownloadableContentJsonSerializerContext.cs +++ b/src/Ryujinx.Common/Configuration/DownloadableContentJsonSerializerContext.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Text.Json.Serialization; namespace Ryujinx.Common.Configuration diff --git a/src/Ryujinx.Common/Configuration/DownloadableContentNca.cs b/src/Ryujinx.Common/Configuration/DownloadableContentNca.cs index dded719cf..60d4a9bd6 100644 --- a/src/Ryujinx.Common/Configuration/DownloadableContentNca.cs +++ b/src/Ryujinx.Common/Configuration/DownloadableContentNca.cs @@ -1,4 +1,4 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace Ryujinx.Common.Configuration { diff --git a/src/Ryujinx.Common/Configuration/GraphicsBackend.cs b/src/Ryujinx.Common/Configuration/GraphicsBackend.cs index 8957c5ccc..e3b4f91b0 100644 --- a/src/Ryujinx.Common/Configuration/GraphicsBackend.cs +++ b/src/Ryujinx.Common/Configuration/GraphicsBackend.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System.Text.Json.Serialization; namespace Ryujinx.Common.Configuration diff --git a/src/Ryujinx.Common/Configuration/Hid/Controller/GamepadInputId.cs b/src/Ryujinx.Common/Configuration/Hid/Controller/GamepadInputId.cs index 78bc46f21..1380813b0 100644 --- a/src/Ryujinx.Common/Configuration/Hid/Controller/GamepadInputId.cs +++ b/src/Ryujinx.Common/Configuration/Hid/Controller/GamepadInputId.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System.Text.Json.Serialization; namespace Ryujinx.Common.Configuration.Hid.Controller diff --git a/src/Ryujinx.Common/Configuration/Hid/Controller/GenericControllerInputConfig.cs b/src/Ryujinx.Common/Configuration/Hid/Controller/GenericControllerInputConfig.cs index abc245bc4..e6fe74d53 100644 --- a/src/Ryujinx.Common/Configuration/Hid/Controller/GenericControllerInputConfig.cs +++ b/src/Ryujinx.Common/Configuration/Hid/Controller/GenericControllerInputConfig.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Configuration.Hid.Controller.Motion; +using Ryujinx.Common.Configuration.Hid.Controller.Motion; using System; using System.Text.Json.Serialization; diff --git a/src/Ryujinx.Common/Configuration/Hid/Controller/JoyconConfigControllerStick.cs b/src/Ryujinx.Common/Configuration/Hid/Controller/JoyconConfigControllerStick.cs index aaa3ef1d9..608681551 100644 --- a/src/Ryujinx.Common/Configuration/Hid/Controller/JoyconConfigControllerStick.cs +++ b/src/Ryujinx.Common/Configuration/Hid/Controller/JoyconConfigControllerStick.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Common.Configuration.Hid.Controller +namespace Ryujinx.Common.Configuration.Hid.Controller { public class JoyconConfigControllerStick where TButton : unmanaged where TStick : unmanaged { diff --git a/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/CemuHookMotionConfigController.cs b/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/CemuHookMotionConfigController.cs index 2a5a73ff0..1c31fff7b 100644 --- a/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/CemuHookMotionConfigController.cs +++ b/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/CemuHookMotionConfigController.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Common.Configuration.Hid.Controller.Motion +namespace Ryujinx.Common.Configuration.Hid.Controller.Motion { public class CemuHookMotionConfigController : MotionConfigController { diff --git a/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/JsonMotionConfigControllerConverter.cs b/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/JsonMotionConfigControllerConverter.cs index 613533718..40f067aea 100644 --- a/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/JsonMotionConfigControllerConverter.cs +++ b/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/JsonMotionConfigControllerConverter.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System; using System.Text.Json; using System.Text.Json.Serialization; diff --git a/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigController.cs b/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigController.cs index 7636aa414..7905ef062 100644 --- a/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigController.cs +++ b/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigController.cs @@ -1,4 +1,4 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace Ryujinx.Common.Configuration.Hid.Controller.Motion { diff --git a/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigJsonSerializerContext.cs b/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigJsonSerializerContext.cs index f9d154ffd..784e0cb11 100644 --- a/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigJsonSerializerContext.cs +++ b/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigJsonSerializerContext.cs @@ -1,4 +1,4 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace Ryujinx.Common.Configuration.Hid.Controller.Motion { diff --git a/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionInputBackendType.cs b/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionInputBackendType.cs index fac4e0f7a..fd8391289 100644 --- a/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionInputBackendType.cs +++ b/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionInputBackendType.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System.Text.Json.Serialization; namespace Ryujinx.Common.Configuration.Hid.Controller.Motion diff --git a/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/StandardMotionConfigController.cs b/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/StandardMotionConfigController.cs index df925444a..7f1ac40a2 100644 --- a/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/StandardMotionConfigController.cs +++ b/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/StandardMotionConfigController.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Common.Configuration.Hid.Controller.Motion +namespace Ryujinx.Common.Configuration.Hid.Controller.Motion { public class StandardMotionConfigController : MotionConfigController { } } diff --git a/src/Ryujinx.Common/Configuration/Hid/Controller/RumbleConfigController.cs b/src/Ryujinx.Common/Configuration/Hid/Controller/RumbleConfigController.cs index 48be4f13e..ee8ab457d 100644 --- a/src/Ryujinx.Common/Configuration/Hid/Controller/RumbleConfigController.cs +++ b/src/Ryujinx.Common/Configuration/Hid/Controller/RumbleConfigController.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Common.Configuration.Hid.Controller +namespace Ryujinx.Common.Configuration.Hid.Controller { public class RumbleConfigController { diff --git a/src/Ryujinx.Common/Configuration/Hid/Controller/StandardControllerInputConfig.cs b/src/Ryujinx.Common/Configuration/Hid/Controller/StandardControllerInputConfig.cs index 4154a42b0..cfd9755bf 100644 --- a/src/Ryujinx.Common/Configuration/Hid/Controller/StandardControllerInputConfig.cs +++ b/src/Ryujinx.Common/Configuration/Hid/Controller/StandardControllerInputConfig.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Common.Configuration.Hid.Controller +namespace Ryujinx.Common.Configuration.Hid.Controller { public class StandardControllerInputConfig : GenericControllerInputConfig { } } diff --git a/src/Ryujinx.Common/Configuration/Hid/Controller/StickInputId.cs b/src/Ryujinx.Common/Configuration/Hid/Controller/StickInputId.cs index cbe63e578..8f9539c46 100644 --- a/src/Ryujinx.Common/Configuration/Hid/Controller/StickInputId.cs +++ b/src/Ryujinx.Common/Configuration/Hid/Controller/StickInputId.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System.Text.Json.Serialization; namespace Ryujinx.Common.Configuration.Hid.Controller diff --git a/src/Ryujinx.Common/Configuration/Hid/GenericInputConfigurationCommon.cs b/src/Ryujinx.Common/Configuration/Hid/GenericInputConfigurationCommon.cs index 618e20b5c..c70594df4 100644 --- a/src/Ryujinx.Common/Configuration/Hid/GenericInputConfigurationCommon.cs +++ b/src/Ryujinx.Common/Configuration/Hid/GenericInputConfigurationCommon.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Common.Configuration.Hid +namespace Ryujinx.Common.Configuration.Hid { public class GenericInputConfigurationCommon : InputConfig where TButton : unmanaged { diff --git a/src/Ryujinx.Common/Configuration/Hid/InputBackendType.cs b/src/Ryujinx.Common/Configuration/Hid/InputBackendType.cs index 1db3f5703..c3e4402b2 100644 --- a/src/Ryujinx.Common/Configuration/Hid/InputBackendType.cs +++ b/src/Ryujinx.Common/Configuration/Hid/InputBackendType.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System.Text.Json.Serialization; namespace Ryujinx.Common.Configuration.Hid diff --git a/src/Ryujinx.Common/Configuration/Hid/InputConfig.cs b/src/Ryujinx.Common/Configuration/Hid/InputConfig.cs index 16a1042e3..a93b721ad 100644 --- a/src/Ryujinx.Common/Configuration/Hid/InputConfig.cs +++ b/src/Ryujinx.Common/Configuration/Hid/InputConfig.cs @@ -1,4 +1,4 @@ -using System.ComponentModel; +using System.ComponentModel; using System.Runtime.CompilerServices; using System.Text.Json.Serialization; diff --git a/src/Ryujinx.Common/Configuration/Hid/InputConfigJsonSerializerContext.cs b/src/Ryujinx.Common/Configuration/Hid/InputConfigJsonSerializerContext.cs index 30138049b..bd8be2491 100644 --- a/src/Ryujinx.Common/Configuration/Hid/InputConfigJsonSerializerContext.cs +++ b/src/Ryujinx.Common/Configuration/Hid/InputConfigJsonSerializerContext.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Configuration.Hid.Controller; +using Ryujinx.Common.Configuration.Hid.Controller; using Ryujinx.Common.Configuration.Hid.Keyboard; using System.Text.Json.Serialization; diff --git a/src/Ryujinx.Common/Configuration/Hid/JsonInputConfigConverter.cs b/src/Ryujinx.Common/Configuration/Hid/JsonInputConfigConverter.cs index 81b0d932d..6c2a69b88 100644 --- a/src/Ryujinx.Common/Configuration/Hid/JsonInputConfigConverter.cs +++ b/src/Ryujinx.Common/Configuration/Hid/JsonInputConfigConverter.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Configuration.Hid.Controller; +using Ryujinx.Common.Configuration.Hid.Controller; using Ryujinx.Common.Configuration.Hid.Keyboard; using Ryujinx.Common.Utilities; using System; diff --git a/src/Ryujinx.Common/Configuration/Hid/Key.cs b/src/Ryujinx.Common/Configuration/Hid/Key.cs index a82a99592..e3dd8e50c 100644 --- a/src/Ryujinx.Common/Configuration/Hid/Key.cs +++ b/src/Ryujinx.Common/Configuration/Hid/Key.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System.Text.Json.Serialization; namespace Ryujinx.Common.Configuration.Hid diff --git a/src/Ryujinx.Common/Configuration/Hid/Keyboard/GenericKeyboardInputConfig.cs b/src/Ryujinx.Common/Configuration/Hid/Keyboard/GenericKeyboardInputConfig.cs index 37819a26d..ecddd31e3 100644 --- a/src/Ryujinx.Common/Configuration/Hid/Keyboard/GenericKeyboardInputConfig.cs +++ b/src/Ryujinx.Common/Configuration/Hid/Keyboard/GenericKeyboardInputConfig.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Common.Configuration.Hid.Keyboard +namespace Ryujinx.Common.Configuration.Hid.Keyboard { public class GenericKeyboardInputConfig : GenericInputConfigurationCommon where TKey : unmanaged { diff --git a/src/Ryujinx.Common/Configuration/Hid/Keyboard/JoyconConfigKeyboardStick.cs b/src/Ryujinx.Common/Configuration/Hid/Keyboard/JoyconConfigKeyboardStick.cs index e0bdefc5c..36292a8b7 100644 --- a/src/Ryujinx.Common/Configuration/Hid/Keyboard/JoyconConfigKeyboardStick.cs +++ b/src/Ryujinx.Common/Configuration/Hid/Keyboard/JoyconConfigKeyboardStick.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Common.Configuration.Hid.Keyboard +namespace Ryujinx.Common.Configuration.Hid.Keyboard { public class JoyconConfigKeyboardStick where TKey : unmanaged { diff --git a/src/Ryujinx.Common/Configuration/Hid/Keyboard/StandardKeyboardInputConfig.cs b/src/Ryujinx.Common/Configuration/Hid/Keyboard/StandardKeyboardInputConfig.cs index 054d777d5..1e8b188e7 100644 --- a/src/Ryujinx.Common/Configuration/Hid/Keyboard/StandardKeyboardInputConfig.cs +++ b/src/Ryujinx.Common/Configuration/Hid/Keyboard/StandardKeyboardInputConfig.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Common.Configuration.Hid.Keyboard +namespace Ryujinx.Common.Configuration.Hid.Keyboard { public class StandardKeyboardInputConfig : GenericKeyboardInputConfig { } } diff --git a/src/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs b/src/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs index f0707c73d..b4f2f9468 100644 --- a/src/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs +++ b/src/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Common.Configuration.Hid +namespace Ryujinx.Common.Configuration.Hid { // NOTE: Please don't change this to struct. // This breaks Avalonia's TwoWay binding, which makes us unable to save new KeyboardHotkeys. diff --git a/src/Ryujinx.Common/Configuration/Hid/LeftJoyconCommonConfig.cs b/src/Ryujinx.Common/Configuration/Hid/LeftJoyconCommonConfig.cs index 4ae890721..140453555 100644 --- a/src/Ryujinx.Common/Configuration/Hid/LeftJoyconCommonConfig.cs +++ b/src/Ryujinx.Common/Configuration/Hid/LeftJoyconCommonConfig.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Common.Configuration.Hid +namespace Ryujinx.Common.Configuration.Hid { public class LeftJoyconCommonConfig { diff --git a/src/Ryujinx.Common/Configuration/Hid/RightJoyconCommonConfig.cs b/src/Ryujinx.Common/Configuration/Hid/RightJoyconCommonConfig.cs index e121b9a52..1fb99104f 100644 --- a/src/Ryujinx.Common/Configuration/Hid/RightJoyconCommonConfig.cs +++ b/src/Ryujinx.Common/Configuration/Hid/RightJoyconCommonConfig.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Common.Configuration.Hid +namespace Ryujinx.Common.Configuration.Hid { public class RightJoyconCommonConfig { diff --git a/src/Ryujinx.Common/Configuration/MemoryManagerMode.cs b/src/Ryujinx.Common/Configuration/MemoryManagerMode.cs index 8b7150b5c..93031928f 100644 --- a/src/Ryujinx.Common/Configuration/MemoryManagerMode.cs +++ b/src/Ryujinx.Common/Configuration/MemoryManagerMode.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System.Text.Json.Serialization; namespace Ryujinx.Common.Configuration diff --git a/src/Ryujinx.Common/Configuration/Mod.cs b/src/Ryujinx.Common/Configuration/Mod.cs new file mode 100644 index 000000000..052c7c8d1 --- /dev/null +++ b/src/Ryujinx.Common/Configuration/Mod.cs @@ -0,0 +1,9 @@ +namespace Ryujinx.Common.Configuration +{ + public class Mod + { + public string Name { get; set; } + public string Path { get; set; } + public bool Enabled { get; set; } + } +} diff --git a/src/Ryujinx.Common/Configuration/ModMetadata.cs b/src/Ryujinx.Common/Configuration/ModMetadata.cs new file mode 100644 index 000000000..174320d0a --- /dev/null +++ b/src/Ryujinx.Common/Configuration/ModMetadata.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; + +namespace Ryujinx.Common.Configuration +{ + public struct ModMetadata + { + public List Mods { get; set; } + + public ModMetadata() + { + Mods = new List(); + } + } +} diff --git a/src/Ryujinx.Common/Configuration/ModMetadataJsonSerializerContext.cs b/src/Ryujinx.Common/Configuration/ModMetadataJsonSerializerContext.cs new file mode 100644 index 000000000..8c1e242ad --- /dev/null +++ b/src/Ryujinx.Common/Configuration/ModMetadataJsonSerializerContext.cs @@ -0,0 +1,10 @@ +using System.Text.Json.Serialization; + +namespace Ryujinx.Common.Configuration +{ + [JsonSourceGenerationOptions(WriteIndented = true)] + [JsonSerializable(typeof(ModMetadata))] + public partial class ModMetadataJsonSerializerContext : JsonSerializerContext + { + } +} diff --git a/src/Ryujinx.Common/Configuration/Multiplayer/MultiplayerMode.cs b/src/Ryujinx.Common/Configuration/Multiplayer/MultiplayerMode.cs index 05108716d..69f7d876d 100644 --- a/src/Ryujinx.Common/Configuration/Multiplayer/MultiplayerMode.cs +++ b/src/Ryujinx.Common/Configuration/Multiplayer/MultiplayerMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Common.Configuration.Multiplayer +namespace Ryujinx.Common.Configuration.Multiplayer { public enum MultiplayerMode { diff --git a/src/Ryujinx.Common/Configuration/TitleUpdateMetadata.cs b/src/Ryujinx.Common/Configuration/TitleUpdateMetadata.cs index 17a13bf15..a1b14f6f7 100644 --- a/src/Ryujinx.Common/Configuration/TitleUpdateMetadata.cs +++ b/src/Ryujinx.Common/Configuration/TitleUpdateMetadata.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace Ryujinx.Common.Configuration { diff --git a/src/Ryujinx.Common/Configuration/TitleUpdateMetadataJsonSerializerContext.cs b/src/Ryujinx.Common/Configuration/TitleUpdateMetadataJsonSerializerContext.cs index 4cfd232c7..a4b6efff4 100644 --- a/src/Ryujinx.Common/Configuration/TitleUpdateMetadataJsonSerializerContext.cs +++ b/src/Ryujinx.Common/Configuration/TitleUpdateMetadataJsonSerializerContext.cs @@ -1,4 +1,4 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace Ryujinx.Common.Configuration { diff --git a/src/Ryujinx.Common/Extensions/BinaryReaderExtensions.cs b/src/Ryujinx.Common/Extensions/BinaryReaderExtensions.cs index 3b82f96a2..dece2384c 100644 --- a/src/Ryujinx.Common/Extensions/BinaryReaderExtensions.cs +++ b/src/Ryujinx.Common/Extensions/BinaryReaderExtensions.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Common/Extensions/BinaryWriterExtensions.cs b/src/Ryujinx.Common/Extensions/BinaryWriterExtensions.cs index c96bc698f..9c3e72329 100644 --- a/src/Ryujinx.Common/Extensions/BinaryWriterExtensions.cs +++ b/src/Ryujinx.Common/Extensions/BinaryWriterExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Common/Extensions/StreamExtensions.cs b/src/Ryujinx.Common/Extensions/StreamExtensions.cs index f6fc870ab..431d5534a 100644 --- a/src/Ryujinx.Common/Extensions/StreamExtensions.cs +++ b/src/Ryujinx.Common/Extensions/StreamExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Buffers.Binary; using System.IO; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Common/GraphicsDriver/DriverUtilities.cs b/src/Ryujinx.Common/GraphicsDriver/DriverUtilities.cs index 3aabced7c..7fe2a4f02 100644 --- a/src/Ryujinx.Common/GraphicsDriver/DriverUtilities.cs +++ b/src/Ryujinx.Common/GraphicsDriver/DriverUtilities.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Common.GraphicsDriver { diff --git a/src/Ryujinx.Common/GraphicsDriver/NVAPI/Nvapi.cs b/src/Ryujinx.Common/GraphicsDriver/NVAPI/Nvapi.cs index 60b9455c7..985e5e6d3 100644 --- a/src/Ryujinx.Common/GraphicsDriver/NVAPI/Nvapi.cs +++ b/src/Ryujinx.Common/GraphicsDriver/NVAPI/Nvapi.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Common.GraphicsDriver.NVAPI +namespace Ryujinx.Common.GraphicsDriver.NVAPI { enum Nvapi : uint { diff --git a/src/Ryujinx.Common/GraphicsDriver/NVAPI/NvapiUnicodeString.cs b/src/Ryujinx.Common/GraphicsDriver/NVAPI/NvapiUnicodeString.cs index 4a71ce70b..f3e0ffd02 100644 --- a/src/Ryujinx.Common/GraphicsDriver/NVAPI/NvapiUnicodeString.cs +++ b/src/Ryujinx.Common/GraphicsDriver/NVAPI/NvapiUnicodeString.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; using System.Text; namespace Ryujinx.Common.GraphicsDriver.NVAPI diff --git a/src/Ryujinx.Common/GraphicsDriver/NVAPI/NvdrsApplicationV4.cs b/src/Ryujinx.Common/GraphicsDriver/NVAPI/NvdrsApplicationV4.cs index 78e1b6952..39820bfef 100644 --- a/src/Ryujinx.Common/GraphicsDriver/NVAPI/NvdrsApplicationV4.cs +++ b/src/Ryujinx.Common/GraphicsDriver/NVAPI/NvdrsApplicationV4.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.Common.GraphicsDriver.NVAPI { diff --git a/src/Ryujinx.Common/GraphicsDriver/NVAPI/NvdrsProfile.cs b/src/Ryujinx.Common/GraphicsDriver/NVAPI/NvdrsProfile.cs index 6d9b8e51b..f9fe4ed41 100644 --- a/src/Ryujinx.Common/GraphicsDriver/NVAPI/NvdrsProfile.cs +++ b/src/Ryujinx.Common/GraphicsDriver/NVAPI/NvdrsProfile.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.Common.GraphicsDriver.NVAPI { diff --git a/src/Ryujinx.Common/GraphicsDriver/NVAPI/NvdrsSetting.cs b/src/Ryujinx.Common/GraphicsDriver/NVAPI/NvdrsSetting.cs index 6cd0360dd..a36781baf 100644 --- a/src/Ryujinx.Common/GraphicsDriver/NVAPI/NvdrsSetting.cs +++ b/src/Ryujinx.Common/GraphicsDriver/NVAPI/NvdrsSetting.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.Common.GraphicsDriver.NVAPI { diff --git a/src/Ryujinx.Common/GraphicsDriver/NVThreadedOptimization.cs b/src/Ryujinx.Common/GraphicsDriver/NVThreadedOptimization.cs index cda889d96..f7b11783d 100644 --- a/src/Ryujinx.Common/GraphicsDriver/NVThreadedOptimization.cs +++ b/src/Ryujinx.Common/GraphicsDriver/NVThreadedOptimization.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.GraphicsDriver.NVAPI; +using Ryujinx.Common.GraphicsDriver.NVAPI; using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Common/Hash128.cs b/src/Ryujinx.Common/Hash128.cs index 28c0946b3..e0ffd230e 100644 --- a/src/Ryujinx.Common/Hash128.cs +++ b/src/Ryujinx.Common/Hash128.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; namespace Ryujinx.Common diff --git a/src/Ryujinx.Common/Logging/Formatters/DefaultLogFormatter.cs b/src/Ryujinx.Common/Logging/Formatters/DefaultLogFormatter.cs index ed2a8144b..b1cffcb56 100644 --- a/src/Ryujinx.Common/Logging/Formatters/DefaultLogFormatter.cs +++ b/src/Ryujinx.Common/Logging/Formatters/DefaultLogFormatter.cs @@ -1,4 +1,4 @@ -using System.Diagnostics; +using System.Diagnostics; using System.Text; namespace Ryujinx.Common.Logging.Formatters diff --git a/src/Ryujinx.Common/Logging/Formatters/DynamicObjectFormatter.cs b/src/Ryujinx.Common/Logging/Formatters/DynamicObjectFormatter.cs index 1ee73acd6..b1cc0eae3 100644 --- a/src/Ryujinx.Common/Logging/Formatters/DynamicObjectFormatter.cs +++ b/src/Ryujinx.Common/Logging/Formatters/DynamicObjectFormatter.cs @@ -1,4 +1,4 @@ -#nullable enable +#nullable enable using System; using System.Reflection; using System.Text; diff --git a/src/Ryujinx.Common/Logging/Formatters/ILogFormatter.cs b/src/Ryujinx.Common/Logging/Formatters/ILogFormatter.cs index 5c660a52b..3a2261a6b 100644 --- a/src/Ryujinx.Common/Logging/Formatters/ILogFormatter.cs +++ b/src/Ryujinx.Common/Logging/Formatters/ILogFormatter.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Common.Logging.Formatters +namespace Ryujinx.Common.Logging.Formatters { interface ILogFormatter { diff --git a/src/Ryujinx.Common/Logging/LogEventArgsJson.cs b/src/Ryujinx.Common/Logging/LogEventArgsJson.cs index 9628a757c..7c745d63e 100644 --- a/src/Ryujinx.Common/Logging/LogEventArgsJson.cs +++ b/src/Ryujinx.Common/Logging/LogEventArgsJson.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging.Formatters; +using Ryujinx.Common.Logging.Formatters; using System; using System.Text.Json.Serialization; diff --git a/src/Ryujinx.Common/Logging/LogEventJsonSerializerContext.cs b/src/Ryujinx.Common/Logging/LogEventJsonSerializerContext.cs index c5dd6114e..ac63d9a10 100644 --- a/src/Ryujinx.Common/Logging/LogEventJsonSerializerContext.cs +++ b/src/Ryujinx.Common/Logging/LogEventJsonSerializerContext.cs @@ -1,4 +1,4 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace Ryujinx.Common.Logging { diff --git a/src/Ryujinx.Common/Logging/Targets/AsyncLogTargetWrapper.cs b/src/Ryujinx.Common/Logging/Targets/AsyncLogTargetWrapper.cs index 226318b0d..02c6dc97b 100644 --- a/src/Ryujinx.Common/Logging/Targets/AsyncLogTargetWrapper.cs +++ b/src/Ryujinx.Common/Logging/Targets/AsyncLogTargetWrapper.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Concurrent; using System.Threading; diff --git a/src/Ryujinx.Common/Logging/Targets/ConsoleLogTarget.cs b/src/Ryujinx.Common/Logging/Targets/ConsoleLogTarget.cs index 16735834a..42ba00cd5 100644 --- a/src/Ryujinx.Common/Logging/Targets/ConsoleLogTarget.cs +++ b/src/Ryujinx.Common/Logging/Targets/ConsoleLogTarget.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging.Formatters; +using Ryujinx.Common.Logging.Formatters; using System; namespace Ryujinx.Common.Logging.Targets diff --git a/src/Ryujinx.Common/Logging/Targets/FileLogTarget.cs b/src/Ryujinx.Common/Logging/Targets/FileLogTarget.cs index 8d1a94e51..a4e8f7147 100644 --- a/src/Ryujinx.Common/Logging/Targets/FileLogTarget.cs +++ b/src/Ryujinx.Common/Logging/Targets/FileLogTarget.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging.Formatters; +using Ryujinx.Common.Logging.Formatters; using System; using System.IO; using System.Linq; @@ -13,31 +13,71 @@ namespace Ryujinx.Common.Logging.Targets string ILogTarget.Name { get => _name; } - public FileLogTarget(string path, string name) - : this(path, name, FileShare.Read, FileMode.Append) - { } + public FileLogTarget(string name, FileStream fileStream) + { + _name = name; + _logWriter = new StreamWriter(fileStream); + _formatter = new DefaultLogFormatter(); + } - public FileLogTarget(string path, string name, FileShare fileShare, FileMode fileMode) + public static FileStream PrepareLogFile(string path) { // Ensure directory is present - DirectoryInfo logDir = new(Path.Combine(path, "Logs")); - logDir.Create(); + DirectoryInfo logDir = new(path); + try + { + logDir.Create(); + } + catch (IOException exception) + { + Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}': {exception}"); + + return null; + } // Clean up old logs, should only keep 3 FileInfo[] files = logDir.GetFiles("*.log").OrderBy((info => info.CreationTime)).ToArray(); for (int i = 0; i < files.Length - 2; i++) { - files[i].Delete(); + try + { + files[i].Delete(); + } + catch (UnauthorizedAccessException exception) + { + Logger.Warning?.Print(LogClass.Application, $"Old log file could not be deleted '{files[i].FullName}': {exception}"); + + return null; + } + catch (IOException exception) + { + Logger.Warning?.Print(LogClass.Application, $"Old log file could not be deleted '{files[i].FullName}': {exception}"); + + return null; + } } - string version = ReleaseInformation.GetVersion(); + string version = ReleaseInformation.Version; // Get path for the current time path = Path.Combine(logDir.FullName, $"Ryujinx_{version}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.log"); - _name = name; - _logWriter = new StreamWriter(File.Open(path, fileMode, FileAccess.Write, fileShare)); - _formatter = new DefaultLogFormatter(); + try + { + return File.Open(path, FileMode.Append, FileAccess.Write, FileShare.Read); + } + catch (UnauthorizedAccessException exception) + { + Logger.Warning?.Print(LogClass.Application, $"Log file could not be created '{path}': {exception}"); + + return null; + } + catch (IOException exception) + { + Logger.Warning?.Print(LogClass.Application, $"Log file could not be created '{path}': {exception}"); + + return null; + } } public void Log(object sender, LogEventArgs args) diff --git a/src/Ryujinx.Common/Logging/Targets/ILogTarget.cs b/src/Ryujinx.Common/Logging/Targets/ILogTarget.cs index e3b1ad208..2d7aca4fe 100644 --- a/src/Ryujinx.Common/Logging/Targets/ILogTarget.cs +++ b/src/Ryujinx.Common/Logging/Targets/ILogTarget.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Common.Logging.Targets { diff --git a/src/Ryujinx.Common/Logging/Targets/JsonLogTarget.cs b/src/Ryujinx.Common/Logging/Targets/JsonLogTarget.cs index 1873dc606..c5bf23cdb 100644 --- a/src/Ryujinx.Common/Logging/Targets/JsonLogTarget.cs +++ b/src/Ryujinx.Common/Logging/Targets/JsonLogTarget.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System; using System.IO; diff --git a/src/Ryujinx.Common/Memory/ArrayPtr.cs b/src/Ryujinx.Common/Memory/ArrayPtr.cs index 0365a5089..7487a1ff5 100644 --- a/src/Ryujinx.Common/Memory/ArrayPtr.cs +++ b/src/Ryujinx.Common/Memory/ArrayPtr.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Common/Memory/Box.cs b/src/Ryujinx.Common/Memory/Box.cs index 743cc31dc..e7dd76a65 100644 --- a/src/Ryujinx.Common/Memory/Box.cs +++ b/src/Ryujinx.Common/Memory/Box.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Common.Memory +namespace Ryujinx.Common.Memory { public class Box where T : unmanaged { diff --git a/src/Ryujinx.Common/Memory/ByteMemoryPool.ByteMemoryPoolBuffer.cs b/src/Ryujinx.Common/Memory/ByteMemoryPool.ByteMemoryPoolBuffer.cs index 8f2a61c85..df3f8dc93 100644 --- a/src/Ryujinx.Common/Memory/ByteMemoryPool.ByteMemoryPoolBuffer.cs +++ b/src/Ryujinx.Common/Memory/ByteMemoryPool.ByteMemoryPoolBuffer.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Buffers; using System.Threading; diff --git a/src/Ryujinx.Common/Memory/ByteMemoryPool.cs b/src/Ryujinx.Common/Memory/ByteMemoryPool.cs index b63449f83..071f56b13 100644 --- a/src/Ryujinx.Common/Memory/ByteMemoryPool.cs +++ b/src/Ryujinx.Common/Memory/ByteMemoryPool.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Buffers; namespace Ryujinx.Common.Memory diff --git a/src/Ryujinx.Common/Memory/IArray.cs b/src/Ryujinx.Common/Memory/IArray.cs index 8f17fade0..3e0385c2d 100644 --- a/src/Ryujinx.Common/Memory/IArray.cs +++ b/src/Ryujinx.Common/Memory/IArray.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Common.Memory +namespace Ryujinx.Common.Memory { /// /// Array interface. diff --git a/src/Ryujinx.Common/Memory/MemoryStreamManager.cs b/src/Ryujinx.Common/Memory/MemoryStreamManager.cs index cc3a59682..834210e07 100644 --- a/src/Ryujinx.Common/Memory/MemoryStreamManager.cs +++ b/src/Ryujinx.Common/Memory/MemoryStreamManager.cs @@ -1,4 +1,4 @@ -using Microsoft.IO; +using Microsoft.IO; using System; namespace Ryujinx.Common.Memory diff --git a/src/Ryujinx.Common/Memory/PartialUnmaps/NativeReaderWriterLock.cs b/src/Ryujinx.Common/Memory/PartialUnmaps/NativeReaderWriterLock.cs index 03d48fd8d..17106ae5f 100644 --- a/src/Ryujinx.Common/Memory/PartialUnmaps/NativeReaderWriterLock.cs +++ b/src/Ryujinx.Common/Memory/PartialUnmaps/NativeReaderWriterLock.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; using System.Threading; using static Ryujinx.Common.Memory.PartialUnmaps.PartialUnmapHelpers; diff --git a/src/Ryujinx.Common/Memory/PartialUnmaps/PartialUnmapHelpers.cs b/src/Ryujinx.Common/Memory/PartialUnmaps/PartialUnmapHelpers.cs index e650de068..0daa7c464 100644 --- a/src/Ryujinx.Common/Memory/PartialUnmaps/PartialUnmapHelpers.cs +++ b/src/Ryujinx.Common/Memory/PartialUnmaps/PartialUnmapHelpers.cs @@ -1,4 +1,4 @@ -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; namespace Ryujinx.Common.Memory.PartialUnmaps { diff --git a/src/Ryujinx.Common/Memory/PartialUnmaps/PartialUnmapState.cs b/src/Ryujinx.Common/Memory/PartialUnmaps/PartialUnmapState.cs index a583930b7..93fef5c3b 100644 --- a/src/Ryujinx.Common/Memory/PartialUnmaps/PartialUnmapState.cs +++ b/src/Ryujinx.Common/Memory/PartialUnmaps/PartialUnmapState.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; diff --git a/src/Ryujinx.Common/Memory/PartialUnmaps/ThreadLocalMap.cs b/src/Ryujinx.Common/Memory/PartialUnmaps/ThreadLocalMap.cs index a3c3dc57b..009aff628 100644 --- a/src/Ryujinx.Common/Memory/PartialUnmaps/ThreadLocalMap.cs +++ b/src/Ryujinx.Common/Memory/PartialUnmaps/ThreadLocalMap.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; using System.Threading; using static Ryujinx.Common.Memory.PartialUnmaps.PartialUnmapHelpers; diff --git a/src/Ryujinx.Common/Memory/Ptr.cs b/src/Ryujinx.Common/Memory/Ptr.cs index 5285d756f..d01748c16 100644 --- a/src/Ryujinx.Common/Memory/Ptr.cs +++ b/src/Ryujinx.Common/Memory/Ptr.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Common/Memory/SpanOrArray.cs b/src/Ryujinx.Common/Memory/SpanOrArray.cs index a9798d278..269ac02fd 100644 --- a/src/Ryujinx.Common/Memory/SpanOrArray.cs +++ b/src/Ryujinx.Common/Memory/SpanOrArray.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Common.Memory { diff --git a/src/Ryujinx.Common/Memory/SpanWriter.cs b/src/Ryujinx.Common/Memory/SpanWriter.cs index 248acc42b..5866652dc 100644 --- a/src/Ryujinx.Common/Memory/SpanWriter.cs +++ b/src/Ryujinx.Common/Memory/SpanWriter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Common/Memory/StructArrayHelpers.cs b/src/Ryujinx.Common/Memory/StructArrayHelpers.cs index 807bd69c3..762c73889 100644 --- a/src/Ryujinx.Common/Memory/StructArrayHelpers.cs +++ b/src/Ryujinx.Common/Memory/StructArrayHelpers.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics.Contracts; using System.Runtime.InteropServices; @@ -744,6 +744,17 @@ namespace Ryujinx.Common.Memory public Span AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); } + public struct Array65 : IArray where T : unmanaged + { + T _e0; + Array64 _other; + public readonly int Length => 65; + public ref T this[int index] => ref AsSpan()[index]; + + [Pure] + public Span AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length); + } + public struct Array73 : IArray where T : unmanaged { T _e0; diff --git a/src/Ryujinx.Common/Memory/StructByteArrayHelpers.cs b/src/Ryujinx.Common/Memory/StructByteArrayHelpers.cs index f0f452730..79b7d681a 100644 --- a/src/Ryujinx.Common/Memory/StructByteArrayHelpers.cs +++ b/src/Ryujinx.Common/Memory/StructByteArrayHelpers.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; namespace Ryujinx.Common.Memory @@ -63,6 +63,18 @@ namespace Ryujinx.Common.Memory public Span AsSpan() => MemoryMarshal.CreateSpan(ref _element, Size); } + [StructLayout(LayoutKind.Sequential, Size = Size, Pack = 1)] + public struct ByteArray3000 : IArray + { + private const int Size = 3000; + + byte _element; + + public readonly int Length => Size; + public ref byte this[int index] => ref AsSpan()[index]; + public Span AsSpan() => MemoryMarshal.CreateSpan(ref _element, Size); + } + [StructLayout(LayoutKind.Sequential, Size = Size, Pack = 1)] public struct ByteArray4096 : IArray { diff --git a/src/Ryujinx.Common/PerformanceCounter.cs b/src/Ryujinx.Common/PerformanceCounter.cs index 4b49c5c9e..8c40fd7f4 100644 --- a/src/Ryujinx.Common/PerformanceCounter.cs +++ b/src/Ryujinx.Common/PerformanceCounter.cs @@ -1,4 +1,4 @@ -using System.Diagnostics; +using System.Diagnostics; namespace Ryujinx.Common { diff --git a/src/Ryujinx.Common/Pools/ObjectPool.cs b/src/Ryujinx.Common/Pools/ObjectPool.cs index a0d3feb95..0b6ce3771 100644 --- a/src/Ryujinx.Common/Pools/ObjectPool.cs +++ b/src/Ryujinx.Common/Pools/ObjectPool.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading; namespace Ryujinx.Common diff --git a/src/Ryujinx.Common/Pools/SharedPools.cs b/src/Ryujinx.Common/Pools/SharedPools.cs index 272a74180..342eab4dd 100644 --- a/src/Ryujinx.Common/Pools/SharedPools.cs +++ b/src/Ryujinx.Common/Pools/SharedPools.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Common +namespace Ryujinx.Common { public static class SharedPools { diff --git a/src/Ryujinx.Common/Pools/ThreadStaticArray.cs b/src/Ryujinx.Common/Pools/ThreadStaticArray.cs index 54df50419..a2b9811c5 100644 --- a/src/Ryujinx.Common/Pools/ThreadStaticArray.cs +++ b/src/Ryujinx.Common/Pools/ThreadStaticArray.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Common.Pools { diff --git a/src/Ryujinx.Common/PreciseSleep/WindowsGranularTimer.cs b/src/Ryujinx.Common/PreciseSleep/WindowsGranularTimer.cs index a0de16341..3bf092704 100644 --- a/src/Ryujinx.Common/PreciseSleep/WindowsGranularTimer.cs +++ b/src/Ryujinx.Common/PreciseSleep/WindowsGranularTimer.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Runtime.Versioning; diff --git a/src/Ryujinx.Common/ReactiveObject.cs b/src/Ryujinx.Common/ReactiveObject.cs index ac7d2c4d8..4831edb52 100644 --- a/src/Ryujinx.Common/ReactiveObject.cs +++ b/src/Ryujinx.Common/ReactiveObject.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading; namespace Ryujinx.Common diff --git a/src/Ryujinx.Common/ReferenceEqualityComparer.cs b/src/Ryujinx.Common/ReferenceEqualityComparer.cs index d8ec29d83..714a967a4 100644 --- a/src/Ryujinx.Common/ReferenceEqualityComparer.cs +++ b/src/Ryujinx.Common/ReferenceEqualityComparer.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; namespace Ryujinx.Common diff --git a/src/Ryujinx.Common/ReleaseInformation.cs b/src/Ryujinx.Common/ReleaseInformation.cs index b561ef03e..774ae012a 100644 --- a/src/Ryujinx.Common/ReleaseInformation.cs +++ b/src/Ryujinx.Common/ReleaseInformation.cs @@ -1,5 +1,3 @@ -using Ryujinx.Common.Configuration; -using System; using System.Reflection; namespace Ryujinx.Common @@ -9,50 +7,25 @@ namespace Ryujinx.Common { private const string FlatHubChannelOwner = "flathub"; - public const string BuildVersion = "%%RYUJINX_BUILD_VERSION%%"; - public const string BuildGitHash = "%%RYUJINX_BUILD_GIT_HASH%%"; - public const string ReleaseChannelName = "%%RYUJINX_TARGET_RELEASE_CHANNEL_NAME%%"; + private const string BuildVersion = "%%RYUJINX_BUILD_VERSION%%"; + private const string BuildGitHash = "%%RYUJINX_BUILD_GIT_HASH%%"; + private const string ReleaseChannelName = "%%RYUJINX_TARGET_RELEASE_CHANNEL_NAME%%"; + private const string ConfigFileName = "%%RYUJINX_CONFIG_FILE_NAME%%"; + public const string ReleaseChannelOwner = "%%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER%%"; public const string ReleaseChannelRepo = "%%RYUJINX_TARGET_RELEASE_CHANNEL_REPO%%"; - public static bool IsValid() - { - return !BuildGitHash.StartsWith("%%") && - !ReleaseChannelName.StartsWith("%%") && - !ReleaseChannelOwner.StartsWith("%%") && - !ReleaseChannelRepo.StartsWith("%%"); - } + public static string ConfigName => !ConfigFileName.StartsWith("%%") ? ConfigFileName : "Config.json"; - public static bool IsFlatHubBuild() - { - return IsValid() && ReleaseChannelOwner.Equals(FlatHubChannelOwner); - } + public static bool IsValid => + !BuildGitHash.StartsWith("%%") && + !ReleaseChannelName.StartsWith("%%") && + !ReleaseChannelOwner.StartsWith("%%") && + !ReleaseChannelRepo.StartsWith("%%") && + !ConfigFileName.StartsWith("%%"); - public static string GetVersion() - { - if (IsValid()) - { - return BuildVersion; - } + public static bool IsFlatHubBuild => IsValid && ReleaseChannelOwner.Equals(FlatHubChannelOwner); - return Assembly.GetEntryAssembly().GetCustomAttribute().InformationalVersion; - } - -#if FORCE_EXTERNAL_BASE_DIR - public static string GetBaseApplicationDirectory() - { - return AppDataManager.BaseDirPath; - } -#else - public static string GetBaseApplicationDirectory() - { - if (IsFlatHubBuild() || OperatingSystem.IsMacOS()) - { - return AppDataManager.BaseDirPath; - } - - return AppDomain.CurrentDomain.BaseDirectory; - } -#endif + public static string Version => IsValid ? BuildVersion : Assembly.GetEntryAssembly()!.GetCustomAttribute()?.InformationalVersion; } } diff --git a/src/Ryujinx.Common/SystemInterop/ForceDpiAware.cs b/src/Ryujinx.Common/SystemInterop/ForceDpiAware.cs index 3af96ba12..b8e1df7d2 100644 --- a/src/Ryujinx.Common/SystemInterop/ForceDpiAware.cs +++ b/src/Ryujinx.Common/SystemInterop/ForceDpiAware.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using System; using System.Globalization; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Common/SystemInterop/GdiPlusHelper.cs b/src/Ryujinx.Common/SystemInterop/GdiPlusHelper.cs index bedf56ea4..7e8e9f2a5 100644 --- a/src/Ryujinx.Common/SystemInterop/GdiPlusHelper.cs +++ b/src/Ryujinx.Common/SystemInterop/GdiPlusHelper.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; using System.Runtime.Versioning; diff --git a/src/Ryujinx.Common/SystemInterop/WindowsMultimediaTimerResolution.cs b/src/Ryujinx.Common/SystemInterop/WindowsMultimediaTimerResolution.cs index 88acadd57..0fbce37e2 100644 --- a/src/Ryujinx.Common/SystemInterop/WindowsMultimediaTimerResolution.cs +++ b/src/Ryujinx.Common/SystemInterop/WindowsMultimediaTimerResolution.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Common/Utilities/Buffers.cs b/src/Ryujinx.Common/Utilities/Buffers.cs index c85b87130..b66f6025e 100644 --- a/src/Ryujinx.Common/Utilities/Buffers.cs +++ b/src/Ryujinx.Common/Utilities/Buffers.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Common/Utilities/CommonJsonContext.cs b/src/Ryujinx.Common/Utilities/CommonJsonContext.cs index 93f065122..6c59ccae4 100644 --- a/src/Ryujinx.Common/Utilities/CommonJsonContext.cs +++ b/src/Ryujinx.Common/Utilities/CommonJsonContext.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Text.Json.Serialization; namespace Ryujinx.Common.Utilities diff --git a/src/Ryujinx.Common/Utilities/FileSystemUtils.cs b/src/Ryujinx.Common/Utilities/FileSystemUtils.cs new file mode 100644 index 000000000..e76c2b60b --- /dev/null +++ b/src/Ryujinx.Common/Utilities/FileSystemUtils.cs @@ -0,0 +1,48 @@ +using System.IO; + +namespace Ryujinx.Common.Utilities +{ + public static class FileSystemUtils + { + public static void CopyDirectory(string sourceDir, string destinationDir, bool recursive) + { + // Get information about the source directory + var dir = new DirectoryInfo(sourceDir); + + // Check if the source directory exists + if (!dir.Exists) + { + throw new DirectoryNotFoundException($"Source directory not found: {dir.FullName}"); + } + + // Cache directories before we start copying + DirectoryInfo[] dirs = dir.GetDirectories(); + + // Create the destination directory + Directory.CreateDirectory(destinationDir); + + // Get the files in the source directory and copy to the destination directory + foreach (FileInfo file in dir.GetFiles()) + { + string targetFilePath = Path.Combine(destinationDir, file.Name); + file.CopyTo(targetFilePath); + } + + // If recursive and copying subdirectories, recursively call this method + if (recursive) + { + foreach (DirectoryInfo subDir in dirs) + { + string newDestinationDir = Path.Combine(destinationDir, subDir.Name); + CopyDirectory(subDir.FullName, newDestinationDir, true); + } + } + } + + public static void MoveDirectory(string sourceDir, string destinationDir) + { + CopyDirectory(sourceDir, destinationDir, true); + Directory.Delete(sourceDir, true); + } + } +} diff --git a/src/Ryujinx.Common/Utilities/HexUtils.cs b/src/Ryujinx.Common/Utilities/HexUtils.cs index 4690eaa1f..cf975e44a 100644 --- a/src/Ryujinx.Common/Utilities/HexUtils.cs +++ b/src/Ryujinx.Common/Utilities/HexUtils.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text; namespace Ryujinx.Common diff --git a/src/Ryujinx.Common/Utilities/JsonHelper.cs b/src/Ryujinx.Common/Utilities/JsonHelper.cs index d4ecf5e9b..95daec27a 100644 --- a/src/Ryujinx.Common/Utilities/JsonHelper.cs +++ b/src/Ryujinx.Common/Utilities/JsonHelper.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; using System.Text; using System.Text.Json; using System.Text.Json.Serialization.Metadata; diff --git a/src/Ryujinx.Common/Utilities/MessagePackObjectFormatter.cs b/src/Ryujinx.Common/Utilities/MessagePackObjectFormatter.cs index a7c596bae..426cd46b7 100644 --- a/src/Ryujinx.Common/Utilities/MessagePackObjectFormatter.cs +++ b/src/Ryujinx.Common/Utilities/MessagePackObjectFormatter.cs @@ -1,4 +1,4 @@ -using MsgPack; +using MsgPack; using System; using System.Text; diff --git a/src/Ryujinx.Common/Utilities/NetworkHelpers.cs b/src/Ryujinx.Common/Utilities/NetworkHelpers.cs index 3b64a28f5..71e02184e 100644 --- a/src/Ryujinx.Common/Utilities/NetworkHelpers.cs +++ b/src/Ryujinx.Common/Utilities/NetworkHelpers.cs @@ -1,4 +1,4 @@ -using System.Buffers.Binary; +using System.Buffers.Binary; using System.Net; using System.Net.NetworkInformation; diff --git a/src/Ryujinx.Common/Utilities/SpanHelpers.cs b/src/Ryujinx.Common/Utilities/SpanHelpers.cs index 4765eab3a..8c8e00a45 100644 --- a/src/Ryujinx.Common/Utilities/SpanHelpers.cs +++ b/src/Ryujinx.Common/Utilities/SpanHelpers.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Common/Utilities/StreamUtils.cs b/src/Ryujinx.Common/Utilities/StreamUtils.cs index 4d090fe98..7a20c98e9 100644 --- a/src/Ryujinx.Common/Utilities/StreamUtils.cs +++ b/src/Ryujinx.Common/Utilities/StreamUtils.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.IO; using System.Threading; using System.Threading.Tasks; diff --git a/src/Ryujinx.Common/Utilities/TypedStringEnumConverter.cs b/src/Ryujinx.Common/Utilities/TypedStringEnumConverter.cs index 9c575d69f..9d3944c15 100644 --- a/src/Ryujinx.Common/Utilities/TypedStringEnumConverter.cs +++ b/src/Ryujinx.Common/Utilities/TypedStringEnumConverter.cs @@ -1,4 +1,4 @@ -#nullable enable +#nullable enable using Ryujinx.Common.Logging; using System; using System.Text.Json; diff --git a/src/Ryujinx.Common/XXHash128.cs b/src/Ryujinx.Common/XXHash128.cs index 62e23fc23..686867c9d 100644 --- a/src/Ryujinx.Common/XXHash128.cs +++ b/src/Ryujinx.Common/XXHash128.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Buffers.Binary; using System.Diagnostics; using System.Numerics; diff --git a/src/Ryujinx.Cpu/AppleHv/HvCodePatcher.cs b/src/Ryujinx.Cpu/AppleHv/HvCodePatcher.cs deleted file mode 100644 index 876597b78..000000000 --- a/src/Ryujinx.Cpu/AppleHv/HvCodePatcher.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; - -namespace Ryujinx.Cpu.AppleHv -{ - static class HvCodePatcher - { - private const uint XMask = 0x3f808000u; - private const uint XValue = 0x8000000u; - - private const uint ZrIndex = 31u; - - public static void RewriteUnorderedExclusiveInstructions(Span code) - { - Span codeUint = MemoryMarshal.Cast(code); - Span> codeVector = MemoryMarshal.Cast>(code); - - Vector128 mask = Vector128.Create(XMask); - Vector128 value = Vector128.Create(XValue); - - for (int index = 0; index < codeVector.Length; index++) - { - Vector128 v = codeVector[index]; - - if (Vector128.EqualsAny(Vector128.BitwiseAnd(v, mask), value)) - { - int baseIndex = index * 4; - - for (int instIndex = baseIndex; instIndex < baseIndex + 4; instIndex++) - { - ref uint inst = ref codeUint[instIndex]; - - if ((inst & XMask) != XValue) - { - continue; - } - - bool isPair = (inst & (1u << 21)) != 0; - bool isLoad = (inst & (1u << 22)) != 0; - - uint rt2 = (inst >> 10) & 0x1fu; - uint rs = (inst >> 16) & 0x1fu; - - if (isLoad && rs != ZrIndex) - { - continue; - } - - if (!isPair && rt2 != ZrIndex) - { - continue; - } - - // Set the ordered flag. - inst |= 1u << 15; - } - } - } - } - } -} diff --git a/src/Ryujinx.Cpu/AppleHv/HvCpuContext.cs b/src/Ryujinx.Cpu/AppleHv/HvCpuContext.cs index 2c4ff2b64..99e4c0479 100644 --- a/src/Ryujinx.Cpu/AppleHv/HvCpuContext.cs +++ b/src/Ryujinx.Cpu/AppleHv/HvCpuContext.cs @@ -40,5 +40,9 @@ namespace Ryujinx.Cpu.AppleHv public void PrepareCodeRange(ulong address, ulong size) { } + + public void Dispose() + { + } } } diff --git a/src/Ryujinx.Cpu/AppleHv/HvMemoryManager.cs b/src/Ryujinx.Cpu/AppleHv/HvMemoryManager.cs index 947c37100..2f9743ab4 100644 --- a/src/Ryujinx.Cpu/AppleHv/HvMemoryManager.cs +++ b/src/Ryujinx.Cpu/AppleHv/HvMemoryManager.cs @@ -724,18 +724,6 @@ namespace Ryujinx.Cpu.AppleHv /// public void Reprotect(ulong va, ulong size, MemoryPermission protection) { - if (protection.HasFlag(MemoryPermission.Execute)) - { - // Some applications use unordered exclusive memory access instructions - // where it is not valid to do so, leading to memory re-ordering that - // makes the code behave incorrectly on some CPUs. - // To work around this, we force all such accesses to be ordered. - - using WritableRegion writableRegion = GetWritableRegion(va, (int)size); - - HvCodePatcher.RewriteUnorderedExclusiveInstructions(writableRegion.Memory.Span); - } - // TODO } diff --git a/src/Ryujinx.Cpu/DummyDiskCacheLoadState.cs b/src/Ryujinx.Cpu/DummyDiskCacheLoadState.cs new file mode 100644 index 000000000..d050bddeb --- /dev/null +++ b/src/Ryujinx.Cpu/DummyDiskCacheLoadState.cs @@ -0,0 +1,17 @@ +using System; + +namespace Ryujinx.Cpu +{ + public class DummyDiskCacheLoadState : IDiskCacheLoadState + { +#pragma warning disable CS0067 // The event is never used + /// + public event Action StateChanged; +#pragma warning restore CS0067 + + /// + public void Cancel() + { + } + } +} diff --git a/src/Ryujinx.Cpu/ICpuContext.cs b/src/Ryujinx.Cpu/ICpuContext.cs index 80916d1ca..edcebdfc4 100644 --- a/src/Ryujinx.Cpu/ICpuContext.cs +++ b/src/Ryujinx.Cpu/ICpuContext.cs @@ -1,9 +1,11 @@ +using System; + namespace Ryujinx.Cpu { /// /// CPU context interface. /// - public interface ICpuContext + public interface ICpuContext : IDisposable { /// /// Creates a new execution context that will store thread CPU register state when executing guest code. diff --git a/src/Ryujinx.Cpu/IVirtualMemoryManagerTracked.cs b/src/Ryujinx.Cpu/IVirtualMemoryManagerTracked.cs index 5fa88d623..199bff240 100644 --- a/src/Ryujinx.Cpu/IVirtualMemoryManagerTracked.cs +++ b/src/Ryujinx.Cpu/IVirtualMemoryManagerTracked.cs @@ -1,4 +1,4 @@ -using Ryujinx.Memory; +using Ryujinx.Memory; using Ryujinx.Memory.Tracking; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.Cpu/Jit/JitCpuContext.cs b/src/Ryujinx.Cpu/Jit/JitCpuContext.cs index 02465a0b3..dce0490a4 100644 --- a/src/Ryujinx.Cpu/Jit/JitCpuContext.cs +++ b/src/Ryujinx.Cpu/Jit/JitCpuContext.cs @@ -1,5 +1,7 @@ -using ARMeilleure.Memory; +using ARMeilleure.Memory; using ARMeilleure.Translation; +using Ryujinx.Cpu.Signal; +using Ryujinx.Memory; namespace Ryujinx.Cpu.Jit { @@ -11,7 +13,13 @@ namespace Ryujinx.Cpu.Jit public JitCpuContext(ITickSource tickSource, IMemoryManager memory, bool for64Bit) { _tickSource = tickSource; - _translator = new Translator(new JitMemoryAllocator(), memory, for64Bit); + _translator = new Translator(new JitMemoryAllocator(forJit: true), memory, for64Bit); + + if (memory.Type.IsHostMapped()) + { + NativeSignalHandler.InitializeSignalHandler(MemoryBlock.GetPageSize()); + } + memory.UnmapEvent += UnmapHandler; } @@ -49,5 +57,9 @@ namespace Ryujinx.Cpu.Jit { _translator.PrepareCodeRange(address, size); } + + public void Dispose() + { + } } } diff --git a/src/Ryujinx.Cpu/Jit/JitMemoryAllocator.cs b/src/Ryujinx.Cpu/Jit/JitMemoryAllocator.cs index 4aa78d06c..06c11b7b9 100644 --- a/src/Ryujinx.Cpu/Jit/JitMemoryAllocator.cs +++ b/src/Ryujinx.Cpu/Jit/JitMemoryAllocator.cs @@ -1,13 +1,18 @@ -using ARMeilleure.Memory; +using ARMeilleure.Memory; using Ryujinx.Memory; namespace Ryujinx.Cpu.Jit { public class JitMemoryAllocator : IJitMemoryAllocator { - public IJitMemoryBlock Allocate(ulong size) => new JitMemoryBlock(size, MemoryAllocationFlags.None); - public IJitMemoryBlock Reserve(ulong size) => new JitMemoryBlock(size, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.Jit); + private readonly MemoryAllocationFlags _jitFlag; - public ulong GetPageSize() => MemoryBlock.GetPageSize(); + public JitMemoryAllocator(bool forJit = false) + { + _jitFlag = forJit ? MemoryAllocationFlags.Jit : MemoryAllocationFlags.None; + } + + public IJitMemoryBlock Allocate(ulong size) => new JitMemoryBlock(size, MemoryAllocationFlags.None); + public IJitMemoryBlock Reserve(ulong size) => new JitMemoryBlock(size, MemoryAllocationFlags.Reserve | _jitFlag); } } diff --git a/src/Ryujinx.Cpu/Jit/JitMemoryBlock.cs b/src/Ryujinx.Cpu/Jit/JitMemoryBlock.cs index ed160680a..bd07d349c 100644 --- a/src/Ryujinx.Cpu/Jit/JitMemoryBlock.cs +++ b/src/Ryujinx.Cpu/Jit/JitMemoryBlock.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Memory; +using ARMeilleure.Memory; using Ryujinx.Memory; using System; @@ -16,6 +16,7 @@ namespace Ryujinx.Cpu.Jit } public void Commit(ulong offset, ulong size) => _impl.Commit(offset, size); + public void MapAsRw(ulong offset, ulong size) => _impl.Reprotect(offset, size, MemoryPermission.ReadAndWrite); public void MapAsRx(ulong offset, ulong size) => _impl.Reprotect(offset, size, MemoryPermission.ReadAndExecute); public void MapAsRwx(ulong offset, ulong size) => _impl.Reprotect(offset, size, MemoryPermission.ReadWriteExecute); diff --git a/src/Ryujinx.Cpu/Jit/MemoryManager.cs b/src/Ryujinx.Cpu/Jit/MemoryManager.cs index 912e3f7e3..b9a547025 100644 --- a/src/Ryujinx.Cpu/Jit/MemoryManager.cs +++ b/src/Ryujinx.Cpu/Jit/MemoryManager.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Memory; +using ARMeilleure.Memory; using Ryujinx.Memory; using Ryujinx.Memory.Range; using Ryujinx.Memory.Tracking; diff --git a/src/Ryujinx.Cpu/Jit/MemoryManagerHostMapped.cs b/src/Ryujinx.Cpu/Jit/MemoryManagerHostMapped.cs index 6d32787ac..2b315e841 100644 --- a/src/Ryujinx.Cpu/Jit/MemoryManagerHostMapped.cs +++ b/src/Ryujinx.Cpu/Jit/MemoryManagerHostMapped.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Memory; +using ARMeilleure.Memory; using Ryujinx.Memory; using Ryujinx.Memory.Range; using Ryujinx.Memory.Tracking; diff --git a/src/Ryujinx.Cpu/LightningJit/AarchCompiler.cs b/src/Ryujinx.Cpu/LightningJit/AarchCompiler.cs new file mode 100644 index 000000000..ee4fc439f --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/AarchCompiler.cs @@ -0,0 +1,32 @@ +using ARMeilleure.Common; +using ARMeilleure.Memory; +using Ryujinx.Cpu.LightningJit.Arm32; +using Ryujinx.Cpu.LightningJit.Arm64; +using Ryujinx.Cpu.LightningJit.State; +using System; +using System.Runtime.InteropServices; + +namespace Ryujinx.Cpu.LightningJit +{ + class AarchCompiler + { + public static CompiledFunction Compile( + CpuPreset cpuPreset, + IMemoryManager memoryManager, + ulong address, + AddressTable funcTable, + IntPtr dispatchStubPtr, + ExecutionMode executionMode, + Architecture targetArch) + { + if (executionMode == ExecutionMode.Aarch64) + { + return A64Compiler.Compile(cpuPreset, memoryManager, address, funcTable, dispatchStubPtr, targetArch); + } + else + { + return A32Compiler.Compile(cpuPreset, memoryManager, address, funcTable, dispatchStubPtr, executionMode == ExecutionMode.Aarch32Thumb, targetArch); + } + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/AddressForm.cs b/src/Ryujinx.Cpu/LightningJit/AddressForm.cs new file mode 100644 index 000000000..a9ad7e8a3 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/AddressForm.cs @@ -0,0 +1,18 @@ + +namespace Ryujinx.Cpu.LightningJit +{ + enum AddressForm : byte + { + None, + OffsetReg, + PostIndexed, + PreIndexed, + SignedScaled, + UnsignedScaled, + BaseRegister, + BasePlusOffset, + Literal, + StructNoOffset, + StructPostIndexedReg, + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/A32Compiler.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/A32Compiler.cs new file mode 100644 index 000000000..7f6024d47 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/A32Compiler.cs @@ -0,0 +1,30 @@ +using ARMeilleure.Common; +using ARMeilleure.Memory; +using Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64; +using System; +using System.Runtime.InteropServices; + +namespace Ryujinx.Cpu.LightningJit.Arm32 +{ + static class A32Compiler + { + public static CompiledFunction Compile( + CpuPreset cpuPreset, + IMemoryManager memoryManager, + ulong address, + AddressTable funcTable, + IntPtr dispatchStubPtr, + bool isThumb, + Architecture targetArch) + { + if (targetArch == Architecture.Arm64) + { + return Compiler.Compile(cpuPreset, memoryManager, address, funcTable, dispatchStubPtr, isThumb); + } + else + { + throw new PlatformNotSupportedException(); + } + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Block.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Block.cs new file mode 100644 index 000000000..4729f6940 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Block.cs @@ -0,0 +1,101 @@ +using System.Collections.Generic; +using System.Diagnostics; + +namespace Ryujinx.Cpu.LightningJit.Arm32 +{ + class Block + { + public readonly ulong Address; + public readonly ulong EndAddress; + public readonly List Instructions; + public readonly bool EndsWithBranch; + public readonly bool HasHostCall; + public readonly bool IsTruncated; + public readonly bool IsLoopEnd; + public readonly bool IsThumb; + + public Block( + ulong address, + ulong endAddress, + List instructions, + bool endsWithBranch, + bool hasHostCall, + bool isTruncated, + bool isLoopEnd, + bool isThumb) + { + Debug.Assert(isThumb || (int)((endAddress - address) / 4) == instructions.Count); + + Address = address; + EndAddress = endAddress; + Instructions = instructions; + EndsWithBranch = endsWithBranch; + HasHostCall = hasHostCall; + IsTruncated = isTruncated; + IsLoopEnd = isLoopEnd; + IsThumb = isThumb; + } + + public (Block, Block) SplitAtAddress(ulong address) + { + int splitIndex = FindSplitIndex(address); + + if (splitIndex < 0) + { + return (null, null); + } + + int splitCount = Instructions.Count - splitIndex; + + // Technically those are valid, but we don't want to create empty blocks. + Debug.Assert(splitIndex != 0); + Debug.Assert(splitCount != 0); + + Block leftBlock = new( + Address, + address, + Instructions.GetRange(0, splitIndex), + false, + HasHostCall, + false, + false, + IsThumb); + + Block rightBlock = new( + address, + EndAddress, + Instructions.GetRange(splitIndex, splitCount), + EndsWithBranch, + HasHostCall, + IsTruncated, + IsLoopEnd, + IsThumb); + + return (leftBlock, rightBlock); + } + + private int FindSplitIndex(ulong address) + { + if (IsThumb) + { + ulong pc = Address; + + for (int index = 0; index < Instructions.Count; index++) + { + if (pc == address) + { + return index; + } + + pc += Instructions[index].Flags.HasFlag(InstFlags.Thumb16) ? 2UL : 4UL; + } + + return -1; + } + else + { + return (int)((address - Address) / 4); + } + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/BranchType.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/BranchType.cs new file mode 100644 index 000000000..6d9fdf2c4 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/BranchType.cs @@ -0,0 +1,15 @@ +namespace Ryujinx.Cpu.LightningJit.Arm32 +{ + enum BranchType + { + Branch, + Call, + IndirectBranch, + TableBranchByte, + TableBranchHalfword, + IndirectCall, + SyncPoint, + SoftwareInterrupt, + ReadCntpct, + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/CodeGenContext.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/CodeGenContext.cs new file mode 100644 index 000000000..f55e2bb99 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/CodeGenContext.cs @@ -0,0 +1,198 @@ +using ARMeilleure.Memory; +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; +using System; +using System.Collections.Generic; + +namespace Ryujinx.Cpu.LightningJit.Arm32 +{ + class CodeGenContext + { + public CodeWriter CodeWriter { get; } + public Assembler Arm64Assembler { get; } + public RegisterAllocator RegisterAllocator { get; } + + public MemoryManagerType MemoryManagerType { get; } + + private uint _instructionAddress; + + public bool IsThumb { get; } + public uint Pc { get; private set; } + public bool InITBlock { get; private set; } + + private InstInfo _nextInstruction; + private bool _skipNextInstruction; + + private readonly ArmCondition[] _itConditions; + private int _itCount; + + private readonly List _pendingBranches; + + private bool _nzcvModified; + + public CodeGenContext(CodeWriter codeWriter, Assembler arm64Assembler, RegisterAllocator registerAllocator, MemoryManagerType mmType, bool isThumb) + { + CodeWriter = codeWriter; + Arm64Assembler = arm64Assembler; + RegisterAllocator = registerAllocator; + MemoryManagerType = mmType; + _itConditions = new ArmCondition[4]; + _pendingBranches = new(); + IsThumb = isThumb; + } + + public void SetPc(uint address) + { + // Due to historical reasons, the PC value is always 2 instructions ahead on 32-bit Arm CPUs. + Pc = address + (IsThumb ? 4u : 8u); + _instructionAddress = address; + } + + public void SetNextInstruction(InstInfo info) + { + _nextInstruction = info; + } + + public InstInfo PeekNextInstruction() + { + return _nextInstruction; + } + + public void SetSkipNextInstruction() + { + _skipNextInstruction = true; + } + + public bool ConsumeSkipNextInstruction() + { + bool skip = _skipNextInstruction; + _skipNextInstruction = false; + + return skip; + } + + public void AddPendingBranch(InstName name, int offset) + { + _pendingBranches.Add(new(BranchType.Branch, Pc + (uint)offset, 0u, name, CodeWriter.InstructionPointer)); + } + + public void AddPendingCall(uint targetAddress, uint nextAddress) + { + _pendingBranches.Add(new(BranchType.Call, targetAddress, nextAddress, InstName.BlI, CodeWriter.InstructionPointer)); + + RegisterAllocator.EnsureTempGprRegisters(1); + RegisterAllocator.MarkGprAsUsed(RegisterUtils.LrRegister); + } + + public void AddPendingIndirectBranch(InstName name, uint targetRegister) + { + _pendingBranches.Add(new(BranchType.IndirectBranch, targetRegister, 0u, name, CodeWriter.InstructionPointer)); + + RegisterAllocator.MarkGprAsUsed((int)targetRegister); + } + + public void AddPendingTableBranch(uint rn, uint rm, bool halfword) + { + _pendingBranches.Add(new(halfword ? BranchType.TableBranchHalfword : BranchType.TableBranchByte, rn, rm, InstName.Tbb, CodeWriter.InstructionPointer)); + + RegisterAllocator.EnsureTempGprRegisters(2); + RegisterAllocator.MarkGprAsUsed((int)rn); + RegisterAllocator.MarkGprAsUsed((int)rm); + } + + public void AddPendingIndirectCall(uint targetRegister, uint nextAddress) + { + _pendingBranches.Add(new(BranchType.IndirectCall, targetRegister, nextAddress, InstName.BlxR, CodeWriter.InstructionPointer)); + + RegisterAllocator.EnsureTempGprRegisters(targetRegister == RegisterUtils.LrRegister ? 1 : 0); + RegisterAllocator.MarkGprAsUsed((int)targetRegister); + RegisterAllocator.MarkGprAsUsed(RegisterUtils.LrRegister); + } + + public void AddPendingSyncPoint() + { + _pendingBranches.Add(new(BranchType.SyncPoint, 0, 0, default, CodeWriter.InstructionPointer)); + + RegisterAllocator.EnsureTempGprRegisters(1); + } + + public void AddPendingBkpt(uint imm) + { + _pendingBranches.Add(new(BranchType.SoftwareInterrupt, imm, _instructionAddress, InstName.Bkpt, CodeWriter.InstructionPointer)); + + RegisterAllocator.EnsureTempGprRegisters(1); + } + + public void AddPendingSvc(uint imm) + { + _pendingBranches.Add(new(BranchType.SoftwareInterrupt, imm, _instructionAddress, InstName.Svc, CodeWriter.InstructionPointer)); + + RegisterAllocator.EnsureTempGprRegisters(1); + } + + public void AddPendingUdf(uint imm) + { + _pendingBranches.Add(new(BranchType.SoftwareInterrupt, imm, _instructionAddress, InstName.Udf, CodeWriter.InstructionPointer)); + + RegisterAllocator.EnsureTempGprRegisters(1); + } + + public void AddPendingReadCntpct(uint rt, uint rt2) + { + _pendingBranches.Add(new(BranchType.ReadCntpct, rt, rt2, InstName.Mrrc, CodeWriter.InstructionPointer)); + + RegisterAllocator.EnsureTempGprRegisters(1); + } + + public IEnumerable GetPendingBranches() + { + return _pendingBranches; + } + + public void SetItBlockStart(ReadOnlySpan conditions) + { + _itCount = conditions.Length; + + for (int index = 0; index < conditions.Length; index++) + { + _itConditions[index] = conditions[index]; + } + + InITBlock = true; + } + + public bool ConsumeItCondition(out ArmCondition condition) + { + if (_itCount != 0) + { + condition = _itConditions[--_itCount]; + + return true; + } + + condition = ArmCondition.Al; + + return false; + } + + public void UpdateItState() + { + if (_itCount == 0) + { + InITBlock = false; + } + } + + public void SetNzcvModified() + { + _nzcvModified = true; + } + + public bool ConsumeNzcvModified() + { + bool modified = _nzcvModified; + _nzcvModified = false; + + return modified; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Decoder.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Decoder.cs new file mode 100644 index 000000000..e0a18e666 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Decoder.cs @@ -0,0 +1,546 @@ +using ARMeilleure.Memory; +using Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64; +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; +using System.Collections.Generic; +using System.Diagnostics; + +namespace Ryujinx.Cpu.LightningJit.Arm32 +{ + static class Decoder where T : IInstEmit + { + public static MultiBlock DecodeMulti(CpuPreset cpuPreset, IMemoryManager memoryManager, ulong address, bool isThumb) + { + List blocks = new(); + List branchTargets = new(); + + while (true) + { + Block block = Decode(cpuPreset, memoryManager, address, isThumb); + + if (!block.IsTruncated && TryGetBranchTarget(block, out ulong targetAddress)) + { + branchTargets.Add(targetAddress); + } + + blocks.Add(block); + + if (block.IsTruncated || !HasNextBlock(block, block.EndAddress - 4UL, branchTargets)) + { + break; + } + + address = block.EndAddress; + } + + branchTargets.Sort(); + SplitBlocks(blocks, branchTargets); + + return new(blocks); + } + + private static bool TryGetBranchTarget(Block block, out ulong targetAddress) + { + // PC is 2 instructions ahead, since the end address is already one instruction after the last one, we just need to add + // another instruction. + + ulong pc = block.EndAddress + (block.IsThumb ? 2UL : 4UL); + + return TryGetBranchTarget(block.Instructions[^1].Name, block.Instructions[^1].Flags, pc, block.Instructions[^1].Encoding, block.IsThumb, out targetAddress); + } + + private static bool TryGetBranchTarget(InstName name, InstFlags flags, ulong pc, uint encoding, bool isThumb, out ulong targetAddress) + { + int originalOffset; + + switch (name) + { + case InstName.B: + if (isThumb) + { + if (flags.HasFlag(InstFlags.Thumb16)) + { + if ((encoding & (1u << 29)) != 0) + { + InstImm11b16w11 inst = new(encoding); + + originalOffset = ImmUtils.ExtractT16SImm11Times2(inst.Imm11); + } + else + { + InstCondb24w4Imm8b16w8 inst = new(encoding); + + originalOffset = ImmUtils.ExtractT16SImm8Times2(inst.Imm8); + } + } + else + { + if ((encoding & (1u << 12)) != 0) + { + InstSb26w1Imm10b16w10J1b13w1J2b11w1Imm11b0w11 inst = new(encoding); + + originalOffset = ImmUtils.CombineSImm24Times2(inst.Imm11, inst.Imm10, inst.J1, inst.J2, inst.S); + } + else + { + InstSb26w1Condb22w4Imm6b16w6J1b13w1J2b11w1Imm11b0w11 inst = new(encoding); + + originalOffset = ImmUtils.CombineSImm20Times2(inst.Imm11, inst.Imm6, inst.J1, inst.J2, inst.S); + } + } + } + else + { + originalOffset = ImmUtils.ExtractSImm24Times4(encoding); + } + + targetAddress = pc + (ulong)originalOffset; + Debug.Assert((targetAddress & 1) == 0); + + return true; + + case InstName.Cbnz: + originalOffset = ImmUtils.ExtractT16UImm5Times2(encoding); + targetAddress = pc + (ulong)originalOffset; + Debug.Assert((targetAddress & 1) == 0); + + return true; + } + + targetAddress = 0; + + return false; + } + + private static void SplitBlocks(List blocks, List branchTargets) + { + int btIndex = 0; + + while (btIndex < branchTargets.Count) + { + for (int blockIndex = 0; blockIndex < blocks.Count && btIndex < branchTargets.Count; blockIndex++) + { + Block block = blocks[blockIndex]; + ulong currentBranchTarget = branchTargets[btIndex]; + + while (currentBranchTarget >= block.Address && currentBranchTarget < block.EndAddress) + { + if (block.Address != currentBranchTarget) + { + (Block leftBlock, Block rightBlock) = block.SplitAtAddress(currentBranchTarget); + + if (leftBlock != null && rightBlock != null) + { + blocks.Insert(blockIndex, leftBlock); + blocks[blockIndex + 1] = rightBlock; + + block = leftBlock; + } + else + { + // Split can only fail in thumb mode, where the instruction size is not fixed. + + Debug.Assert(block.IsThumb); + } + } + + btIndex++; + + while (btIndex < branchTargets.Count && branchTargets[btIndex] == currentBranchTarget) + { + btIndex++; + } + + if (btIndex >= branchTargets.Count) + { + break; + } + + currentBranchTarget = branchTargets[btIndex]; + } + } + + Debug.Assert(btIndex < int.MaxValue); + btIndex++; + } + } + + private static bool HasNextBlock(in Block block, ulong pc, List branchTargets) + { + InstFlags lastInstFlags = block.Instructions[^1].Flags; + + // Thumb has separate encodings for conditional and unconditional branch instructions. + if (lastInstFlags.HasFlag(InstFlags.Cond) && (block.IsThumb || (ArmCondition)(block.Instructions[^1].Encoding >> 28) < ArmCondition.Al)) + { + return true; + } + + switch (block.Instructions[^1].Name) + { + case InstName.B: + return branchTargets.Contains(pc + 4UL) || + (TryGetBranchTarget(block, out ulong targetAddress) && targetAddress >= pc && targetAddress < pc + 0x1000); + + case InstName.Bx: + case InstName.Bxj: + return branchTargets.Contains(pc + 4UL); + + case InstName.Cbnz: + case InstName.BlI: + case InstName.BlxR: + return true; + } + + if (WritesToPC(block.Instructions[^1].Encoding, block.Instructions[^1].Name, lastInstFlags, block.IsThumb)) + { + return branchTargets.Contains(pc + 4UL); + } + + return !block.EndsWithBranch; + } + + private static Block Decode(CpuPreset cpuPreset, IMemoryManager memoryManager, ulong address, bool isThumb) + { + ulong startAddress = address; + + List insts = new(); + + uint encoding; + InstMeta meta; + InstFlags extraFlags = InstFlags.None; + bool hasHostCall = false; + bool isTruncated = false; + + do + { + if (!memoryManager.IsMapped(address)) + { + encoding = 0; + meta = default; + isTruncated = true; + break; + } + + if (isThumb) + { + encoding = (uint)memoryManager.Read(address) << 16; + address += 2UL; + + extraFlags = InstFlags.Thumb16; + + if (!InstTableT16.TryGetMeta(encoding, cpuPreset.Version, cpuPreset.Features, out meta)) + { + encoding |= memoryManager.Read(address); + + if (InstTableT32.TryGetMeta(encoding, cpuPreset.Version, cpuPreset.Features, out meta)) + { + address += 2UL; + extraFlags = InstFlags.None; + } + } + } + else + { + encoding = memoryManager.Read(address); + address += 4UL; + + meta = InstTableA32.GetMeta(encoding, cpuPreset.Version, cpuPreset.Features); + } + + if (meta.Name.IsSystemOrCall() && !hasHostCall) + { + hasHostCall = meta.Name.IsCall() || InstEmitSystem.NeedsCall(meta.Name); + } + + insts.Add(new(encoding, meta.Name, meta.EmitFunc, meta.Flags | extraFlags)); + } + while (!IsControlFlow(encoding, meta.Name, meta.Flags | extraFlags, isThumb)); + + bool isLoopEnd = false; + + if (!isTruncated && IsBackwardsBranch(meta.Name, encoding)) + { + hasHostCall = true; + isLoopEnd = true; + } + + return new( + startAddress, + address, + insts, + !isTruncated, + hasHostCall, + isTruncated, + isLoopEnd, + isThumb); + } + + private static bool IsControlFlow(uint encoding, InstName name, InstFlags flags, bool isThumb) + { + switch (name) + { + case InstName.B: + case InstName.BlI: + case InstName.BlxR: + case InstName.Bx: + case InstName.Bxj: + case InstName.Cbnz: + case InstName.Tbb: + return true; + } + + return WritesToPC(encoding, name, flags, isThumb); + } + + public static bool WritesToPC(uint encoding, InstName name, InstFlags flags, bool isThumb) + { + return (GetRegisterWriteMask(encoding, name, flags, isThumb) & (1u << RegisterUtils.PcRegister)) != 0; + } + + private static uint GetRegisterWriteMask(uint encoding, InstName name, InstFlags flags, bool isThumb) + { + uint mask = 0; + + if (isThumb) + { + if (flags.HasFlag(InstFlags.Thumb16)) + { + if (flags.HasFlag(InstFlags.Rdn)) + { + mask |= 1u << RegisterUtils.ExtractRdn(flags, encoding); + } + + if (flags.HasFlag(InstFlags.Rd)) + { + mask |= 1u << RegisterUtils.ExtractRdT16(flags, encoding); + } + + Debug.Assert(!flags.HasFlag(InstFlags.RdHi)); + + if (IsRegisterWrite(flags, InstFlags.Rt)) + { + mask |= 1u << RegisterUtils.ExtractRtT16(flags, encoding); + } + + Debug.Assert(!flags.HasFlag(InstFlags.Rt2)); + + if (IsRegisterWrite(flags, InstFlags.Rlist)) + { + mask |= (byte)(encoding >> 16); + + if (name == InstName.Push) + { + mask |= (encoding >> 10) & 0x4000; // LR + } + else if (name == InstName.Pop) + { + mask |= (encoding >> 9) & 0x8000; // PC + } + } + + Debug.Assert(!flags.HasFlag(InstFlags.WBack)); + } + else + { + if (flags.HasFlag(InstFlags.Rd)) + { + mask |= 1u << RegisterUtils.ExtractRdT32(flags, encoding); + } + + if (flags.HasFlag(InstFlags.RdLo)) + { + mask |= 1u << RegisterUtils.ExtractRdLoT32(encoding); + } + + if (flags.HasFlag(InstFlags.RdHi)) + { + mask |= 1u << RegisterUtils.ExtractRdHiT32(encoding); + } + + if (IsRegisterWrite(flags, InstFlags.Rt) && IsRtWrite(name, encoding) && !IsR15RtEncodingSpecial(name, encoding)) + { + mask |= 1u << RegisterUtils.ExtractRtT32(encoding); + } + + if (IsRegisterWrite(flags, InstFlags.Rt2) && IsRtWrite(name, encoding)) + { + mask |= 1u << RegisterUtils.ExtractRt2T32(encoding); + } + + if (IsRegisterWrite(flags, InstFlags.Rlist)) + { + mask |= (ushort)encoding; + } + + if (flags.HasFlag(InstFlags.WBack) && HasWriteBackT32(name, encoding)) + { + mask |= 1u << RegisterUtils.ExtractRn(encoding); // This is at the same bit position as A32. + } + } + } + else + { + if (flags.HasFlag(InstFlags.Rd)) + { + mask |= 1u << RegisterUtils.ExtractRd(flags, encoding); + } + + if (flags.HasFlag(InstFlags.RdHi)) + { + mask |= 1u << RegisterUtils.ExtractRdHi(encoding); + } + + if (IsRegisterWrite(flags, InstFlags.Rt) && IsRtWrite(name, encoding) && !IsR15RtEncodingSpecial(name, encoding)) + { + mask |= 1u << RegisterUtils.ExtractRt(encoding); + } + + if (IsRegisterWrite(flags, InstFlags.Rt2) && IsRtWrite(name, encoding)) + { + mask |= 1u << RegisterUtils.ExtractRt2(encoding); + } + + if (IsRegisterWrite(flags, InstFlags.Rlist)) + { + mask |= (ushort)encoding; + } + + if (flags.HasFlag(InstFlags.WBack) && HasWriteBack(name, encoding)) + { + mask |= 1u << RegisterUtils.ExtractRn(encoding); + } + } + + return mask; + } + + private static bool IsRtWrite(InstName name, uint encoding) + { + // Some instructions can move GPR to FP/SIMD or FP/SIMD to GPR depending on the encoding. + // Detect those cases so that we can tell if we're actually doing a register write. + + switch (name) + { + case InstName.VmovD: + case InstName.VmovH: + case InstName.VmovS: + case InstName.VmovSs: + return (encoding & (1u << 20)) != 0; + } + + return true; + } + + private static bool HasWriteBack(InstName name, uint encoding) + { + if (IsLoadStoreMultiple(name)) + { + return (encoding & (1u << 21)) != 0; + } + + if (IsVLDnVSTn(name)) + { + return (encoding & 0xf) != RegisterUtils.PcRegister; + } + + bool w = (encoding & (1u << 21)) != 0; + bool p = (encoding & (1u << 24)) != 0; + + return !p || w; + } + + private static bool HasWriteBackT32(InstName name, uint encoding) + { + if (IsLoadStoreMultiple(name)) + { + return (encoding & (1u << 21)) != 0; + } + + if (IsVLDnVSTn(name)) + { + return (encoding & 0xf) != RegisterUtils.PcRegister; + } + + return (encoding & (1u << 8)) != 0; + } + + private static bool IsLoadStoreMultiple(InstName name) + { + switch (name) + { + case InstName.Ldm: + case InstName.Ldmda: + case InstName.Ldmdb: + case InstName.LdmE: + case InstName.Ldmib: + case InstName.LdmU: + case InstName.Stm: + case InstName.Stmda: + case InstName.Stmdb: + case InstName.Stmib: + case InstName.StmU: + case InstName.Fldmx: + case InstName.Fstmx: + case InstName.Vldm: + case InstName.Vstm: + return true; + } + + return false; + } + + private static bool IsVLDnVSTn(InstName name) + { + switch (name) + { + case InstName.Vld11: + case InstName.Vld1A: + case InstName.Vld1M: + case InstName.Vld21: + case InstName.Vld2A: + case InstName.Vld2M: + case InstName.Vld31: + case InstName.Vld3A: + case InstName.Vld3M: + case InstName.Vld41: + case InstName.Vld4A: + case InstName.Vld4M: + case InstName.Vst11: + case InstName.Vst1M: + case InstName.Vst21: + case InstName.Vst2M: + case InstName.Vst31: + case InstName.Vst3M: + case InstName.Vst41: + case InstName.Vst4M: + return true; + } + + return false; + } + + private static bool IsR15RtEncodingSpecial(InstName name, uint encoding) + { + if (name == InstName.Vmrs) + { + return ((encoding >> 16) & 0xf) == 1; + } + + return false; + } + + private static bool IsRegisterWrite(InstFlags flags, InstFlags testFlag) + { + return flags.HasFlag(testFlag) && !flags.HasFlag(InstFlags.ReadRd); + } + + private static bool IsBackwardsBranch(InstName name, uint encoding) + { + if (name == InstName.B) + { + return ImmUtils.ExtractSImm24Times4(encoding) < 0; + } + + return false; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/IInstEmit.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/IInstEmit.cs new file mode 100644 index 000000000..32dc5aeb8 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/IInstEmit.cs @@ -0,0 +1,1231 @@ +namespace Ryujinx.Cpu.LightningJit.Arm32 +{ + interface IInstEmit + { + static abstract void AdcIA1(CodeGenContext context, uint encoding); + static abstract void AdcIT1(CodeGenContext context, uint encoding); + static abstract void AdcRA1(CodeGenContext context, uint encoding); + static abstract void AdcRT1(CodeGenContext context, uint encoding); + static abstract void AdcRT2(CodeGenContext context, uint encoding); + static abstract void AdcRrA1(CodeGenContext context, uint encoding); + static abstract void AddIA1(CodeGenContext context, uint encoding); + static abstract void AddIT1(CodeGenContext context, uint encoding); + static abstract void AddIT2(CodeGenContext context, uint encoding); + static abstract void AddIT3(CodeGenContext context, uint encoding); + static abstract void AddIT4(CodeGenContext context, uint encoding); + static abstract void AddRA1(CodeGenContext context, uint encoding); + static abstract void AddRT1(CodeGenContext context, uint encoding); + static abstract void AddRT2(CodeGenContext context, uint encoding); + static abstract void AddRT3(CodeGenContext context, uint encoding); + static abstract void AddRrA1(CodeGenContext context, uint encoding); + static abstract void AddSpIA1(CodeGenContext context, uint encoding); + static abstract void AddSpIT1(CodeGenContext context, uint encoding); + static abstract void AddSpIT2(CodeGenContext context, uint encoding); + static abstract void AddSpIT3(CodeGenContext context, uint encoding); + static abstract void AddSpIT4(CodeGenContext context, uint encoding); + static abstract void AddSpRA1(CodeGenContext context, uint encoding); + static abstract void AddSpRT1(CodeGenContext context, uint encoding); + static abstract void AddSpRT2(CodeGenContext context, uint encoding); + static abstract void AddSpRT3(CodeGenContext context, uint encoding); + static abstract void AdrA1(CodeGenContext context, uint encoding); + static abstract void AdrA2(CodeGenContext context, uint encoding); + static abstract void AdrT1(CodeGenContext context, uint encoding); + static abstract void AdrT2(CodeGenContext context, uint encoding); + static abstract void AdrT3(CodeGenContext context, uint encoding); + static abstract void AesdA1(CodeGenContext context, uint encoding); + static abstract void AesdT1(CodeGenContext context, uint encoding); + static abstract void AeseA1(CodeGenContext context, uint encoding); + static abstract void AeseT1(CodeGenContext context, uint encoding); + static abstract void AesimcA1(CodeGenContext context, uint encoding); + static abstract void AesimcT1(CodeGenContext context, uint encoding); + static abstract void AesmcA1(CodeGenContext context, uint encoding); + static abstract void AesmcT1(CodeGenContext context, uint encoding); + static abstract void AndIA1(CodeGenContext context, uint encoding); + static abstract void AndIT1(CodeGenContext context, uint encoding); + static abstract void AndRA1(CodeGenContext context, uint encoding); + static abstract void AndRT1(CodeGenContext context, uint encoding); + static abstract void AndRT2(CodeGenContext context, uint encoding); + static abstract void AndRrA1(CodeGenContext context, uint encoding); + static abstract void BA1(CodeGenContext context, uint encoding); + static abstract void BT1(CodeGenContext context, uint encoding); + static abstract void BT2(CodeGenContext context, uint encoding); + static abstract void BT3(CodeGenContext context, uint encoding); + static abstract void BT4(CodeGenContext context, uint encoding); + static abstract void BfcA1(CodeGenContext context, uint encoding); + static abstract void BfcT1(CodeGenContext context, uint encoding); + static abstract void BfiA1(CodeGenContext context, uint encoding); + static abstract void BfiT1(CodeGenContext context, uint encoding); + static abstract void BicIA1(CodeGenContext context, uint encoding); + static abstract void BicIT1(CodeGenContext context, uint encoding); + static abstract void BicRA1(CodeGenContext context, uint encoding); + static abstract void BicRT1(CodeGenContext context, uint encoding); + static abstract void BicRT2(CodeGenContext context, uint encoding); + static abstract void BicRrA1(CodeGenContext context, uint encoding); + static abstract void BkptA1(CodeGenContext context, uint encoding); + static abstract void BkptT1(CodeGenContext context, uint encoding); + static abstract void BlxRA1(CodeGenContext context, uint encoding); + static abstract void BlxRT1(CodeGenContext context, uint encoding); + static abstract void BlIA1(CodeGenContext context, uint encoding); + static abstract void BlIA2(CodeGenContext context, uint encoding); + static abstract void BlIT1(CodeGenContext context, uint encoding); + static abstract void BlIT2(CodeGenContext context, uint encoding); + static abstract void BxA1(CodeGenContext context, uint encoding); + static abstract void BxT1(CodeGenContext context, uint encoding); + static abstract void BxjA1(CodeGenContext context, uint encoding); + static abstract void BxjT1(CodeGenContext context, uint encoding); + static abstract void CbnzT1(CodeGenContext context, uint encoding); + static abstract void ClrbhbA1(CodeGenContext context, uint encoding); + static abstract void ClrbhbT1(CodeGenContext context, uint encoding); + static abstract void ClrexA1(CodeGenContext context, uint encoding); + static abstract void ClrexT1(CodeGenContext context, uint encoding); + static abstract void ClzA1(CodeGenContext context, uint encoding); + static abstract void ClzT1(CodeGenContext context, uint encoding); + static abstract void CmnIA1(CodeGenContext context, uint encoding); + static abstract void CmnIT1(CodeGenContext context, uint encoding); + static abstract void CmnRA1(CodeGenContext context, uint encoding); + static abstract void CmnRT1(CodeGenContext context, uint encoding); + static abstract void CmnRT2(CodeGenContext context, uint encoding); + static abstract void CmnRrA1(CodeGenContext context, uint encoding); + static abstract void CmpIA1(CodeGenContext context, uint encoding); + static abstract void CmpIT1(CodeGenContext context, uint encoding); + static abstract void CmpIT2(CodeGenContext context, uint encoding); + static abstract void CmpRA1(CodeGenContext context, uint encoding); + static abstract void CmpRT1(CodeGenContext context, uint encoding); + static abstract void CmpRT2(CodeGenContext context, uint encoding); + static abstract void CmpRT3(CodeGenContext context, uint encoding); + static abstract void CmpRrA1(CodeGenContext context, uint encoding); + static abstract void CpsA1(CodeGenContext context, uint encoding); + static abstract void CpsT1(CodeGenContext context, uint encoding); + static abstract void CpsT2(CodeGenContext context, uint encoding); + static abstract void Crc32A1(CodeGenContext context, uint encoding); + static abstract void Crc32T1(CodeGenContext context, uint encoding); + static abstract void Crc32cA1(CodeGenContext context, uint encoding); + static abstract void Crc32cT1(CodeGenContext context, uint encoding); + static abstract void CsdbA1(CodeGenContext context, uint encoding); + static abstract void CsdbT1(CodeGenContext context, uint encoding); + static abstract void DbgA1(CodeGenContext context, uint encoding); + static abstract void DbgT1(CodeGenContext context, uint encoding); + static abstract void Dcps1T1(CodeGenContext context, uint encoding); + static abstract void Dcps2T1(CodeGenContext context, uint encoding); + static abstract void Dcps3T1(CodeGenContext context, uint encoding); + static abstract void DmbA1(CodeGenContext context, uint encoding); + static abstract void DmbT1(CodeGenContext context, uint encoding); + static abstract void DsbA1(CodeGenContext context, uint encoding); + static abstract void DsbT1(CodeGenContext context, uint encoding); + static abstract void EorIA1(CodeGenContext context, uint encoding); + static abstract void EorIT1(CodeGenContext context, uint encoding); + static abstract void EorRA1(CodeGenContext context, uint encoding); + static abstract void EorRT1(CodeGenContext context, uint encoding); + static abstract void EorRT2(CodeGenContext context, uint encoding); + static abstract void EorRrA1(CodeGenContext context, uint encoding); + static abstract void EretA1(CodeGenContext context, uint encoding); + static abstract void EretT1(CodeGenContext context, uint encoding); + static abstract void EsbA1(CodeGenContext context, uint encoding); + static abstract void EsbT1(CodeGenContext context, uint encoding); + static abstract void FldmxA1(CodeGenContext context, uint encoding); + static abstract void FldmxT1(CodeGenContext context, uint encoding); + static abstract void FstmxA1(CodeGenContext context, uint encoding); + static abstract void FstmxT1(CodeGenContext context, uint encoding); + static abstract void HltA1(CodeGenContext context, uint encoding); + static abstract void HltT1(CodeGenContext context, uint encoding); + static abstract void HvcA1(CodeGenContext context, uint encoding); + static abstract void HvcT1(CodeGenContext context, uint encoding); + static abstract void IsbA1(CodeGenContext context, uint encoding); + static abstract void IsbT1(CodeGenContext context, uint encoding); + static abstract void ItT1(CodeGenContext context, uint encoding); + static abstract void LdaA1(CodeGenContext context, uint encoding); + static abstract void LdaT1(CodeGenContext context, uint encoding); + static abstract void LdabA1(CodeGenContext context, uint encoding); + static abstract void LdabT1(CodeGenContext context, uint encoding); + static abstract void LdaexA1(CodeGenContext context, uint encoding); + static abstract void LdaexT1(CodeGenContext context, uint encoding); + static abstract void LdaexbA1(CodeGenContext context, uint encoding); + static abstract void LdaexbT1(CodeGenContext context, uint encoding); + static abstract void LdaexdA1(CodeGenContext context, uint encoding); + static abstract void LdaexdT1(CodeGenContext context, uint encoding); + static abstract void LdaexhA1(CodeGenContext context, uint encoding); + static abstract void LdaexhT1(CodeGenContext context, uint encoding); + static abstract void LdahA1(CodeGenContext context, uint encoding); + static abstract void LdahT1(CodeGenContext context, uint encoding); + static abstract void LdcIA1(CodeGenContext context, uint encoding); + static abstract void LdcIT1(CodeGenContext context, uint encoding); + static abstract void LdcLA1(CodeGenContext context, uint encoding); + static abstract void LdcLT1(CodeGenContext context, uint encoding); + static abstract void LdmA1(CodeGenContext context, uint encoding); + static abstract void LdmT1(CodeGenContext context, uint encoding); + static abstract void LdmT2(CodeGenContext context, uint encoding); + static abstract void LdmdaA1(CodeGenContext context, uint encoding); + static abstract void LdmdbA1(CodeGenContext context, uint encoding); + static abstract void LdmdbT1(CodeGenContext context, uint encoding); + static abstract void LdmibA1(CodeGenContext context, uint encoding); + static abstract void LdmEA1(CodeGenContext context, uint encoding); + static abstract void LdmUA1(CodeGenContext context, uint encoding); + static abstract void LdrbtA1(CodeGenContext context, uint encoding); + static abstract void LdrbtA2(CodeGenContext context, uint encoding); + static abstract void LdrbtT1(CodeGenContext context, uint encoding); + static abstract void LdrbIA1(CodeGenContext context, uint encoding); + static abstract void LdrbIT1(CodeGenContext context, uint encoding); + static abstract void LdrbIT2(CodeGenContext context, uint encoding); + static abstract void LdrbIT3(CodeGenContext context, uint encoding); + static abstract void LdrbLA1(CodeGenContext context, uint encoding); + static abstract void LdrbLT1(CodeGenContext context, uint encoding); + static abstract void LdrbRA1(CodeGenContext context, uint encoding); + static abstract void LdrbRT1(CodeGenContext context, uint encoding); + static abstract void LdrbRT2(CodeGenContext context, uint encoding); + static abstract void LdrdIA1(CodeGenContext context, uint encoding); + static abstract void LdrdIT1(CodeGenContext context, uint encoding); + static abstract void LdrdLA1(CodeGenContext context, uint encoding); + static abstract void LdrdLT1(CodeGenContext context, uint encoding); + static abstract void LdrdRA1(CodeGenContext context, uint encoding); + static abstract void LdrexA1(CodeGenContext context, uint encoding); + static abstract void LdrexT1(CodeGenContext context, uint encoding); + static abstract void LdrexbA1(CodeGenContext context, uint encoding); + static abstract void LdrexbT1(CodeGenContext context, uint encoding); + static abstract void LdrexdA1(CodeGenContext context, uint encoding); + static abstract void LdrexdT1(CodeGenContext context, uint encoding); + static abstract void LdrexhA1(CodeGenContext context, uint encoding); + static abstract void LdrexhT1(CodeGenContext context, uint encoding); + static abstract void LdrhtA1(CodeGenContext context, uint encoding); + static abstract void LdrhtA2(CodeGenContext context, uint encoding); + static abstract void LdrhtT1(CodeGenContext context, uint encoding); + static abstract void LdrhIA1(CodeGenContext context, uint encoding); + static abstract void LdrhIT1(CodeGenContext context, uint encoding); + static abstract void LdrhIT2(CodeGenContext context, uint encoding); + static abstract void LdrhIT3(CodeGenContext context, uint encoding); + static abstract void LdrhLA1(CodeGenContext context, uint encoding); + static abstract void LdrhLT1(CodeGenContext context, uint encoding); + static abstract void LdrhRA1(CodeGenContext context, uint encoding); + static abstract void LdrhRT1(CodeGenContext context, uint encoding); + static abstract void LdrhRT2(CodeGenContext context, uint encoding); + static abstract void LdrsbtA1(CodeGenContext context, uint encoding); + static abstract void LdrsbtA2(CodeGenContext context, uint encoding); + static abstract void LdrsbtT1(CodeGenContext context, uint encoding); + static abstract void LdrsbIA1(CodeGenContext context, uint encoding); + static abstract void LdrsbIT1(CodeGenContext context, uint encoding); + static abstract void LdrsbIT2(CodeGenContext context, uint encoding); + static abstract void LdrsbLA1(CodeGenContext context, uint encoding); + static abstract void LdrsbLT1(CodeGenContext context, uint encoding); + static abstract void LdrsbRA1(CodeGenContext context, uint encoding); + static abstract void LdrsbRT1(CodeGenContext context, uint encoding); + static abstract void LdrsbRT2(CodeGenContext context, uint encoding); + static abstract void LdrshtA1(CodeGenContext context, uint encoding); + static abstract void LdrshtA2(CodeGenContext context, uint encoding); + static abstract void LdrshtT1(CodeGenContext context, uint encoding); + static abstract void LdrshIA1(CodeGenContext context, uint encoding); + static abstract void LdrshIT1(CodeGenContext context, uint encoding); + static abstract void LdrshIT2(CodeGenContext context, uint encoding); + static abstract void LdrshLA1(CodeGenContext context, uint encoding); + static abstract void LdrshLT1(CodeGenContext context, uint encoding); + static abstract void LdrshRA1(CodeGenContext context, uint encoding); + static abstract void LdrshRT1(CodeGenContext context, uint encoding); + static abstract void LdrshRT2(CodeGenContext context, uint encoding); + static abstract void LdrtA1(CodeGenContext context, uint encoding); + static abstract void LdrtA2(CodeGenContext context, uint encoding); + static abstract void LdrtT1(CodeGenContext context, uint encoding); + static abstract void LdrIA1(CodeGenContext context, uint encoding); + static abstract void LdrIT1(CodeGenContext context, uint encoding); + static abstract void LdrIT2(CodeGenContext context, uint encoding); + static abstract void LdrIT3(CodeGenContext context, uint encoding); + static abstract void LdrIT4(CodeGenContext context, uint encoding); + static abstract void LdrLA1(CodeGenContext context, uint encoding); + static abstract void LdrLT1(CodeGenContext context, uint encoding); + static abstract void LdrLT2(CodeGenContext context, uint encoding); + static abstract void LdrRA1(CodeGenContext context, uint encoding); + static abstract void LdrRT1(CodeGenContext context, uint encoding); + static abstract void LdrRT2(CodeGenContext context, uint encoding); + static abstract void McrA1(CodeGenContext context, uint encoding); + static abstract void McrT1(CodeGenContext context, uint encoding); + static abstract void McrrA1(CodeGenContext context, uint encoding); + static abstract void McrrT1(CodeGenContext context, uint encoding); + static abstract void MlaA1(CodeGenContext context, uint encoding); + static abstract void MlaT1(CodeGenContext context, uint encoding); + static abstract void MlsA1(CodeGenContext context, uint encoding); + static abstract void MlsT1(CodeGenContext context, uint encoding); + static abstract void MovtA1(CodeGenContext context, uint encoding); + static abstract void MovtT1(CodeGenContext context, uint encoding); + static abstract void MovIA1(CodeGenContext context, uint encoding); + static abstract void MovIA2(CodeGenContext context, uint encoding); + static abstract void MovIT1(CodeGenContext context, uint encoding); + static abstract void MovIT2(CodeGenContext context, uint encoding); + static abstract void MovIT3(CodeGenContext context, uint encoding); + static abstract void MovRA1(CodeGenContext context, uint encoding); + static abstract void MovRT1(CodeGenContext context, uint encoding); + static abstract void MovRT2(CodeGenContext context, uint encoding); + static abstract void MovRT3(CodeGenContext context, uint encoding); + static abstract void MovRrA1(CodeGenContext context, uint encoding); + static abstract void MovRrT1(CodeGenContext context, uint encoding); + static abstract void MovRrT2(CodeGenContext context, uint encoding); + static abstract void MrcA1(CodeGenContext context, uint encoding); + static abstract void MrcT1(CodeGenContext context, uint encoding); + static abstract void MrrcA1(CodeGenContext context, uint encoding); + static abstract void MrrcT1(CodeGenContext context, uint encoding); + static abstract void MrsA1(CodeGenContext context, uint encoding); + static abstract void MrsT1(CodeGenContext context, uint encoding); + static abstract void MrsBrA1(CodeGenContext context, uint encoding); + static abstract void MrsBrT1(CodeGenContext context, uint encoding); + static abstract void MsrBrA1(CodeGenContext context, uint encoding); + static abstract void MsrBrT1(CodeGenContext context, uint encoding); + static abstract void MsrIA1(CodeGenContext context, uint encoding); + static abstract void MsrRA1(CodeGenContext context, uint encoding); + static abstract void MsrRT1(CodeGenContext context, uint encoding); + static abstract void MulA1(CodeGenContext context, uint encoding); + static abstract void MulT1(CodeGenContext context, uint encoding); + static abstract void MulT2(CodeGenContext context, uint encoding); + static abstract void MvnIA1(CodeGenContext context, uint encoding); + static abstract void MvnIT1(CodeGenContext context, uint encoding); + static abstract void MvnRA1(CodeGenContext context, uint encoding); + static abstract void MvnRT1(CodeGenContext context, uint encoding); + static abstract void MvnRT2(CodeGenContext context, uint encoding); + static abstract void MvnRrA1(CodeGenContext context, uint encoding); + static abstract void NopA1(CodeGenContext context, uint encoding); + static abstract void NopT1(CodeGenContext context, uint encoding); + static abstract void NopT2(CodeGenContext context, uint encoding); + static abstract void OrnIT1(CodeGenContext context, uint encoding); + static abstract void OrnRT1(CodeGenContext context, uint encoding); + static abstract void OrrIA1(CodeGenContext context, uint encoding); + static abstract void OrrIT1(CodeGenContext context, uint encoding); + static abstract void OrrRA1(CodeGenContext context, uint encoding); + static abstract void OrrRT1(CodeGenContext context, uint encoding); + static abstract void OrrRT2(CodeGenContext context, uint encoding); + static abstract void OrrRrA1(CodeGenContext context, uint encoding); + static abstract void PkhA1(CodeGenContext context, uint encoding); + static abstract void PkhT1(CodeGenContext context, uint encoding); + static abstract void PldIA1(CodeGenContext context, uint encoding); + static abstract void PldIT1(CodeGenContext context, uint encoding); + static abstract void PldIT2(CodeGenContext context, uint encoding); + static abstract void PldLA1(CodeGenContext context, uint encoding); + static abstract void PldLT1(CodeGenContext context, uint encoding); + static abstract void PldRA1(CodeGenContext context, uint encoding); + static abstract void PldRT1(CodeGenContext context, uint encoding); + static abstract void PliIA1(CodeGenContext context, uint encoding); + static abstract void PliIT1(CodeGenContext context, uint encoding); + static abstract void PliIT2(CodeGenContext context, uint encoding); + static abstract void PliIT3(CodeGenContext context, uint encoding); + static abstract void PliRA1(CodeGenContext context, uint encoding); + static abstract void PliRT1(CodeGenContext context, uint encoding); + static abstract void PopT1(CodeGenContext context, uint encoding); + static abstract void PssbbA1(CodeGenContext context, uint encoding); + static abstract void PssbbT1(CodeGenContext context, uint encoding); + static abstract void PushT1(CodeGenContext context, uint encoding); + static abstract void QaddA1(CodeGenContext context, uint encoding); + static abstract void QaddT1(CodeGenContext context, uint encoding); + static abstract void Qadd16A1(CodeGenContext context, uint encoding); + static abstract void Qadd16T1(CodeGenContext context, uint encoding); + static abstract void Qadd8A1(CodeGenContext context, uint encoding); + static abstract void Qadd8T1(CodeGenContext context, uint encoding); + static abstract void QasxA1(CodeGenContext context, uint encoding); + static abstract void QasxT1(CodeGenContext context, uint encoding); + static abstract void QdaddA1(CodeGenContext context, uint encoding); + static abstract void QdaddT1(CodeGenContext context, uint encoding); + static abstract void QdsubA1(CodeGenContext context, uint encoding); + static abstract void QdsubT1(CodeGenContext context, uint encoding); + static abstract void QsaxA1(CodeGenContext context, uint encoding); + static abstract void QsaxT1(CodeGenContext context, uint encoding); + static abstract void QsubA1(CodeGenContext context, uint encoding); + static abstract void QsubT1(CodeGenContext context, uint encoding); + static abstract void Qsub16A1(CodeGenContext context, uint encoding); + static abstract void Qsub16T1(CodeGenContext context, uint encoding); + static abstract void Qsub8A1(CodeGenContext context, uint encoding); + static abstract void Qsub8T1(CodeGenContext context, uint encoding); + static abstract void RbitA1(CodeGenContext context, uint encoding); + static abstract void RbitT1(CodeGenContext context, uint encoding); + static abstract void RevA1(CodeGenContext context, uint encoding); + static abstract void RevT1(CodeGenContext context, uint encoding); + static abstract void RevT2(CodeGenContext context, uint encoding); + static abstract void Rev16A1(CodeGenContext context, uint encoding); + static abstract void Rev16T1(CodeGenContext context, uint encoding); + static abstract void Rev16T2(CodeGenContext context, uint encoding); + static abstract void RevshA1(CodeGenContext context, uint encoding); + static abstract void RevshT1(CodeGenContext context, uint encoding); + static abstract void RevshT2(CodeGenContext context, uint encoding); + static abstract void RfeA1(CodeGenContext context, uint encoding); + static abstract void RfeT1(CodeGenContext context, uint encoding); + static abstract void RfeT2(CodeGenContext context, uint encoding); + static abstract void RsbIA1(CodeGenContext context, uint encoding); + static abstract void RsbIT1(CodeGenContext context, uint encoding); + static abstract void RsbIT2(CodeGenContext context, uint encoding); + static abstract void RsbRA1(CodeGenContext context, uint encoding); + static abstract void RsbRT1(CodeGenContext context, uint encoding); + static abstract void RsbRrA1(CodeGenContext context, uint encoding); + static abstract void RscIA1(CodeGenContext context, uint encoding); + static abstract void RscRA1(CodeGenContext context, uint encoding); + static abstract void RscRrA1(CodeGenContext context, uint encoding); + static abstract void Sadd16A1(CodeGenContext context, uint encoding); + static abstract void Sadd16T1(CodeGenContext context, uint encoding); + static abstract void Sadd8A1(CodeGenContext context, uint encoding); + static abstract void Sadd8T1(CodeGenContext context, uint encoding); + static abstract void SasxA1(CodeGenContext context, uint encoding); + static abstract void SasxT1(CodeGenContext context, uint encoding); + static abstract void SbA1(CodeGenContext context, uint encoding); + static abstract void SbT1(CodeGenContext context, uint encoding); + static abstract void SbcIA1(CodeGenContext context, uint encoding); + static abstract void SbcIT1(CodeGenContext context, uint encoding); + static abstract void SbcRA1(CodeGenContext context, uint encoding); + static abstract void SbcRT1(CodeGenContext context, uint encoding); + static abstract void SbcRT2(CodeGenContext context, uint encoding); + static abstract void SbcRrA1(CodeGenContext context, uint encoding); + static abstract void SbfxA1(CodeGenContext context, uint encoding); + static abstract void SbfxT1(CodeGenContext context, uint encoding); + static abstract void SdivA1(CodeGenContext context, uint encoding); + static abstract void SdivT1(CodeGenContext context, uint encoding); + static abstract void SelA1(CodeGenContext context, uint encoding); + static abstract void SelT1(CodeGenContext context, uint encoding); + static abstract void SetendA1(CodeGenContext context, uint encoding); + static abstract void SetendT1(CodeGenContext context, uint encoding); + static abstract void SetpanA1(CodeGenContext context, uint encoding); + static abstract void SetpanT1(CodeGenContext context, uint encoding); + static abstract void SevA1(CodeGenContext context, uint encoding); + static abstract void SevT1(CodeGenContext context, uint encoding); + static abstract void SevT2(CodeGenContext context, uint encoding); + static abstract void SevlA1(CodeGenContext context, uint encoding); + static abstract void SevlT1(CodeGenContext context, uint encoding); + static abstract void SevlT2(CodeGenContext context, uint encoding); + static abstract void Sha1cA1(CodeGenContext context, uint encoding); + static abstract void Sha1cT1(CodeGenContext context, uint encoding); + static abstract void Sha1hA1(CodeGenContext context, uint encoding); + static abstract void Sha1hT1(CodeGenContext context, uint encoding); + static abstract void Sha1mA1(CodeGenContext context, uint encoding); + static abstract void Sha1mT1(CodeGenContext context, uint encoding); + static abstract void Sha1pA1(CodeGenContext context, uint encoding); + static abstract void Sha1pT1(CodeGenContext context, uint encoding); + static abstract void Sha1su0A1(CodeGenContext context, uint encoding); + static abstract void Sha1su0T1(CodeGenContext context, uint encoding); + static abstract void Sha1su1A1(CodeGenContext context, uint encoding); + static abstract void Sha1su1T1(CodeGenContext context, uint encoding); + static abstract void Sha256hA1(CodeGenContext context, uint encoding); + static abstract void Sha256hT1(CodeGenContext context, uint encoding); + static abstract void Sha256h2A1(CodeGenContext context, uint encoding); + static abstract void Sha256h2T1(CodeGenContext context, uint encoding); + static abstract void Sha256su0A1(CodeGenContext context, uint encoding); + static abstract void Sha256su0T1(CodeGenContext context, uint encoding); + static abstract void Sha256su1A1(CodeGenContext context, uint encoding); + static abstract void Sha256su1T1(CodeGenContext context, uint encoding); + static abstract void Shadd16A1(CodeGenContext context, uint encoding); + static abstract void Shadd16T1(CodeGenContext context, uint encoding); + static abstract void Shadd8A1(CodeGenContext context, uint encoding); + static abstract void Shadd8T1(CodeGenContext context, uint encoding); + static abstract void ShasxA1(CodeGenContext context, uint encoding); + static abstract void ShasxT1(CodeGenContext context, uint encoding); + static abstract void ShsaxA1(CodeGenContext context, uint encoding); + static abstract void ShsaxT1(CodeGenContext context, uint encoding); + static abstract void Shsub16A1(CodeGenContext context, uint encoding); + static abstract void Shsub16T1(CodeGenContext context, uint encoding); + static abstract void Shsub8A1(CodeGenContext context, uint encoding); + static abstract void Shsub8T1(CodeGenContext context, uint encoding); + static abstract void SmcA1(CodeGenContext context, uint encoding); + static abstract void SmcT1(CodeGenContext context, uint encoding); + static abstract void SmlabbA1(CodeGenContext context, uint encoding); + static abstract void SmlabbT1(CodeGenContext context, uint encoding); + static abstract void SmladA1(CodeGenContext context, uint encoding); + static abstract void SmladT1(CodeGenContext context, uint encoding); + static abstract void SmlalA1(CodeGenContext context, uint encoding); + static abstract void SmlalT1(CodeGenContext context, uint encoding); + static abstract void SmlalbbA1(CodeGenContext context, uint encoding); + static abstract void SmlalbbT1(CodeGenContext context, uint encoding); + static abstract void SmlaldA1(CodeGenContext context, uint encoding); + static abstract void SmlaldT1(CodeGenContext context, uint encoding); + static abstract void SmlawbA1(CodeGenContext context, uint encoding); + static abstract void SmlawbT1(CodeGenContext context, uint encoding); + static abstract void SmlsdA1(CodeGenContext context, uint encoding); + static abstract void SmlsdT1(CodeGenContext context, uint encoding); + static abstract void SmlsldA1(CodeGenContext context, uint encoding); + static abstract void SmlsldT1(CodeGenContext context, uint encoding); + static abstract void SmmlaA1(CodeGenContext context, uint encoding); + static abstract void SmmlaT1(CodeGenContext context, uint encoding); + static abstract void SmmlsA1(CodeGenContext context, uint encoding); + static abstract void SmmlsT1(CodeGenContext context, uint encoding); + static abstract void SmmulA1(CodeGenContext context, uint encoding); + static abstract void SmmulT1(CodeGenContext context, uint encoding); + static abstract void SmuadA1(CodeGenContext context, uint encoding); + static abstract void SmuadT1(CodeGenContext context, uint encoding); + static abstract void SmulbbA1(CodeGenContext context, uint encoding); + static abstract void SmulbbT1(CodeGenContext context, uint encoding); + static abstract void SmullA1(CodeGenContext context, uint encoding); + static abstract void SmullT1(CodeGenContext context, uint encoding); + static abstract void SmulwbA1(CodeGenContext context, uint encoding); + static abstract void SmulwbT1(CodeGenContext context, uint encoding); + static abstract void SmusdA1(CodeGenContext context, uint encoding); + static abstract void SmusdT1(CodeGenContext context, uint encoding); + static abstract void SrsA1(CodeGenContext context, uint encoding); + static abstract void SrsT1(CodeGenContext context, uint encoding); + static abstract void SrsT2(CodeGenContext context, uint encoding); + static abstract void SsatA1(CodeGenContext context, uint encoding); + static abstract void SsatT1(CodeGenContext context, uint encoding); + static abstract void Ssat16A1(CodeGenContext context, uint encoding); + static abstract void Ssat16T1(CodeGenContext context, uint encoding); + static abstract void SsaxA1(CodeGenContext context, uint encoding); + static abstract void SsaxT1(CodeGenContext context, uint encoding); + static abstract void SsbbA1(CodeGenContext context, uint encoding); + static abstract void SsbbT1(CodeGenContext context, uint encoding); + static abstract void Ssub16A1(CodeGenContext context, uint encoding); + static abstract void Ssub16T1(CodeGenContext context, uint encoding); + static abstract void Ssub8A1(CodeGenContext context, uint encoding); + static abstract void Ssub8T1(CodeGenContext context, uint encoding); + static abstract void StcA1(CodeGenContext context, uint encoding); + static abstract void StcT1(CodeGenContext context, uint encoding); + static abstract void StlA1(CodeGenContext context, uint encoding); + static abstract void StlT1(CodeGenContext context, uint encoding); + static abstract void StlbA1(CodeGenContext context, uint encoding); + static abstract void StlbT1(CodeGenContext context, uint encoding); + static abstract void StlexA1(CodeGenContext context, uint encoding); + static abstract void StlexT1(CodeGenContext context, uint encoding); + static abstract void StlexbA1(CodeGenContext context, uint encoding); + static abstract void StlexbT1(CodeGenContext context, uint encoding); + static abstract void StlexdA1(CodeGenContext context, uint encoding); + static abstract void StlexdT1(CodeGenContext context, uint encoding); + static abstract void StlexhA1(CodeGenContext context, uint encoding); + static abstract void StlexhT1(CodeGenContext context, uint encoding); + static abstract void StlhA1(CodeGenContext context, uint encoding); + static abstract void StlhT1(CodeGenContext context, uint encoding); + static abstract void StmA1(CodeGenContext context, uint encoding); + static abstract void StmT1(CodeGenContext context, uint encoding); + static abstract void StmT2(CodeGenContext context, uint encoding); + static abstract void StmdaA1(CodeGenContext context, uint encoding); + static abstract void StmdbA1(CodeGenContext context, uint encoding); + static abstract void StmdbT1(CodeGenContext context, uint encoding); + static abstract void StmibA1(CodeGenContext context, uint encoding); + static abstract void StmUA1(CodeGenContext context, uint encoding); + static abstract void StrbtA1(CodeGenContext context, uint encoding); + static abstract void StrbtA2(CodeGenContext context, uint encoding); + static abstract void StrbtT1(CodeGenContext context, uint encoding); + static abstract void StrbIA1(CodeGenContext context, uint encoding); + static abstract void StrbIT1(CodeGenContext context, uint encoding); + static abstract void StrbIT2(CodeGenContext context, uint encoding); + static abstract void StrbIT3(CodeGenContext context, uint encoding); + static abstract void StrbRA1(CodeGenContext context, uint encoding); + static abstract void StrbRT1(CodeGenContext context, uint encoding); + static abstract void StrbRT2(CodeGenContext context, uint encoding); + static abstract void StrdIA1(CodeGenContext context, uint encoding); + static abstract void StrdIT1(CodeGenContext context, uint encoding); + static abstract void StrdRA1(CodeGenContext context, uint encoding); + static abstract void StrexA1(CodeGenContext context, uint encoding); + static abstract void StrexT1(CodeGenContext context, uint encoding); + static abstract void StrexbA1(CodeGenContext context, uint encoding); + static abstract void StrexbT1(CodeGenContext context, uint encoding); + static abstract void StrexdA1(CodeGenContext context, uint encoding); + static abstract void StrexdT1(CodeGenContext context, uint encoding); + static abstract void StrexhA1(CodeGenContext context, uint encoding); + static abstract void StrexhT1(CodeGenContext context, uint encoding); + static abstract void StrhtA1(CodeGenContext context, uint encoding); + static abstract void StrhtA2(CodeGenContext context, uint encoding); + static abstract void StrhtT1(CodeGenContext context, uint encoding); + static abstract void StrhIA1(CodeGenContext context, uint encoding); + static abstract void StrhIT1(CodeGenContext context, uint encoding); + static abstract void StrhIT2(CodeGenContext context, uint encoding); + static abstract void StrhIT3(CodeGenContext context, uint encoding); + static abstract void StrhRA1(CodeGenContext context, uint encoding); + static abstract void StrhRT1(CodeGenContext context, uint encoding); + static abstract void StrhRT2(CodeGenContext context, uint encoding); + static abstract void StrtA1(CodeGenContext context, uint encoding); + static abstract void StrtA2(CodeGenContext context, uint encoding); + static abstract void StrtT1(CodeGenContext context, uint encoding); + static abstract void StrIA1(CodeGenContext context, uint encoding); + static abstract void StrIT1(CodeGenContext context, uint encoding); + static abstract void StrIT2(CodeGenContext context, uint encoding); + static abstract void StrIT3(CodeGenContext context, uint encoding); + static abstract void StrIT4(CodeGenContext context, uint encoding); + static abstract void StrRA1(CodeGenContext context, uint encoding); + static abstract void StrRT1(CodeGenContext context, uint encoding); + static abstract void StrRT2(CodeGenContext context, uint encoding); + static abstract void SubIA1(CodeGenContext context, uint encoding); + static abstract void SubIT1(CodeGenContext context, uint encoding); + static abstract void SubIT2(CodeGenContext context, uint encoding); + static abstract void SubIT3(CodeGenContext context, uint encoding); + static abstract void SubIT4(CodeGenContext context, uint encoding); + static abstract void SubIT5(CodeGenContext context, uint encoding); + static abstract void SubRA1(CodeGenContext context, uint encoding); + static abstract void SubRT1(CodeGenContext context, uint encoding); + static abstract void SubRT2(CodeGenContext context, uint encoding); + static abstract void SubRrA1(CodeGenContext context, uint encoding); + static abstract void SubSpIA1(CodeGenContext context, uint encoding); + static abstract void SubSpIT1(CodeGenContext context, uint encoding); + static abstract void SubSpIT2(CodeGenContext context, uint encoding); + static abstract void SubSpIT3(CodeGenContext context, uint encoding); + static abstract void SubSpRA1(CodeGenContext context, uint encoding); + static abstract void SubSpRT1(CodeGenContext context, uint encoding); + static abstract void SvcA1(CodeGenContext context, uint encoding); + static abstract void SvcT1(CodeGenContext context, uint encoding); + static abstract void SxtabA1(CodeGenContext context, uint encoding); + static abstract void SxtabT1(CodeGenContext context, uint encoding); + static abstract void Sxtab16A1(CodeGenContext context, uint encoding); + static abstract void Sxtab16T1(CodeGenContext context, uint encoding); + static abstract void SxtahA1(CodeGenContext context, uint encoding); + static abstract void SxtahT1(CodeGenContext context, uint encoding); + static abstract void SxtbA1(CodeGenContext context, uint encoding); + static abstract void SxtbT1(CodeGenContext context, uint encoding); + static abstract void SxtbT2(CodeGenContext context, uint encoding); + static abstract void Sxtb16A1(CodeGenContext context, uint encoding); + static abstract void Sxtb16T1(CodeGenContext context, uint encoding); + static abstract void SxthA1(CodeGenContext context, uint encoding); + static abstract void SxthT1(CodeGenContext context, uint encoding); + static abstract void SxthT2(CodeGenContext context, uint encoding); + static abstract void TbbT1(CodeGenContext context, uint encoding); + static abstract void TeqIA1(CodeGenContext context, uint encoding); + static abstract void TeqIT1(CodeGenContext context, uint encoding); + static abstract void TeqRA1(CodeGenContext context, uint encoding); + static abstract void TeqRT1(CodeGenContext context, uint encoding); + static abstract void TeqRrA1(CodeGenContext context, uint encoding); + static abstract void TsbA1(CodeGenContext context, uint encoding); + static abstract void TsbT1(CodeGenContext context, uint encoding); + static abstract void TstIA1(CodeGenContext context, uint encoding); + static abstract void TstIT1(CodeGenContext context, uint encoding); + static abstract void TstRA1(CodeGenContext context, uint encoding); + static abstract void TstRT1(CodeGenContext context, uint encoding); + static abstract void TstRT2(CodeGenContext context, uint encoding); + static abstract void TstRrA1(CodeGenContext context, uint encoding); + static abstract void Uadd16A1(CodeGenContext context, uint encoding); + static abstract void Uadd16T1(CodeGenContext context, uint encoding); + static abstract void Uadd8A1(CodeGenContext context, uint encoding); + static abstract void Uadd8T1(CodeGenContext context, uint encoding); + static abstract void UasxA1(CodeGenContext context, uint encoding); + static abstract void UasxT1(CodeGenContext context, uint encoding); + static abstract void UbfxA1(CodeGenContext context, uint encoding); + static abstract void UbfxT1(CodeGenContext context, uint encoding); + static abstract void UdfA1(CodeGenContext context, uint encoding); + static abstract void UdfT1(CodeGenContext context, uint encoding); + static abstract void UdfT2(CodeGenContext context, uint encoding); + static abstract void UdivA1(CodeGenContext context, uint encoding); + static abstract void UdivT1(CodeGenContext context, uint encoding); + static abstract void Uhadd16A1(CodeGenContext context, uint encoding); + static abstract void Uhadd16T1(CodeGenContext context, uint encoding); + static abstract void Uhadd8A1(CodeGenContext context, uint encoding); + static abstract void Uhadd8T1(CodeGenContext context, uint encoding); + static abstract void UhasxA1(CodeGenContext context, uint encoding); + static abstract void UhasxT1(CodeGenContext context, uint encoding); + static abstract void UhsaxA1(CodeGenContext context, uint encoding); + static abstract void UhsaxT1(CodeGenContext context, uint encoding); + static abstract void Uhsub16A1(CodeGenContext context, uint encoding); + static abstract void Uhsub16T1(CodeGenContext context, uint encoding); + static abstract void Uhsub8A1(CodeGenContext context, uint encoding); + static abstract void Uhsub8T1(CodeGenContext context, uint encoding); + static abstract void UmaalA1(CodeGenContext context, uint encoding); + static abstract void UmaalT1(CodeGenContext context, uint encoding); + static abstract void UmlalA1(CodeGenContext context, uint encoding); + static abstract void UmlalT1(CodeGenContext context, uint encoding); + static abstract void UmullA1(CodeGenContext context, uint encoding); + static abstract void UmullT1(CodeGenContext context, uint encoding); + static abstract void Uqadd16A1(CodeGenContext context, uint encoding); + static abstract void Uqadd16T1(CodeGenContext context, uint encoding); + static abstract void Uqadd8A1(CodeGenContext context, uint encoding); + static abstract void Uqadd8T1(CodeGenContext context, uint encoding); + static abstract void UqasxA1(CodeGenContext context, uint encoding); + static abstract void UqasxT1(CodeGenContext context, uint encoding); + static abstract void UqsaxA1(CodeGenContext context, uint encoding); + static abstract void UqsaxT1(CodeGenContext context, uint encoding); + static abstract void Uqsub16A1(CodeGenContext context, uint encoding); + static abstract void Uqsub16T1(CodeGenContext context, uint encoding); + static abstract void Uqsub8A1(CodeGenContext context, uint encoding); + static abstract void Uqsub8T1(CodeGenContext context, uint encoding); + static abstract void Usad8A1(CodeGenContext context, uint encoding); + static abstract void Usad8T1(CodeGenContext context, uint encoding); + static abstract void Usada8A1(CodeGenContext context, uint encoding); + static abstract void Usada8T1(CodeGenContext context, uint encoding); + static abstract void UsatA1(CodeGenContext context, uint encoding); + static abstract void UsatT1(CodeGenContext context, uint encoding); + static abstract void Usat16A1(CodeGenContext context, uint encoding); + static abstract void Usat16T1(CodeGenContext context, uint encoding); + static abstract void UsaxA1(CodeGenContext context, uint encoding); + static abstract void UsaxT1(CodeGenContext context, uint encoding); + static abstract void Usub16A1(CodeGenContext context, uint encoding); + static abstract void Usub16T1(CodeGenContext context, uint encoding); + static abstract void Usub8A1(CodeGenContext context, uint encoding); + static abstract void Usub8T1(CodeGenContext context, uint encoding); + static abstract void UxtabA1(CodeGenContext context, uint encoding); + static abstract void UxtabT1(CodeGenContext context, uint encoding); + static abstract void Uxtab16A1(CodeGenContext context, uint encoding); + static abstract void Uxtab16T1(CodeGenContext context, uint encoding); + static abstract void UxtahA1(CodeGenContext context, uint encoding); + static abstract void UxtahT1(CodeGenContext context, uint encoding); + static abstract void UxtbA1(CodeGenContext context, uint encoding); + static abstract void UxtbT1(CodeGenContext context, uint encoding); + static abstract void UxtbT2(CodeGenContext context, uint encoding); + static abstract void Uxtb16A1(CodeGenContext context, uint encoding); + static abstract void Uxtb16T1(CodeGenContext context, uint encoding); + static abstract void UxthA1(CodeGenContext context, uint encoding); + static abstract void UxthT1(CodeGenContext context, uint encoding); + static abstract void UxthT2(CodeGenContext context, uint encoding); + static abstract void VabaA1(CodeGenContext context, uint encoding); + static abstract void VabaT1(CodeGenContext context, uint encoding); + static abstract void VabalA1(CodeGenContext context, uint encoding); + static abstract void VabalT1(CodeGenContext context, uint encoding); + static abstract void VabdlIA1(CodeGenContext context, uint encoding); + static abstract void VabdlIT1(CodeGenContext context, uint encoding); + static abstract void VabdFA1(CodeGenContext context, uint encoding); + static abstract void VabdFT1(CodeGenContext context, uint encoding); + static abstract void VabdIA1(CodeGenContext context, uint encoding); + static abstract void VabdIT1(CodeGenContext context, uint encoding); + static abstract void VabsA1(CodeGenContext context, uint encoding); + static abstract void VabsA2(CodeGenContext context, uint encoding); + static abstract void VabsT1(CodeGenContext context, uint encoding); + static abstract void VabsT2(CodeGenContext context, uint encoding); + static abstract void VacgeA1(CodeGenContext context, uint encoding); + static abstract void VacgeT1(CodeGenContext context, uint encoding); + static abstract void VacgtA1(CodeGenContext context, uint encoding); + static abstract void VacgtT1(CodeGenContext context, uint encoding); + static abstract void VaddhnA1(CodeGenContext context, uint encoding); + static abstract void VaddhnT1(CodeGenContext context, uint encoding); + static abstract void VaddlA1(CodeGenContext context, uint encoding); + static abstract void VaddlT1(CodeGenContext context, uint encoding); + static abstract void VaddwA1(CodeGenContext context, uint encoding); + static abstract void VaddwT1(CodeGenContext context, uint encoding); + static abstract void VaddFA1(CodeGenContext context, uint encoding); + static abstract void VaddFA2(CodeGenContext context, uint encoding); + static abstract void VaddFT1(CodeGenContext context, uint encoding); + static abstract void VaddFT2(CodeGenContext context, uint encoding); + static abstract void VaddIA1(CodeGenContext context, uint encoding); + static abstract void VaddIT1(CodeGenContext context, uint encoding); + static abstract void VandRA1(CodeGenContext context, uint encoding); + static abstract void VandRT1(CodeGenContext context, uint encoding); + static abstract void VbicIA1(CodeGenContext context, uint encoding); + static abstract void VbicIA2(CodeGenContext context, uint encoding); + static abstract void VbicIT1(CodeGenContext context, uint encoding); + static abstract void VbicIT2(CodeGenContext context, uint encoding); + static abstract void VbicRA1(CodeGenContext context, uint encoding); + static abstract void VbicRT1(CodeGenContext context, uint encoding); + static abstract void VbifA1(CodeGenContext context, uint encoding); + static abstract void VbifT1(CodeGenContext context, uint encoding); + static abstract void VbitA1(CodeGenContext context, uint encoding); + static abstract void VbitT1(CodeGenContext context, uint encoding); + static abstract void VbslA1(CodeGenContext context, uint encoding); + static abstract void VbslT1(CodeGenContext context, uint encoding); + static abstract void VcaddA1(CodeGenContext context, uint encoding); + static abstract void VcaddT1(CodeGenContext context, uint encoding); + static abstract void VceqIA1(CodeGenContext context, uint encoding); + static abstract void VceqIT1(CodeGenContext context, uint encoding); + static abstract void VceqRA1(CodeGenContext context, uint encoding); + static abstract void VceqRA2(CodeGenContext context, uint encoding); + static abstract void VceqRT1(CodeGenContext context, uint encoding); + static abstract void VceqRT2(CodeGenContext context, uint encoding); + static abstract void VcgeIA1(CodeGenContext context, uint encoding); + static abstract void VcgeIT1(CodeGenContext context, uint encoding); + static abstract void VcgeRA1(CodeGenContext context, uint encoding); + static abstract void VcgeRA2(CodeGenContext context, uint encoding); + static abstract void VcgeRT1(CodeGenContext context, uint encoding); + static abstract void VcgeRT2(CodeGenContext context, uint encoding); + static abstract void VcgtIA1(CodeGenContext context, uint encoding); + static abstract void VcgtIT1(CodeGenContext context, uint encoding); + static abstract void VcgtRA1(CodeGenContext context, uint encoding); + static abstract void VcgtRA2(CodeGenContext context, uint encoding); + static abstract void VcgtRT1(CodeGenContext context, uint encoding); + static abstract void VcgtRT2(CodeGenContext context, uint encoding); + static abstract void VcleIA1(CodeGenContext context, uint encoding); + static abstract void VcleIT1(CodeGenContext context, uint encoding); + static abstract void VclsA1(CodeGenContext context, uint encoding); + static abstract void VclsT1(CodeGenContext context, uint encoding); + static abstract void VcltIA1(CodeGenContext context, uint encoding); + static abstract void VcltIT1(CodeGenContext context, uint encoding); + static abstract void VclzA1(CodeGenContext context, uint encoding); + static abstract void VclzT1(CodeGenContext context, uint encoding); + static abstract void VcmlaA1(CodeGenContext context, uint encoding); + static abstract void VcmlaT1(CodeGenContext context, uint encoding); + static abstract void VcmlaSA1(CodeGenContext context, uint encoding); + static abstract void VcmlaST1(CodeGenContext context, uint encoding); + static abstract void VcmpA1(CodeGenContext context, uint encoding); + static abstract void VcmpA2(CodeGenContext context, uint encoding); + static abstract void VcmpT1(CodeGenContext context, uint encoding); + static abstract void VcmpT2(CodeGenContext context, uint encoding); + static abstract void VcmpeA1(CodeGenContext context, uint encoding); + static abstract void VcmpeA2(CodeGenContext context, uint encoding); + static abstract void VcmpeT1(CodeGenContext context, uint encoding); + static abstract void VcmpeT2(CodeGenContext context, uint encoding); + static abstract void VcntA1(CodeGenContext context, uint encoding); + static abstract void VcntT1(CodeGenContext context, uint encoding); + static abstract void VcvtaAsimdA1(CodeGenContext context, uint encoding); + static abstract void VcvtaAsimdT1(CodeGenContext context, uint encoding); + static abstract void VcvtaVfpA1(CodeGenContext context, uint encoding); + static abstract void VcvtaVfpT1(CodeGenContext context, uint encoding); + static abstract void VcvtbA1(CodeGenContext context, uint encoding); + static abstract void VcvtbT1(CodeGenContext context, uint encoding); + static abstract void VcvtbBfsA1(CodeGenContext context, uint encoding); + static abstract void VcvtbBfsT1(CodeGenContext context, uint encoding); + static abstract void VcvtmAsimdA1(CodeGenContext context, uint encoding); + static abstract void VcvtmAsimdT1(CodeGenContext context, uint encoding); + static abstract void VcvtmVfpA1(CodeGenContext context, uint encoding); + static abstract void VcvtmVfpT1(CodeGenContext context, uint encoding); + static abstract void VcvtnAsimdA1(CodeGenContext context, uint encoding); + static abstract void VcvtnAsimdT1(CodeGenContext context, uint encoding); + static abstract void VcvtnVfpA1(CodeGenContext context, uint encoding); + static abstract void VcvtnVfpT1(CodeGenContext context, uint encoding); + static abstract void VcvtpAsimdA1(CodeGenContext context, uint encoding); + static abstract void VcvtpAsimdT1(CodeGenContext context, uint encoding); + static abstract void VcvtpVfpA1(CodeGenContext context, uint encoding); + static abstract void VcvtpVfpT1(CodeGenContext context, uint encoding); + static abstract void VcvtrIvA1(CodeGenContext context, uint encoding); + static abstract void VcvtrIvT1(CodeGenContext context, uint encoding); + static abstract void VcvttA1(CodeGenContext context, uint encoding); + static abstract void VcvttT1(CodeGenContext context, uint encoding); + static abstract void VcvttBfsA1(CodeGenContext context, uint encoding); + static abstract void VcvttBfsT1(CodeGenContext context, uint encoding); + static abstract void VcvtBfsA1(CodeGenContext context, uint encoding); + static abstract void VcvtBfsT1(CodeGenContext context, uint encoding); + static abstract void VcvtDsA1(CodeGenContext context, uint encoding); + static abstract void VcvtDsT1(CodeGenContext context, uint encoding); + static abstract void VcvtHsA1(CodeGenContext context, uint encoding); + static abstract void VcvtHsT1(CodeGenContext context, uint encoding); + static abstract void VcvtIsA1(CodeGenContext context, uint encoding); + static abstract void VcvtIsT1(CodeGenContext context, uint encoding); + static abstract void VcvtIvA1(CodeGenContext context, uint encoding); + static abstract void VcvtIvT1(CodeGenContext context, uint encoding); + static abstract void VcvtViA1(CodeGenContext context, uint encoding); + static abstract void VcvtViT1(CodeGenContext context, uint encoding); + static abstract void VcvtXsA1(CodeGenContext context, uint encoding); + static abstract void VcvtXsT1(CodeGenContext context, uint encoding); + static abstract void VcvtXvA1(CodeGenContext context, uint encoding); + static abstract void VcvtXvT1(CodeGenContext context, uint encoding); + static abstract void VdivA1(CodeGenContext context, uint encoding); + static abstract void VdivT1(CodeGenContext context, uint encoding); + static abstract void VdotA1(CodeGenContext context, uint encoding); + static abstract void VdotT1(CodeGenContext context, uint encoding); + static abstract void VdotSA1(CodeGenContext context, uint encoding); + static abstract void VdotST1(CodeGenContext context, uint encoding); + static abstract void VdupRA1(CodeGenContext context, uint encoding); + static abstract void VdupRT1(CodeGenContext context, uint encoding); + static abstract void VdupSA1(CodeGenContext context, uint encoding); + static abstract void VdupST1(CodeGenContext context, uint encoding); + static abstract void VeorA1(CodeGenContext context, uint encoding); + static abstract void VeorT1(CodeGenContext context, uint encoding); + static abstract void VextA1(CodeGenContext context, uint encoding); + static abstract void VextT1(CodeGenContext context, uint encoding); + static abstract void VfmaA1(CodeGenContext context, uint encoding); + static abstract void VfmaA2(CodeGenContext context, uint encoding); + static abstract void VfmaT1(CodeGenContext context, uint encoding); + static abstract void VfmaT2(CodeGenContext context, uint encoding); + static abstract void VfmalA1(CodeGenContext context, uint encoding); + static abstract void VfmalT1(CodeGenContext context, uint encoding); + static abstract void VfmalSA1(CodeGenContext context, uint encoding); + static abstract void VfmalST1(CodeGenContext context, uint encoding); + static abstract void VfmaBfA1(CodeGenContext context, uint encoding); + static abstract void VfmaBfT1(CodeGenContext context, uint encoding); + static abstract void VfmaBfsA1(CodeGenContext context, uint encoding); + static abstract void VfmaBfsT1(CodeGenContext context, uint encoding); + static abstract void VfmsA1(CodeGenContext context, uint encoding); + static abstract void VfmsA2(CodeGenContext context, uint encoding); + static abstract void VfmsT1(CodeGenContext context, uint encoding); + static abstract void VfmsT2(CodeGenContext context, uint encoding); + static abstract void VfmslA1(CodeGenContext context, uint encoding); + static abstract void VfmslT1(CodeGenContext context, uint encoding); + static abstract void VfmslSA1(CodeGenContext context, uint encoding); + static abstract void VfmslST1(CodeGenContext context, uint encoding); + static abstract void VfnmaA1(CodeGenContext context, uint encoding); + static abstract void VfnmaT1(CodeGenContext context, uint encoding); + static abstract void VfnmsA1(CodeGenContext context, uint encoding); + static abstract void VfnmsT1(CodeGenContext context, uint encoding); + static abstract void VhaddA1(CodeGenContext context, uint encoding); + static abstract void VhaddT1(CodeGenContext context, uint encoding); + static abstract void VhsubA1(CodeGenContext context, uint encoding); + static abstract void VhsubT1(CodeGenContext context, uint encoding); + static abstract void VinsA1(CodeGenContext context, uint encoding); + static abstract void VinsT1(CodeGenContext context, uint encoding); + static abstract void VjcvtA1(CodeGenContext context, uint encoding); + static abstract void VjcvtT1(CodeGenContext context, uint encoding); + static abstract void Vld11A1(CodeGenContext context, uint encoding); + static abstract void Vld11A2(CodeGenContext context, uint encoding); + static abstract void Vld11A3(CodeGenContext context, uint encoding); + static abstract void Vld11T1(CodeGenContext context, uint encoding); + static abstract void Vld11T2(CodeGenContext context, uint encoding); + static abstract void Vld11T3(CodeGenContext context, uint encoding); + static abstract void Vld1AA1(CodeGenContext context, uint encoding); + static abstract void Vld1AT1(CodeGenContext context, uint encoding); + static abstract void Vld1MA1(CodeGenContext context, uint encoding); + static abstract void Vld1MA2(CodeGenContext context, uint encoding); + static abstract void Vld1MA3(CodeGenContext context, uint encoding); + static abstract void Vld1MA4(CodeGenContext context, uint encoding); + static abstract void Vld1MT1(CodeGenContext context, uint encoding); + static abstract void Vld1MT2(CodeGenContext context, uint encoding); + static abstract void Vld1MT3(CodeGenContext context, uint encoding); + static abstract void Vld1MT4(CodeGenContext context, uint encoding); + static abstract void Vld21A1(CodeGenContext context, uint encoding); + static abstract void Vld21A2(CodeGenContext context, uint encoding); + static abstract void Vld21A3(CodeGenContext context, uint encoding); + static abstract void Vld21T1(CodeGenContext context, uint encoding); + static abstract void Vld21T2(CodeGenContext context, uint encoding); + static abstract void Vld21T3(CodeGenContext context, uint encoding); + static abstract void Vld2AA1(CodeGenContext context, uint encoding); + static abstract void Vld2AT1(CodeGenContext context, uint encoding); + static abstract void Vld2MA1(CodeGenContext context, uint encoding); + static abstract void Vld2MA2(CodeGenContext context, uint encoding); + static abstract void Vld2MT1(CodeGenContext context, uint encoding); + static abstract void Vld2MT2(CodeGenContext context, uint encoding); + static abstract void Vld31A1(CodeGenContext context, uint encoding); + static abstract void Vld31A2(CodeGenContext context, uint encoding); + static abstract void Vld31A3(CodeGenContext context, uint encoding); + static abstract void Vld31T1(CodeGenContext context, uint encoding); + static abstract void Vld31T2(CodeGenContext context, uint encoding); + static abstract void Vld31T3(CodeGenContext context, uint encoding); + static abstract void Vld3AA1(CodeGenContext context, uint encoding); + static abstract void Vld3AT1(CodeGenContext context, uint encoding); + static abstract void Vld3MA1(CodeGenContext context, uint encoding); + static abstract void Vld3MT1(CodeGenContext context, uint encoding); + static abstract void Vld41A1(CodeGenContext context, uint encoding); + static abstract void Vld41A2(CodeGenContext context, uint encoding); + static abstract void Vld41A3(CodeGenContext context, uint encoding); + static abstract void Vld41T1(CodeGenContext context, uint encoding); + static abstract void Vld41T2(CodeGenContext context, uint encoding); + static abstract void Vld41T3(CodeGenContext context, uint encoding); + static abstract void Vld4AA1(CodeGenContext context, uint encoding); + static abstract void Vld4AT1(CodeGenContext context, uint encoding); + static abstract void Vld4MA1(CodeGenContext context, uint encoding); + static abstract void Vld4MT1(CodeGenContext context, uint encoding); + static abstract void VldmA1(CodeGenContext context, uint encoding); + static abstract void VldmA2(CodeGenContext context, uint encoding); + static abstract void VldmT1(CodeGenContext context, uint encoding); + static abstract void VldmT2(CodeGenContext context, uint encoding); + static abstract void VldrIA1(CodeGenContext context, uint encoding); + static abstract void VldrIT1(CodeGenContext context, uint encoding); + static abstract void VldrLA1(CodeGenContext context, uint encoding); + static abstract void VldrLT1(CodeGenContext context, uint encoding); + static abstract void VmaxnmA1(CodeGenContext context, uint encoding); + static abstract void VmaxnmA2(CodeGenContext context, uint encoding); + static abstract void VmaxnmT1(CodeGenContext context, uint encoding); + static abstract void VmaxnmT2(CodeGenContext context, uint encoding); + static abstract void VmaxFA1(CodeGenContext context, uint encoding); + static abstract void VmaxFT1(CodeGenContext context, uint encoding); + static abstract void VmaxIA1(CodeGenContext context, uint encoding); + static abstract void VmaxIT1(CodeGenContext context, uint encoding); + static abstract void VminnmA1(CodeGenContext context, uint encoding); + static abstract void VminnmA2(CodeGenContext context, uint encoding); + static abstract void VminnmT1(CodeGenContext context, uint encoding); + static abstract void VminnmT2(CodeGenContext context, uint encoding); + static abstract void VminFA1(CodeGenContext context, uint encoding); + static abstract void VminFT1(CodeGenContext context, uint encoding); + static abstract void VminIA1(CodeGenContext context, uint encoding); + static abstract void VminIT1(CodeGenContext context, uint encoding); + static abstract void VmlalIA1(CodeGenContext context, uint encoding); + static abstract void VmlalIT1(CodeGenContext context, uint encoding); + static abstract void VmlalSA1(CodeGenContext context, uint encoding); + static abstract void VmlalST1(CodeGenContext context, uint encoding); + static abstract void VmlaFA1(CodeGenContext context, uint encoding); + static abstract void VmlaFA2(CodeGenContext context, uint encoding); + static abstract void VmlaFT1(CodeGenContext context, uint encoding); + static abstract void VmlaFT2(CodeGenContext context, uint encoding); + static abstract void VmlaIA1(CodeGenContext context, uint encoding); + static abstract void VmlaIT1(CodeGenContext context, uint encoding); + static abstract void VmlaSA1(CodeGenContext context, uint encoding); + static abstract void VmlaST1(CodeGenContext context, uint encoding); + static abstract void VmlslIA1(CodeGenContext context, uint encoding); + static abstract void VmlslIT1(CodeGenContext context, uint encoding); + static abstract void VmlslSA1(CodeGenContext context, uint encoding); + static abstract void VmlslST1(CodeGenContext context, uint encoding); + static abstract void VmlsFA1(CodeGenContext context, uint encoding); + static abstract void VmlsFA2(CodeGenContext context, uint encoding); + static abstract void VmlsFT1(CodeGenContext context, uint encoding); + static abstract void VmlsFT2(CodeGenContext context, uint encoding); + static abstract void VmlsIA1(CodeGenContext context, uint encoding); + static abstract void VmlsIT1(CodeGenContext context, uint encoding); + static abstract void VmlsSA1(CodeGenContext context, uint encoding); + static abstract void VmlsST1(CodeGenContext context, uint encoding); + static abstract void VmmlaA1(CodeGenContext context, uint encoding); + static abstract void VmmlaT1(CodeGenContext context, uint encoding); + static abstract void VmovlA1(CodeGenContext context, uint encoding); + static abstract void VmovlT1(CodeGenContext context, uint encoding); + static abstract void VmovnA1(CodeGenContext context, uint encoding); + static abstract void VmovnT1(CodeGenContext context, uint encoding); + static abstract void VmovxA1(CodeGenContext context, uint encoding); + static abstract void VmovxT1(CodeGenContext context, uint encoding); + static abstract void VmovDA1(CodeGenContext context, uint encoding); + static abstract void VmovDT1(CodeGenContext context, uint encoding); + static abstract void VmovHA1(CodeGenContext context, uint encoding); + static abstract void VmovHT1(CodeGenContext context, uint encoding); + static abstract void VmovIA1(CodeGenContext context, uint encoding); + static abstract void VmovIA2(CodeGenContext context, uint encoding); + static abstract void VmovIA3(CodeGenContext context, uint encoding); + static abstract void VmovIA4(CodeGenContext context, uint encoding); + static abstract void VmovIA5(CodeGenContext context, uint encoding); + static abstract void VmovIT1(CodeGenContext context, uint encoding); + static abstract void VmovIT2(CodeGenContext context, uint encoding); + static abstract void VmovIT3(CodeGenContext context, uint encoding); + static abstract void VmovIT4(CodeGenContext context, uint encoding); + static abstract void VmovIT5(CodeGenContext context, uint encoding); + static abstract void VmovRA2(CodeGenContext context, uint encoding); + static abstract void VmovRT2(CodeGenContext context, uint encoding); + static abstract void VmovRsA1(CodeGenContext context, uint encoding); + static abstract void VmovRsT1(CodeGenContext context, uint encoding); + static abstract void VmovSA1(CodeGenContext context, uint encoding); + static abstract void VmovST1(CodeGenContext context, uint encoding); + static abstract void VmovSrA1(CodeGenContext context, uint encoding); + static abstract void VmovSrT1(CodeGenContext context, uint encoding); + static abstract void VmovSsA1(CodeGenContext context, uint encoding); + static abstract void VmovSsT1(CodeGenContext context, uint encoding); + static abstract void VmrsA1(CodeGenContext context, uint encoding); + static abstract void VmrsT1(CodeGenContext context, uint encoding); + static abstract void VmsrA1(CodeGenContext context, uint encoding); + static abstract void VmsrT1(CodeGenContext context, uint encoding); + static abstract void VmullIA1(CodeGenContext context, uint encoding); + static abstract void VmullIT1(CodeGenContext context, uint encoding); + static abstract void VmullSA1(CodeGenContext context, uint encoding); + static abstract void VmullST1(CodeGenContext context, uint encoding); + static abstract void VmulFA1(CodeGenContext context, uint encoding); + static abstract void VmulFA2(CodeGenContext context, uint encoding); + static abstract void VmulFT1(CodeGenContext context, uint encoding); + static abstract void VmulFT2(CodeGenContext context, uint encoding); + static abstract void VmulIA1(CodeGenContext context, uint encoding); + static abstract void VmulIT1(CodeGenContext context, uint encoding); + static abstract void VmulSA1(CodeGenContext context, uint encoding); + static abstract void VmulST1(CodeGenContext context, uint encoding); + static abstract void VmvnIA1(CodeGenContext context, uint encoding); + static abstract void VmvnIA2(CodeGenContext context, uint encoding); + static abstract void VmvnIA3(CodeGenContext context, uint encoding); + static abstract void VmvnIT1(CodeGenContext context, uint encoding); + static abstract void VmvnIT2(CodeGenContext context, uint encoding); + static abstract void VmvnIT3(CodeGenContext context, uint encoding); + static abstract void VmvnRA1(CodeGenContext context, uint encoding); + static abstract void VmvnRT1(CodeGenContext context, uint encoding); + static abstract void VnegA1(CodeGenContext context, uint encoding); + static abstract void VnegA2(CodeGenContext context, uint encoding); + static abstract void VnegT1(CodeGenContext context, uint encoding); + static abstract void VnegT2(CodeGenContext context, uint encoding); + static abstract void VnmlaA1(CodeGenContext context, uint encoding); + static abstract void VnmlaT1(CodeGenContext context, uint encoding); + static abstract void VnmlsA1(CodeGenContext context, uint encoding); + static abstract void VnmlsT1(CodeGenContext context, uint encoding); + static abstract void VnmulA1(CodeGenContext context, uint encoding); + static abstract void VnmulT1(CodeGenContext context, uint encoding); + static abstract void VornRA1(CodeGenContext context, uint encoding); + static abstract void VornRT1(CodeGenContext context, uint encoding); + static abstract void VorrIA1(CodeGenContext context, uint encoding); + static abstract void VorrIA2(CodeGenContext context, uint encoding); + static abstract void VorrIT1(CodeGenContext context, uint encoding); + static abstract void VorrIT2(CodeGenContext context, uint encoding); + static abstract void VorrRA1(CodeGenContext context, uint encoding); + static abstract void VorrRT1(CodeGenContext context, uint encoding); + static abstract void VpadalA1(CodeGenContext context, uint encoding); + static abstract void VpadalT1(CodeGenContext context, uint encoding); + static abstract void VpaddlA1(CodeGenContext context, uint encoding); + static abstract void VpaddlT1(CodeGenContext context, uint encoding); + static abstract void VpaddFA1(CodeGenContext context, uint encoding); + static abstract void VpaddFT1(CodeGenContext context, uint encoding); + static abstract void VpaddIA1(CodeGenContext context, uint encoding); + static abstract void VpaddIT1(CodeGenContext context, uint encoding); + static abstract void VpmaxFA1(CodeGenContext context, uint encoding); + static abstract void VpmaxFT1(CodeGenContext context, uint encoding); + static abstract void VpmaxIA1(CodeGenContext context, uint encoding); + static abstract void VpmaxIT1(CodeGenContext context, uint encoding); + static abstract void VpminFA1(CodeGenContext context, uint encoding); + static abstract void VpminFT1(CodeGenContext context, uint encoding); + static abstract void VpminIA1(CodeGenContext context, uint encoding); + static abstract void VpminIT1(CodeGenContext context, uint encoding); + static abstract void VqabsA1(CodeGenContext context, uint encoding); + static abstract void VqabsT1(CodeGenContext context, uint encoding); + static abstract void VqaddA1(CodeGenContext context, uint encoding); + static abstract void VqaddT1(CodeGenContext context, uint encoding); + static abstract void VqdmlalA1(CodeGenContext context, uint encoding); + static abstract void VqdmlalA2(CodeGenContext context, uint encoding); + static abstract void VqdmlalT1(CodeGenContext context, uint encoding); + static abstract void VqdmlalT2(CodeGenContext context, uint encoding); + static abstract void VqdmlslA1(CodeGenContext context, uint encoding); + static abstract void VqdmlslA2(CodeGenContext context, uint encoding); + static abstract void VqdmlslT1(CodeGenContext context, uint encoding); + static abstract void VqdmlslT2(CodeGenContext context, uint encoding); + static abstract void VqdmulhA1(CodeGenContext context, uint encoding); + static abstract void VqdmulhA2(CodeGenContext context, uint encoding); + static abstract void VqdmulhT1(CodeGenContext context, uint encoding); + static abstract void VqdmulhT2(CodeGenContext context, uint encoding); + static abstract void VqdmullA1(CodeGenContext context, uint encoding); + static abstract void VqdmullA2(CodeGenContext context, uint encoding); + static abstract void VqdmullT1(CodeGenContext context, uint encoding); + static abstract void VqdmullT2(CodeGenContext context, uint encoding); + static abstract void VqmovnA1(CodeGenContext context, uint encoding); + static abstract void VqmovnT1(CodeGenContext context, uint encoding); + static abstract void VqnegA1(CodeGenContext context, uint encoding); + static abstract void VqnegT1(CodeGenContext context, uint encoding); + static abstract void VqrdmlahA1(CodeGenContext context, uint encoding); + static abstract void VqrdmlahA2(CodeGenContext context, uint encoding); + static abstract void VqrdmlahT1(CodeGenContext context, uint encoding); + static abstract void VqrdmlahT2(CodeGenContext context, uint encoding); + static abstract void VqrdmlshA1(CodeGenContext context, uint encoding); + static abstract void VqrdmlshA2(CodeGenContext context, uint encoding); + static abstract void VqrdmlshT1(CodeGenContext context, uint encoding); + static abstract void VqrdmlshT2(CodeGenContext context, uint encoding); + static abstract void VqrdmulhA1(CodeGenContext context, uint encoding); + static abstract void VqrdmulhA2(CodeGenContext context, uint encoding); + static abstract void VqrdmulhT1(CodeGenContext context, uint encoding); + static abstract void VqrdmulhT2(CodeGenContext context, uint encoding); + static abstract void VqrshlA1(CodeGenContext context, uint encoding); + static abstract void VqrshlT1(CodeGenContext context, uint encoding); + static abstract void VqrshrnA1(CodeGenContext context, uint encoding); + static abstract void VqrshrnT1(CodeGenContext context, uint encoding); + static abstract void VqshlIA1(CodeGenContext context, uint encoding); + static abstract void VqshlIT1(CodeGenContext context, uint encoding); + static abstract void VqshlRA1(CodeGenContext context, uint encoding); + static abstract void VqshlRT1(CodeGenContext context, uint encoding); + static abstract void VqshrnA1(CodeGenContext context, uint encoding); + static abstract void VqshrnT1(CodeGenContext context, uint encoding); + static abstract void VqsubA1(CodeGenContext context, uint encoding); + static abstract void VqsubT1(CodeGenContext context, uint encoding); + static abstract void VraddhnA1(CodeGenContext context, uint encoding); + static abstract void VraddhnT1(CodeGenContext context, uint encoding); + static abstract void VrecpeA1(CodeGenContext context, uint encoding); + static abstract void VrecpeT1(CodeGenContext context, uint encoding); + static abstract void VrecpsA1(CodeGenContext context, uint encoding); + static abstract void VrecpsT1(CodeGenContext context, uint encoding); + static abstract void Vrev16A1(CodeGenContext context, uint encoding); + static abstract void Vrev16T1(CodeGenContext context, uint encoding); + static abstract void Vrev32A1(CodeGenContext context, uint encoding); + static abstract void Vrev32T1(CodeGenContext context, uint encoding); + static abstract void Vrev64A1(CodeGenContext context, uint encoding); + static abstract void Vrev64T1(CodeGenContext context, uint encoding); + static abstract void VrhaddA1(CodeGenContext context, uint encoding); + static abstract void VrhaddT1(CodeGenContext context, uint encoding); + static abstract void VrintaAsimdA1(CodeGenContext context, uint encoding); + static abstract void VrintaAsimdT1(CodeGenContext context, uint encoding); + static abstract void VrintaVfpA1(CodeGenContext context, uint encoding); + static abstract void VrintaVfpT1(CodeGenContext context, uint encoding); + static abstract void VrintmAsimdA1(CodeGenContext context, uint encoding); + static abstract void VrintmAsimdT1(CodeGenContext context, uint encoding); + static abstract void VrintmVfpA1(CodeGenContext context, uint encoding); + static abstract void VrintmVfpT1(CodeGenContext context, uint encoding); + static abstract void VrintnAsimdA1(CodeGenContext context, uint encoding); + static abstract void VrintnAsimdT1(CodeGenContext context, uint encoding); + static abstract void VrintnVfpA1(CodeGenContext context, uint encoding); + static abstract void VrintnVfpT1(CodeGenContext context, uint encoding); + static abstract void VrintpAsimdA1(CodeGenContext context, uint encoding); + static abstract void VrintpAsimdT1(CodeGenContext context, uint encoding); + static abstract void VrintpVfpA1(CodeGenContext context, uint encoding); + static abstract void VrintpVfpT1(CodeGenContext context, uint encoding); + static abstract void VrintrVfpA1(CodeGenContext context, uint encoding); + static abstract void VrintrVfpT1(CodeGenContext context, uint encoding); + static abstract void VrintxAsimdA1(CodeGenContext context, uint encoding); + static abstract void VrintxAsimdT1(CodeGenContext context, uint encoding); + static abstract void VrintxVfpA1(CodeGenContext context, uint encoding); + static abstract void VrintxVfpT1(CodeGenContext context, uint encoding); + static abstract void VrintzAsimdA1(CodeGenContext context, uint encoding); + static abstract void VrintzAsimdT1(CodeGenContext context, uint encoding); + static abstract void VrintzVfpA1(CodeGenContext context, uint encoding); + static abstract void VrintzVfpT1(CodeGenContext context, uint encoding); + static abstract void VrshlA1(CodeGenContext context, uint encoding); + static abstract void VrshlT1(CodeGenContext context, uint encoding); + static abstract void VrshrA1(CodeGenContext context, uint encoding); + static abstract void VrshrT1(CodeGenContext context, uint encoding); + static abstract void VrshrnA1(CodeGenContext context, uint encoding); + static abstract void VrshrnT1(CodeGenContext context, uint encoding); + static abstract void VrsqrteA1(CodeGenContext context, uint encoding); + static abstract void VrsqrteT1(CodeGenContext context, uint encoding); + static abstract void VrsqrtsA1(CodeGenContext context, uint encoding); + static abstract void VrsqrtsT1(CodeGenContext context, uint encoding); + static abstract void VrsraA1(CodeGenContext context, uint encoding); + static abstract void VrsraT1(CodeGenContext context, uint encoding); + static abstract void VrsubhnA1(CodeGenContext context, uint encoding); + static abstract void VrsubhnT1(CodeGenContext context, uint encoding); + static abstract void VsdotA1(CodeGenContext context, uint encoding); + static abstract void VsdotT1(CodeGenContext context, uint encoding); + static abstract void VsdotSA1(CodeGenContext context, uint encoding); + static abstract void VsdotST1(CodeGenContext context, uint encoding); + static abstract void VselA1(CodeGenContext context, uint encoding); + static abstract void VselT1(CodeGenContext context, uint encoding); + static abstract void VshllA1(CodeGenContext context, uint encoding); + static abstract void VshllA2(CodeGenContext context, uint encoding); + static abstract void VshllT1(CodeGenContext context, uint encoding); + static abstract void VshllT2(CodeGenContext context, uint encoding); + static abstract void VshlIA1(CodeGenContext context, uint encoding); + static abstract void VshlIT1(CodeGenContext context, uint encoding); + static abstract void VshlRA1(CodeGenContext context, uint encoding); + static abstract void VshlRT1(CodeGenContext context, uint encoding); + static abstract void VshrA1(CodeGenContext context, uint encoding); + static abstract void VshrT1(CodeGenContext context, uint encoding); + static abstract void VshrnA1(CodeGenContext context, uint encoding); + static abstract void VshrnT1(CodeGenContext context, uint encoding); + static abstract void VsliA1(CodeGenContext context, uint encoding); + static abstract void VsliT1(CodeGenContext context, uint encoding); + static abstract void VsmmlaA1(CodeGenContext context, uint encoding); + static abstract void VsmmlaT1(CodeGenContext context, uint encoding); + static abstract void VsqrtA1(CodeGenContext context, uint encoding); + static abstract void VsqrtT1(CodeGenContext context, uint encoding); + static abstract void VsraA1(CodeGenContext context, uint encoding); + static abstract void VsraT1(CodeGenContext context, uint encoding); + static abstract void VsriA1(CodeGenContext context, uint encoding); + static abstract void VsriT1(CodeGenContext context, uint encoding); + static abstract void Vst11A1(CodeGenContext context, uint encoding); + static abstract void Vst11A2(CodeGenContext context, uint encoding); + static abstract void Vst11A3(CodeGenContext context, uint encoding); + static abstract void Vst11T1(CodeGenContext context, uint encoding); + static abstract void Vst11T2(CodeGenContext context, uint encoding); + static abstract void Vst11T3(CodeGenContext context, uint encoding); + static abstract void Vst1MA1(CodeGenContext context, uint encoding); + static abstract void Vst1MA2(CodeGenContext context, uint encoding); + static abstract void Vst1MA3(CodeGenContext context, uint encoding); + static abstract void Vst1MA4(CodeGenContext context, uint encoding); + static abstract void Vst1MT1(CodeGenContext context, uint encoding); + static abstract void Vst1MT2(CodeGenContext context, uint encoding); + static abstract void Vst1MT3(CodeGenContext context, uint encoding); + static abstract void Vst1MT4(CodeGenContext context, uint encoding); + static abstract void Vst21A1(CodeGenContext context, uint encoding); + static abstract void Vst21A2(CodeGenContext context, uint encoding); + static abstract void Vst21A3(CodeGenContext context, uint encoding); + static abstract void Vst21T1(CodeGenContext context, uint encoding); + static abstract void Vst21T2(CodeGenContext context, uint encoding); + static abstract void Vst21T3(CodeGenContext context, uint encoding); + static abstract void Vst2MA1(CodeGenContext context, uint encoding); + static abstract void Vst2MA2(CodeGenContext context, uint encoding); + static abstract void Vst2MT1(CodeGenContext context, uint encoding); + static abstract void Vst2MT2(CodeGenContext context, uint encoding); + static abstract void Vst31A1(CodeGenContext context, uint encoding); + static abstract void Vst31A2(CodeGenContext context, uint encoding); + static abstract void Vst31A3(CodeGenContext context, uint encoding); + static abstract void Vst31T1(CodeGenContext context, uint encoding); + static abstract void Vst31T2(CodeGenContext context, uint encoding); + static abstract void Vst31T3(CodeGenContext context, uint encoding); + static abstract void Vst3MA1(CodeGenContext context, uint encoding); + static abstract void Vst3MT1(CodeGenContext context, uint encoding); + static abstract void Vst41A1(CodeGenContext context, uint encoding); + static abstract void Vst41A2(CodeGenContext context, uint encoding); + static abstract void Vst41A3(CodeGenContext context, uint encoding); + static abstract void Vst41T1(CodeGenContext context, uint encoding); + static abstract void Vst41T2(CodeGenContext context, uint encoding); + static abstract void Vst41T3(CodeGenContext context, uint encoding); + static abstract void Vst4MA1(CodeGenContext context, uint encoding); + static abstract void Vst4MT1(CodeGenContext context, uint encoding); + static abstract void VstmA1(CodeGenContext context, uint encoding); + static abstract void VstmA2(CodeGenContext context, uint encoding); + static abstract void VstmT1(CodeGenContext context, uint encoding); + static abstract void VstmT2(CodeGenContext context, uint encoding); + static abstract void VstrA1(CodeGenContext context, uint encoding); + static abstract void VstrT1(CodeGenContext context, uint encoding); + static abstract void VsubhnA1(CodeGenContext context, uint encoding); + static abstract void VsubhnT1(CodeGenContext context, uint encoding); + static abstract void VsublA1(CodeGenContext context, uint encoding); + static abstract void VsublT1(CodeGenContext context, uint encoding); + static abstract void VsubwA1(CodeGenContext context, uint encoding); + static abstract void VsubwT1(CodeGenContext context, uint encoding); + static abstract void VsubFA1(CodeGenContext context, uint encoding); + static abstract void VsubFA2(CodeGenContext context, uint encoding); + static abstract void VsubFT1(CodeGenContext context, uint encoding); + static abstract void VsubFT2(CodeGenContext context, uint encoding); + static abstract void VsubIA1(CodeGenContext context, uint encoding); + static abstract void VsubIT1(CodeGenContext context, uint encoding); + static abstract void VsudotSA1(CodeGenContext context, uint encoding); + static abstract void VsudotST1(CodeGenContext context, uint encoding); + static abstract void VswpA1(CodeGenContext context, uint encoding); + static abstract void VswpT1(CodeGenContext context, uint encoding); + static abstract void VtblA1(CodeGenContext context, uint encoding); + static abstract void VtblT1(CodeGenContext context, uint encoding); + static abstract void VtrnA1(CodeGenContext context, uint encoding); + static abstract void VtrnT1(CodeGenContext context, uint encoding); + static abstract void VtstA1(CodeGenContext context, uint encoding); + static abstract void VtstT1(CodeGenContext context, uint encoding); + static abstract void VudotA1(CodeGenContext context, uint encoding); + static abstract void VudotT1(CodeGenContext context, uint encoding); + static abstract void VudotSA1(CodeGenContext context, uint encoding); + static abstract void VudotST1(CodeGenContext context, uint encoding); + static abstract void VummlaA1(CodeGenContext context, uint encoding); + static abstract void VummlaT1(CodeGenContext context, uint encoding); + static abstract void VusdotA1(CodeGenContext context, uint encoding); + static abstract void VusdotT1(CodeGenContext context, uint encoding); + static abstract void VusdotSA1(CodeGenContext context, uint encoding); + static abstract void VusdotST1(CodeGenContext context, uint encoding); + static abstract void VusmmlaA1(CodeGenContext context, uint encoding); + static abstract void VusmmlaT1(CodeGenContext context, uint encoding); + static abstract void VuzpA1(CodeGenContext context, uint encoding); + static abstract void VuzpT1(CodeGenContext context, uint encoding); + static abstract void VzipA1(CodeGenContext context, uint encoding); + static abstract void VzipT1(CodeGenContext context, uint encoding); + static abstract void WfeA1(CodeGenContext context, uint encoding); + static abstract void WfeT1(CodeGenContext context, uint encoding); + static abstract void WfeT2(CodeGenContext context, uint encoding); + static abstract void WfiA1(CodeGenContext context, uint encoding); + static abstract void WfiT1(CodeGenContext context, uint encoding); + static abstract void WfiT2(CodeGenContext context, uint encoding); + static abstract void YieldA1(CodeGenContext context, uint encoding); + static abstract void YieldT1(CodeGenContext context, uint encoding); + static abstract void YieldT2(CodeGenContext context, uint encoding); + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/ImmUtils.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/ImmUtils.cs new file mode 100644 index 000000000..516845fc9 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/ImmUtils.cs @@ -0,0 +1,137 @@ +using System.Numerics; + +namespace Ryujinx.Cpu.LightningJit.Arm32 +{ + static class ImmUtils + { + public static uint ExpandImm(uint imm) + { + return BitOperations.RotateRight((byte)imm, (int)(imm >> 8) * 2); + } + + public static bool ExpandedImmRotated(uint imm) + { + return (imm >> 8) != 0; + } + + public static uint ExpandImm(uint imm8, uint imm3, uint i) + { + uint imm = CombineImmU12(imm8, imm3, i); + + if (imm >> 10 == 0) + { + return ((imm >> 8) & 3) switch + { + 0 => (byte)imm, + 1 => (byte)imm * 0x00010001u, + 2 => (byte)imm * 0x01000100u, + 3 => (byte)imm * 0x01010101u, + _ => 0, + }; + } + else + { + return BitOperations.RotateRight(0x80u | (byte)imm, (int)(imm >> 7)); + } + } + + public static bool ExpandedImmRotated(uint imm8, uint imm3, uint i) + { + uint imm = CombineImmU12(imm8, imm3, i); + + return (imm >> 7) != 0; + } + + public static uint CombineImmU5(uint imm2, uint imm3) + { + return imm2 | (imm3 << 2); + } + + public static uint CombineImmU5IImm4(uint i, uint imm4) + { + return i | (imm4 << 1); + } + + public static uint CombineImmU8(uint imm4l, uint imm4h) + { + return imm4l | (imm4h << 4); + } + + public static uint CombineImmU8(uint imm4, uint imm3, uint i) + { + return imm4 | (imm3 << 4) | (i << 7); + } + + public static uint CombineImmU12(uint imm8, uint imm3, uint i) + { + return imm8 | (imm3 << 8) | (i << 11); + } + + public static uint CombineImmU16(uint imm12, uint imm4) + { + return imm12 | (imm4 << 12); + } + + public static uint CombineImmU16(uint imm8, uint imm3, uint i, uint imm4) + { + return imm8 | (imm3 << 8) | (i << 11) | (imm4 << 12); + } + + public static int CombineSImm20Times2(uint imm11, uint imm6, uint j1, uint j2, uint s) + { + int imm32 = (int)(imm11 | (imm6 << 11) | (j1 << 17) | (j2 << 18) | (s << 19)); + + return (imm32 << 13) >> 12; + } + + public static int CombineSImm24Times2(uint imm11, uint imm10, uint j1, uint j2, uint s) + { + uint i1 = j1 ^ s ^ 1; + uint i2 = j2 ^ s ^ 1; + + int imm32 = (int)(imm11 | (imm10 << 11) | (i2 << 21) | (i1 << 22) | (s << 23)); + + return (imm32 << 8) >> 7; + } + + public static int CombineSImm24Times4(uint imm10L, uint imm10H, uint j1, uint j2, uint s) + { + uint i1 = j1 ^ s ^ 1; + uint i2 = j2 ^ s ^ 1; + + int imm32 = (int)(imm10L | (imm10H << 10) | (i2 << 20) | (i1 << 21) | (s << 22)); + + return (imm32 << 9) >> 7; + } + + public static uint CombineRegisterList(uint registerList, uint m) + { + return registerList | (m << 14); + } + + public static uint CombineRegisterList(uint registerList, uint m, uint p) + { + return registerList | (m << 14) | (p << 15); + } + + public static int ExtractSImm24Times4(uint encoding) + { + return (int)(encoding << 8) >> 6; + } + + public static int ExtractT16UImm5Times2(uint encoding) + { + return (int)(encoding >> 18) & 0x3e; + } + + public static int ExtractT16SImm8Times2(uint encoding) + { + return (int)(encoding << 24) >> 23; + } + + public static int ExtractT16SImm11Times2(uint encoding) + { + return (int)(encoding << 21) >> 20; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/InstDecoders.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/InstDecoders.cs new file mode 100644 index 000000000..41b105e4a --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/InstDecoders.cs @@ -0,0 +1,2927 @@ +namespace Ryujinx.Cpu.LightningJit.Arm32 +{ + readonly struct InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12 + { + private readonly uint _value; + public InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12(uint value) => _value = value; + public readonly uint Imm12 => (_value >> 0) & 0xFFF; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint S => (_value >> 20) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 + { + private readonly uint _value; + public InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Imm3 => (_value >> 12) & 0x7; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint S => (_value >> 20) & 0x1; + public readonly uint I => (_value >> 26) & 0x1; + } + + readonly struct InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 + { + private readonly uint _value; + public InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Stype => (_value >> 5) & 0x3; + public readonly uint Imm5 => (_value >> 7) & 0x1F; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint S => (_value >> 20) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRmb19w3Rdnb16w3 + { + private readonly uint _value; + public InstRmb19w3Rdnb16w3(uint value) => _value = value; + public readonly uint Rdn => (_value >> 16) & 0x7; + public readonly uint Rm => (_value >> 19) & 0x7; + } + + readonly struct InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 + { + private readonly uint _value; + public InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Stype => (_value >> 4) & 0x3; + public readonly uint Imm2 => (_value >> 6) & 0x3; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Imm3 => (_value >> 12) & 0x7; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint S => (_value >> 20) & 0x1; + } + + readonly struct InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 + { + private readonly uint _value; + public InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Stype => (_value >> 5) & 0x3; + public readonly uint Rs => (_value >> 8) & 0xF; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint S => (_value >> 20) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstImm3b22w3Rnb19w3Rdb16w3 + { + private readonly uint _value; + public InstImm3b22w3Rnb19w3Rdb16w3(uint value) => _value = value; + public readonly uint Rd => (_value >> 16) & 0x7; + public readonly uint Rn => (_value >> 19) & 0x7; + public readonly uint Imm3 => (_value >> 22) & 0x7; + } + + readonly struct InstRdnb24w3Imm8b16w8 + { + private readonly uint _value; + public InstRdnb24w3Imm8b16w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 16) & 0xFF; + public readonly uint Rdn => (_value >> 24) & 0x7; + } + + readonly struct InstIb26w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 + { + private readonly uint _value; + public InstIb26w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Imm3 => (_value >> 12) & 0x7; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint I => (_value >> 26) & 0x1; + } + + readonly struct InstRmb22w3Rnb19w3Rdb16w3 + { + private readonly uint _value; + public InstRmb22w3Rnb19w3Rdb16w3(uint value) => _value = value; + public readonly uint Rd => (_value >> 16) & 0x7; + public readonly uint Rn => (_value >> 19) & 0x7; + public readonly uint Rm => (_value >> 22) & 0x7; + } + + readonly struct InstDnb23w1Rmb19w4Rdnb16w3 + { + private readonly uint _value; + public InstDnb23w1Rmb19w4Rdnb16w3(uint value) => _value = value; + public readonly uint Rdn => (_value >> 16) & 0x7; + public readonly uint Rm => (_value >> 19) & 0xF; + public readonly uint Dn => (_value >> 23) & 0x1; + } + + readonly struct InstCondb28w4Sb20w1Rdb12w4Imm12b0w12 + { + private readonly uint _value; + public InstCondb28w4Sb20w1Rdb12w4Imm12b0w12(uint value) => _value = value; + public readonly uint Imm12 => (_value >> 0) & 0xFFF; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint S => (_value >> 20) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRdb24w3Imm8b16w8 + { + private readonly uint _value; + public InstRdb24w3Imm8b16w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 16) & 0xFF; + public readonly uint Rd => (_value >> 24) & 0x7; + } + + readonly struct InstImm7b16w7 + { + private readonly uint _value; + public InstImm7b16w7(uint value) => _value = value; + public readonly uint Imm7 => (_value >> 16) & 0x7F; + } + + readonly struct InstIb26w1Sb20w1Imm3b12w3Rdb8w4Imm8b0w8 + { + private readonly uint _value; + public InstIb26w1Sb20w1Imm3b12w3Rdb8w4Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Imm3 => (_value >> 12) & 0x7; + public readonly uint S => (_value >> 20) & 0x1; + public readonly uint I => (_value >> 26) & 0x1; + } + + readonly struct InstIb26w1Imm3b12w3Rdb8w4Imm8b0w8 + { + private readonly uint _value; + public InstIb26w1Imm3b12w3Rdb8w4Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Imm3 => (_value >> 12) & 0x7; + public readonly uint I => (_value >> 26) & 0x1; + } + + readonly struct InstCondb28w4Sb20w1Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 + { + private readonly uint _value; + public InstCondb28w4Sb20w1Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Stype => (_value >> 5) & 0x3; + public readonly uint Imm5 => (_value >> 7) & 0x1F; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint S => (_value >> 20) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstDmb23w1Rdmb16w3 + { + private readonly uint _value; + public InstDmb23w1Rdmb16w3(uint value) => _value = value; + public readonly uint Rdm => (_value >> 16) & 0x7; + public readonly uint Dm => (_value >> 23) & 0x1; + } + + readonly struct InstRmb19w4 + { + private readonly uint _value; + public InstRmb19w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 19) & 0xF; + } + + readonly struct InstSb20w1Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 + { + private readonly uint _value; + public InstSb20w1Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Stype => (_value >> 4) & 0x3; + public readonly uint Imm2 => (_value >> 6) & 0x3; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Imm3 => (_value >> 12) & 0x7; + public readonly uint S => (_value >> 20) & 0x1; + } + + readonly struct InstCondb28w4Rdb12w4Imm12b0w12 + { + private readonly uint _value; + public InstCondb28w4Rdb12w4Imm12b0w12(uint value) => _value = value; + public readonly uint Imm12 => (_value >> 0) & 0xFFF; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Size => (_value >> 18) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstCondb28w4Imm24b0w24 + { + private readonly uint _value; + public InstCondb28w4Imm24b0w24(uint value) => _value = value; + public readonly uint Imm24 => (_value >> 0) & 0xFFFFFF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstCondb24w4Imm8b16w8 + { + private readonly uint _value; + public InstCondb24w4Imm8b16w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 16) & 0xFF; + public readonly uint Cond => (_value >> 24) & 0xF; + } + + readonly struct InstImm11b16w11 + { + private readonly uint _value; + public InstImm11b16w11(uint value) => _value = value; + public readonly uint Imm11 => (_value >> 16) & 0x7FF; + } + + readonly struct InstSb26w1Condb22w4Imm6b16w6J1b13w1J2b11w1Imm11b0w11 + { + private readonly uint _value; + public InstSb26w1Condb22w4Imm6b16w6J1b13w1J2b11w1Imm11b0w11(uint value) => _value = value; + public readonly uint Imm11 => (_value >> 0) & 0x7FF; + public readonly uint J2 => (_value >> 11) & 0x1; + public readonly uint J1 => (_value >> 13) & 0x1; + public readonly uint Imm6 => (_value >> 16) & 0x3F; + public readonly uint Cond => (_value >> 22) & 0xF; + public readonly uint S => (_value >> 26) & 0x1; + } + + readonly struct InstSb26w1Imm10b16w10J1b13w1J2b11w1Imm11b0w11 + { + private readonly uint _value; + public InstSb26w1Imm10b16w10J1b13w1J2b11w1Imm11b0w11(uint value) => _value = value; + public readonly uint Imm11 => (_value >> 0) & 0x7FF; + public readonly uint J2 => (_value >> 11) & 0x1; + public readonly uint J1 => (_value >> 13) & 0x1; + public readonly uint Imm10 => (_value >> 16) & 0x3FF; + public readonly uint S => (_value >> 26) & 0x1; + } + + readonly struct InstCondb28w4Msbb16w5Rdb12w4Lsbb7w5 + { + private readonly uint _value; + public InstCondb28w4Msbb16w5Rdb12w4Lsbb7w5(uint value) => _value = value; + public readonly uint Lsb => (_value >> 7) & 0x1F; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint Msb => (_value >> 16) & 0x1F; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstImm3b12w3Rdb8w4Imm2b6w2Msbb0w5 + { + private readonly uint _value; + public InstImm3b12w3Rdb8w4Imm2b6w2Msbb0w5(uint value) => _value = value; + public readonly uint Msb => (_value >> 0) & 0x1F; + public readonly uint Imm2 => (_value >> 6) & 0x3; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Imm3 => (_value >> 12) & 0x7; + } + + readonly struct InstCondb28w4Msbb16w5Rdb12w4Lsbb7w5Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4Msbb16w5Rdb12w4Lsbb7w5Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint Lsb => (_value >> 7) & 0x1F; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint Msb => (_value >> 16) & 0x1F; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb16w4Imm3b12w3Rdb8w4Imm2b6w2Msbb0w5 + { + private readonly uint _value; + public InstRnb16w4Imm3b12w3Rdb8w4Imm2b6w2Msbb0w5(uint value) => _value = value; + public readonly uint Msb => (_value >> 0) & 0x1F; + public readonly uint Imm2 => (_value >> 6) & 0x3; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Imm3 => (_value >> 12) & 0x7; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Imm12b8w12Imm4b0w4 + { + private readonly uint _value; + public InstCondb28w4Imm12b8w12Imm4b0w4(uint value) => _value = value; + public readonly uint Imm4 => (_value >> 0) & 0xF; + public readonly uint Imm12 => (_value >> 8) & 0xFFF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstImm8b16w8 + { + private readonly uint _value; + public InstImm8b16w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 16) & 0xFF; + } + + readonly struct InstCondb28w4Rmb0w4 + { + private readonly uint _value; + public InstCondb28w4Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstHb24w1Imm24b0w24 + { + private readonly uint _value; + public InstHb24w1Imm24b0w24(uint value) => _value = value; + public readonly uint Imm24 => (_value >> 0) & 0xFFFFFF; + public readonly uint H => (_value >> 24) & 0x1; + } + + readonly struct InstSb26w1Imm10hb16w10J1b13w1J2b11w1Imm10lb1w10Hb0w1 + { + private readonly uint _value; + public InstSb26w1Imm10hb16w10J1b13w1J2b11w1Imm10lb1w10Hb0w1(uint value) => _value = value; + public readonly uint H => (_value >> 0) & 0x1; + public readonly uint Imm10l => (_value >> 1) & 0x3FF; + public readonly uint J2 => (_value >> 11) & 0x1; + public readonly uint J1 => (_value >> 13) & 0x1; + public readonly uint Imm10h => (_value >> 16) & 0x3FF; + public readonly uint S => (_value >> 26) & 0x1; + } + + readonly struct InstRmb16w4 + { + private readonly uint _value; + public InstRmb16w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 16) & 0xF; + } + + readonly struct InstOpb27w1Ib25w1Imm5b19w5Rnb16w3 + { + private readonly uint _value; + public InstOpb27w1Ib25w1Imm5b19w5Rnb16w3(uint value) => _value = value; + public readonly uint Rn => (_value >> 16) & 0x7; + public readonly uint Imm5 => (_value >> 19) & 0x1F; + public readonly uint I => (_value >> 25) & 0x1; + public readonly uint Op => (_value >> 27) & 0x1; + } + + readonly struct InstCondb28w4 + { + private readonly uint _value; + public InstCondb28w4(uint value) => _value = value; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstCondb28w4Rdb12w4Rmb0w4 + { + private readonly uint _value; + public InstCondb28w4Rdb12w4Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb16w4Rdb8w4Rmb0w4 + { + private readonly uint _value; + public InstRnb16w4Rdb8w4Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Rnb16w4Imm12b0w12 + { + private readonly uint _value; + public InstCondb28w4Rnb16w4Imm12b0w12(uint value) => _value = value; + public readonly uint Imm12 => (_value >> 0) & 0xFFF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstIb26w1Rnb16w4Imm3b12w3Imm8b0w8 + { + private readonly uint _value; + public InstIb26w1Rnb16w4Imm3b12w3Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint Imm3 => (_value >> 12) & 0x7; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint I => (_value >> 26) & 0x1; + } + + readonly struct InstCondb28w4Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4 + { + private readonly uint _value; + public InstCondb28w4Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Stype => (_value >> 5) & 0x3; + public readonly uint Imm5 => (_value >> 7) & 0x1F; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRmb19w3Rnb16w3 + { + private readonly uint _value; + public InstRmb19w3Rnb16w3(uint value) => _value = value; + public readonly uint Rn => (_value >> 16) & 0x7; + public readonly uint Rm => (_value >> 19) & 0x7; + } + + readonly struct InstRnb16w4Imm3b12w3Imm2b6w2Stypeb4w2Rmb0w4 + { + private readonly uint _value; + public InstRnb16w4Imm3b12w3Imm2b6w2Stypeb4w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Stype => (_value >> 4) & 0x3; + public readonly uint Imm2 => (_value >> 6) & 0x3; + public readonly uint Imm3 => (_value >> 12) & 0x7; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Rnb16w4Rsb8w4Stypeb5w2Rmb0w4 + { + private readonly uint _value; + public InstCondb28w4Rnb16w4Rsb8w4Stypeb5w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Stype => (_value >> 5) & 0x3; + public readonly uint Rs => (_value >> 8) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb24w3Imm8b16w8 + { + private readonly uint _value; + public InstRnb24w3Imm8b16w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 16) & 0xFF; + public readonly uint Rn => (_value >> 24) & 0x7; + } + + readonly struct InstNb23w1Rmb19w4Rnb16w3 + { + private readonly uint _value; + public InstNb23w1Rmb19w4Rnb16w3(uint value) => _value = value; + public readonly uint Rn => (_value >> 16) & 0x7; + public readonly uint Rm => (_value >> 19) & 0xF; + public readonly uint N => (_value >> 23) & 0x1; + } + + readonly struct InstImodb18w2Mb17w1Ab8w1Ib7w1Fb6w1Modeb0w5 + { + private readonly uint _value; + public InstImodb18w2Mb17w1Ab8w1Ib7w1Fb6w1Modeb0w5(uint value) => _value = value; + public readonly uint Mode => (_value >> 0) & 0x1F; + public readonly uint F => (_value >> 6) & 0x1; + public readonly uint I => (_value >> 7) & 0x1; + public readonly uint A => (_value >> 8) & 0x1; + public readonly uint M => (_value >> 17) & 0x1; + public readonly uint Imod => (_value >> 18) & 0x3; + } + + readonly struct InstImb20w1Ab18w1Ib17w1Fb16w1 + { + private readonly uint _value; + public InstImb20w1Ab18w1Ib17w1Fb16w1(uint value) => _value = value; + public readonly uint F => (_value >> 16) & 0x1; + public readonly uint I => (_value >> 17) & 0x1; + public readonly uint A => (_value >> 18) & 0x1; + public readonly uint Im => (_value >> 20) & 0x1; + } + + readonly struct InstImodb9w2Mb8w1Ab7w1Ib6w1Fb5w1Modeb0w5 + { + private readonly uint _value; + public InstImodb9w2Mb8w1Ab7w1Ib6w1Fb5w1Modeb0w5(uint value) => _value = value; + public readonly uint Mode => (_value >> 0) & 0x1F; + public readonly uint F => (_value >> 5) & 0x1; + public readonly uint I => (_value >> 6) & 0x1; + public readonly uint A => (_value >> 7) & 0x1; + public readonly uint M => (_value >> 8) & 0x1; + public readonly uint Imod => (_value >> 9) & 0x3; + } + + readonly struct InstCondb28w4Szb21w2Rnb16w4Rdb12w4Rmb0w4 + { + private readonly uint _value; + public InstCondb28w4Szb21w2Rnb16w4Rdb12w4Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint Sz => (_value >> 21) & 0x3; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb16w4Rdb8w4Szb4w2Rmb0w4 + { + private readonly uint _value; + public InstRnb16w4Rdb8w4Szb4w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Sz => (_value >> 4) & 0x3; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Optionb0w4 + { + private readonly uint _value; + public InstCondb28w4Optionb0w4(uint value) => _value = value; + public readonly uint Option => (_value >> 0) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstOptionb0w4 + { + private readonly uint _value; + public InstOptionb0w4(uint value) => _value = value; + public readonly uint Option => (_value >> 0) & 0xF; + } + + readonly struct InstCondb28w4Pb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7 + { + private readonly uint _value; + public InstCondb28w4Pb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7(uint value) => _value = value; + public readonly uint Imm871 => (_value >> 1) & 0x7F; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint W => (_value >> 21) & 0x1; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint P => (_value >> 24) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstPb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7 + { + private readonly uint _value; + public InstPb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7(uint value) => _value = value; + public readonly uint Imm871 => (_value >> 1) & 0x7F; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint W => (_value >> 21) & 0x1; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint P => (_value >> 24) & 0x1; + } + + readonly struct InstImm6b16w6 + { + private readonly uint _value; + public InstImm6b16w6(uint value) => _value = value; + public readonly uint Imm6 => (_value >> 16) & 0x3F; + } + + readonly struct InstFirstcondb20w4Maskb16w4 + { + private readonly uint _value; + public InstFirstcondb20w4Maskb16w4(uint value) => _value = value; + public readonly uint Mask => (_value >> 16) & 0xF; + public readonly uint Firstcond => (_value >> 20) & 0xF; + } + + readonly struct InstCondb28w4Rnb16w4Rtb12w4 + { + private readonly uint _value; + public InstCondb28w4Rnb16w4Rtb12w4(uint value) => _value = value; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb16w4Rtb12w4 + { + private readonly uint _value; + public InstRnb16w4Rtb12w4(uint value) => _value = value; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstRnb16w4Rtb12w4Rt2b8w4 + { + private readonly uint _value; + public InstRnb16w4Rtb12w4Rt2b8w4(uint value) => _value = value; + public readonly uint Rt2 => (_value >> 8) & 0xF; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Imm8b0w8 + { + private readonly uint _value; + public InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint W => (_value >> 21) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint P => (_value >> 24) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstPb24w1Ub23w1Wb21w1Rnb16w4Imm8b0w8 + { + private readonly uint _value; + public InstPb24w1Ub23w1Wb21w1Rnb16w4Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint W => (_value >> 21) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint P => (_value >> 24) & 0x1; + } + + readonly struct InstCondb28w4Pb24w1Ub23w1Wb21w1Imm8b0w8 + { + private readonly uint _value; + public InstCondb28w4Pb24w1Ub23w1Wb21w1Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint W => (_value >> 21) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint P => (_value >> 24) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstPb24w1Ub23w1Wb21w1Imm8b0w8 + { + private readonly uint _value; + public InstPb24w1Ub23w1Wb21w1Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint W => (_value >> 21) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint P => (_value >> 24) & 0x1; + } + + readonly struct InstCondb28w4Wb21w1Rnb16w4RegisterListb0w16 + { + private readonly uint _value; + public InstCondb28w4Wb21w1Rnb16w4RegisterListb0w16(uint value) => _value = value; + public readonly uint RegisterList => (_value >> 0) & 0xFFFF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint W => (_value >> 21) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb24w3RegisterListb16w8 + { + private readonly uint _value; + public InstRnb24w3RegisterListb16w8(uint value) => _value = value; + public readonly uint RegisterList => (_value >> 16) & 0xFF; + public readonly uint Rn => (_value >> 24) & 0x7; + } + + readonly struct InstWb21w1Rnb16w4Pb15w1Mb14w1RegisterListb0w14 + { + private readonly uint _value; + public InstWb21w1Rnb16w4Pb15w1Mb14w1RegisterListb0w14(uint value) => _value = value; + public readonly uint RegisterList => (_value >> 0) & 0x3FFF; + public readonly uint M => (_value >> 14) & 0x1; + public readonly uint P => (_value >> 15) & 0x1; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint W => (_value >> 21) & 0x1; + } + + readonly struct InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm12b0w12 + { + private readonly uint _value; + public InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm12b0w12(uint value) => _value = value; + public readonly uint Imm12 => (_value >> 0) & 0xFFF; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4 + { + private readonly uint _value; + public InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Stype => (_value >> 5) & 0x3; + public readonly uint Imm5 => (_value >> 7) & 0x1F; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb16w4Rtb12w4Imm8b0w8 + { + private readonly uint _value; + public InstRnb16w4Rtb12w4Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm12b0w12 + { + private readonly uint _value; + public InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm12b0w12(uint value) => _value = value; + public readonly uint Imm12 => (_value >> 0) & 0xFFF; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint W => (_value >> 21) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint P => (_value >> 24) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstImm5b22w5Rnb19w3Rtb16w3 + { + private readonly uint _value; + public InstImm5b22w5Rnb19w3Rtb16w3(uint value) => _value = value; + public readonly uint Rt => (_value >> 16) & 0x7; + public readonly uint Rn => (_value >> 19) & 0x7; + public readonly uint Imm5 => (_value >> 22) & 0x1F; + } + + readonly struct InstRnb16w4Rtb12w4Imm12b0w12 + { + private readonly uint _value; + public InstRnb16w4Rtb12w4Imm12b0w12(uint value) => _value = value; + public readonly uint Imm12 => (_value >> 0) & 0xFFF; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstRnb16w4Rtb12w4Pb10w1Ub9w1Wb8w1Imm8b0w8 + { + private readonly uint _value; + public InstRnb16w4Rtb12w4Pb10w1Ub9w1Wb8w1Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint W => (_value >> 8) & 0x1; + public readonly uint U => (_value >> 9) & 0x1; + public readonly uint P => (_value >> 10) & 0x1; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Pb24w1Ub23w1Wb21w1Rtb12w4Imm12b0w12 + { + private readonly uint _value; + public InstCondb28w4Pb24w1Ub23w1Wb21w1Rtb12w4Imm12b0w12(uint value) => _value = value; + public readonly uint Imm12 => (_value >> 0) & 0xFFF; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint W => (_value >> 21) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint P => (_value >> 24) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstUb23w1Rtb12w4Imm12b0w12 + { + private readonly uint _value; + public InstUb23w1Rtb12w4Imm12b0w12(uint value) => _value = value; + public readonly uint Imm12 => (_value >> 0) & 0xFFF; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint U => (_value >> 23) & 0x1; + } + + readonly struct InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4 + { + private readonly uint _value; + public InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Stype => (_value >> 5) & 0x3; + public readonly uint Imm5 => (_value >> 7) & 0x1F; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint W => (_value >> 21) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint P => (_value >> 24) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRmb22w3Rnb19w3Rtb16w3 + { + private readonly uint _value; + public InstRmb22w3Rnb19w3Rtb16w3(uint value) => _value = value; + public readonly uint Rt => (_value >> 16) & 0x7; + public readonly uint Rn => (_value >> 19) & 0x7; + public readonly uint Rm => (_value >> 22) & 0x7; + } + + readonly struct InstRnb16w4Rtb12w4Imm2b4w2Rmb0w4 + { + private readonly uint _value; + public InstRnb16w4Rtb12w4Imm2b4w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Imm2 => (_value >> 4) & 0x3; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 + { + private readonly uint _value; + public InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4(uint value) => _value = value; + public readonly uint Imm4l => (_value >> 0) & 0xF; + public readonly uint Imm4h => (_value >> 8) & 0xF; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint W => (_value >> 21) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint P => (_value >> 24) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstPb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rt2b8w4Imm8b0w8 + { + private readonly uint _value; + public InstPb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rt2b8w4Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint Rt2 => (_value >> 8) & 0xF; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint W => (_value >> 21) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint P => (_value >> 24) & 0x1; + } + + readonly struct InstCondb28w4Ub23w1Rtb12w4Imm4hb8w4Imm4lb0w4 + { + private readonly uint _value; + public InstCondb28w4Ub23w1Rtb12w4Imm4hb8w4Imm4lb0w4(uint value) => _value = value; + public readonly uint Imm4l => (_value >> 0) & 0xF; + public readonly uint Imm4h => (_value >> 8) & 0xF; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstPb24w1Ub23w1Wb21w1Rtb12w4Rt2b8w4Imm8b0w8 + { + private readonly uint _value; + public InstPb24w1Ub23w1Wb21w1Rtb12w4Rt2b8w4Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint Rt2 => (_value >> 8) & 0xF; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint W => (_value >> 21) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint P => (_value >> 24) & 0x1; + } + + readonly struct InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rmb0w4 + { + private readonly uint _value; + public InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint W => (_value >> 21) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint P => (_value >> 24) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 + { + private readonly uint _value; + public InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4(uint value) => _value = value; + public readonly uint Imm4l => (_value >> 0) & 0xF; + public readonly uint Imm4h => (_value >> 8) & 0xF; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstCondb28w4Ub23w1Rnb16w4Rtb12w4Rmb0w4 + { + private readonly uint _value; + public InstCondb28w4Ub23w1Rnb16w4Rtb12w4Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstCondb28w4Pb24w1Ub23w1Wb21w1Rtb12w4Imm4hb8w4Imm4lb0w4 + { + private readonly uint _value; + public InstCondb28w4Pb24w1Ub23w1Wb21w1Rtb12w4Imm4hb8w4Imm4lb0w4(uint value) => _value = value; + public readonly uint Imm4l => (_value >> 0) & 0xF; + public readonly uint Imm4h => (_value >> 8) & 0xF; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint W => (_value >> 21) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint P => (_value >> 24) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRtb24w3Imm8b16w8 + { + private readonly uint _value; + public InstRtb24w3Imm8b16w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 16) & 0xFF; + public readonly uint Rt => (_value >> 24) & 0x7; + } + + readonly struct InstCondb28w4Opc1b21w3Crnb16w4Rtb12w4Coproc0b8w1Opc2b5w3Crmb0w4 + { + private readonly uint _value; + public InstCondb28w4Opc1b21w3Crnb16w4Rtb12w4Coproc0b8w1Opc2b5w3Crmb0w4(uint value) => _value = value; + public readonly uint Crm => (_value >> 0) & 0xF; + public readonly uint Opc2 => (_value >> 5) & 0x7; + public readonly uint Coproc0 => (_value >> 8) & 0x1; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Crn => (_value >> 16) & 0xF; + public readonly uint Opc1 => (_value >> 21) & 0x7; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstOpc1b21w3Crnb16w4Rtb12w4Coproc0b8w1Opc2b5w3Crmb0w4 + { + private readonly uint _value; + public InstOpc1b21w3Crnb16w4Rtb12w4Coproc0b8w1Opc2b5w3Crmb0w4(uint value) => _value = value; + public readonly uint Crm => (_value >> 0) & 0xF; + public readonly uint Opc2 => (_value >> 5) & 0x7; + public readonly uint Coproc0 => (_value >> 8) & 0x1; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Crn => (_value >> 16) & 0xF; + public readonly uint Opc1 => (_value >> 21) & 0x7; + } + + readonly struct InstCondb28w4Rt2b16w4Rtb12w4Coproc0b8w1Opc1b4w4Crmb0w4 + { + private readonly uint _value; + public InstCondb28w4Rt2b16w4Rtb12w4Coproc0b8w1Opc1b4w4Crmb0w4(uint value) => _value = value; + public readonly uint Crm => (_value >> 0) & 0xF; + public readonly uint Opc1 => (_value >> 4) & 0xF; + public readonly uint Coproc0 => (_value >> 8) & 0x1; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rt2 => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRt2b16w4Rtb12w4Coproc0b8w1Opc1b4w4Crmb0w4 + { + private readonly uint _value; + public InstRt2b16w4Rtb12w4Coproc0b8w1Opc1b4w4Crmb0w4(uint value) => _value = value; + public readonly uint Crm => (_value >> 0) & 0xF; + public readonly uint Opc1 => (_value >> 4) & 0xF; + public readonly uint Coproc0 => (_value >> 8) & 0x1; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rt2 => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Sb20w1Rdb16w4Rab12w4Rmb8w4Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4Sb20w1Rdb16w4Rab12w4Rmb8w4Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint Rm => (_value >> 8) & 0xF; + public readonly uint Ra => (_value >> 12) & 0xF; + public readonly uint Rd => (_value >> 16) & 0xF; + public readonly uint S => (_value >> 20) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb16w4Rab12w4Rdb8w4Rmb0w4 + { + private readonly uint _value; + public InstRnb16w4Rab12w4Rdb8w4Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Ra => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Rdb16w4Rab12w4Rmb8w4Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4Rdb16w4Rab12w4Rmb8w4Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint Rm => (_value >> 8) & 0xF; + public readonly uint Ra => (_value >> 12) & 0xF; + public readonly uint Rd => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstCondb28w4Imm4b16w4Rdb12w4Imm12b0w12 + { + private readonly uint _value; + public InstCondb28w4Imm4b16w4Rdb12w4Imm12b0w12(uint value) => _value = value; + public readonly uint Imm12 => (_value >> 0) & 0xFFF; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint Imm4 => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstIb26w1Imm4b16w4Imm3b12w3Rdb8w4Imm8b0w8 + { + private readonly uint _value; + public InstIb26w1Imm4b16w4Imm3b12w3Rdb8w4Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Imm3 => (_value >> 12) & 0x7; + public readonly uint Imm4 => (_value >> 16) & 0xF; + public readonly uint I => (_value >> 26) & 0x1; + } + + readonly struct InstDb23w1Rmb19w4Rdb16w3 + { + private readonly uint _value; + public InstDb23w1Rmb19w4Rdb16w3(uint value) => _value = value; + public readonly uint Rd => (_value >> 16) & 0x7; + public readonly uint Rm => (_value >> 19) & 0xF; + public readonly uint D => (_value >> 23) & 0x1; + } + + readonly struct InstOpb27w2Imm5b22w5Rmb19w3Rdb16w3 + { + private readonly uint _value; + public InstOpb27w2Imm5b22w5Rmb19w3Rdb16w3(uint value) => _value = value; + public readonly uint Rd => (_value >> 16) & 0x7; + public readonly uint Rm => (_value >> 19) & 0x7; + public readonly uint Imm5 => (_value >> 22) & 0x1F; + public readonly uint Op => (_value >> 27) & 0x3; + } + + readonly struct InstCondb28w4Sb20w1Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 + { + private readonly uint _value; + public InstCondb28w4Sb20w1Rdb12w4Rsb8w4Stypeb5w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Stype => (_value >> 5) & 0x3; + public readonly uint Rs => (_value >> 8) & 0xF; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint S => (_value >> 20) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRsb19w3Rdmb16w3 + { + private readonly uint _value; + public InstRsb19w3Rdmb16w3(uint value) => _value = value; + public readonly uint Rdm => (_value >> 16) & 0x7; + public readonly uint Rs => (_value >> 19) & 0x7; + } + + readonly struct InstStypeb21w2Sb20w1Rmb16w4Rdb8w4Rsb0w4 + { + private readonly uint _value; + public InstStypeb21w2Sb20w1Rmb16w4Rdb8w4Rsb0w4(uint value) => _value = value; + public readonly uint Rs => (_value >> 0) & 0xF; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Rm => (_value >> 16) & 0xF; + public readonly uint S => (_value >> 20) & 0x1; + public readonly uint Stype => (_value >> 21) & 0x3; + } + + readonly struct InstCondb28w4Rb22w1Rdb12w4 + { + private readonly uint _value; + public InstCondb28w4Rb22w1Rdb12w4(uint value) => _value = value; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint R => (_value >> 22) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRb20w1Rdb8w4 + { + private readonly uint _value; + public InstRb20w1Rdb8w4(uint value) => _value = value; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint R => (_value >> 20) & 0x1; + } + + readonly struct InstCondb28w4Rb22w1M1b16w4Rdb12w4Mb8w1 + { + private readonly uint _value; + public InstCondb28w4Rb22w1M1b16w4Rdb12w4Mb8w1(uint value) => _value = value; + public readonly uint M => (_value >> 8) & 0x1; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint M1 => (_value >> 16) & 0xF; + public readonly uint R => (_value >> 22) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRb20w1M1b16w4Rdb8w4Mb4w1 + { + private readonly uint _value; + public InstRb20w1M1b16w4Rdb8w4Mb4w1(uint value) => _value = value; + public readonly uint M => (_value >> 4) & 0x1; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint M1 => (_value >> 16) & 0xF; + public readonly uint R => (_value >> 20) & 0x1; + } + + readonly struct InstCondb28w4Rb22w1M1b16w4Mb8w1Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4Rb22w1M1b16w4Mb8w1Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 8) & 0x1; + public readonly uint M1 => (_value >> 16) & 0xF; + public readonly uint R => (_value >> 22) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRb20w1Rnb16w4M1b8w4Mb4w1 + { + private readonly uint _value; + public InstRb20w1Rnb16w4M1b8w4Mb4w1(uint value) => _value = value; + public readonly uint M => (_value >> 4) & 0x1; + public readonly uint M1 => (_value >> 8) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint R => (_value >> 20) & 0x1; + } + + readonly struct InstCondb28w4Rb22w1Maskb16w4Imm12b0w12 + { + private readonly uint _value; + public InstCondb28w4Rb22w1Maskb16w4Imm12b0w12(uint value) => _value = value; + public readonly uint Imm12 => (_value >> 0) & 0xFFF; + public readonly uint Mask => (_value >> 16) & 0xF; + public readonly uint R => (_value >> 22) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstCondb28w4Rb22w1Maskb16w4Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4Rb22w1Maskb16w4Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint Mask => (_value >> 16) & 0xF; + public readonly uint R => (_value >> 22) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRb20w1Rnb16w4Maskb8w4 + { + private readonly uint _value; + public InstRb20w1Rnb16w4Maskb8w4(uint value) => _value = value; + public readonly uint Mask => (_value >> 8) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint R => (_value >> 20) & 0x1; + } + + readonly struct InstCondb28w4Sb20w1Rdb16w4Rmb8w4Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4Sb20w1Rdb16w4Rmb8w4Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint Rm => (_value >> 8) & 0xF; + public readonly uint Rd => (_value >> 16) & 0xF; + public readonly uint S => (_value >> 20) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb19w3Rdmb16w3 + { + private readonly uint _value; + public InstRnb19w3Rdmb16w3(uint value) => _value = value; + public readonly uint Rdm => (_value >> 16) & 0x7; + public readonly uint Rn => (_value >> 19) & 0x7; + } + + readonly struct InstRmb19w3Rdb16w3 + { + private readonly uint _value; + public InstRmb19w3Rdb16w3(uint value) => _value = value; + public readonly uint Rd => (_value >> 16) & 0x7; + public readonly uint Rm => (_value >> 19) & 0x7; + } + + readonly struct InstCondb28w4Rnb16w4Rdb12w4Imm5b7w5Tbb6w1Rmb0w4 + { + private readonly uint _value; + public InstCondb28w4Rnb16w4Rdb12w4Imm5b7w5Tbb6w1Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Tb => (_value >> 6) & 0x1; + public readonly uint Imm5 => (_value >> 7) & 0x1F; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb16w4Imm3b12w3Rdb8w4Imm2b6w2Tbb5w1Rmb0w4 + { + private readonly uint _value; + public InstRnb16w4Imm3b12w3Rdb8w4Imm2b6w2Tbb5w1Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Tb => (_value >> 5) & 0x1; + public readonly uint Imm2 => (_value >> 6) & 0x3; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Imm3 => (_value >> 12) & 0x7; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstUb23w1Rb22w1Rnb16w4Imm12b0w12 + { + private readonly uint _value; + public InstUb23w1Rb22w1Rnb16w4Imm12b0w12(uint value) => _value = value; + public readonly uint Imm12 => (_value >> 0) & 0xFFF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint R => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + } + + readonly struct InstWb21w1Rnb16w4Imm12b0w12 + { + private readonly uint _value; + public InstWb21w1Rnb16w4Imm12b0w12(uint value) => _value = value; + public readonly uint Imm12 => (_value >> 0) & 0xFFF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint W => (_value >> 21) & 0x1; + } + + readonly struct InstWb21w1Rnb16w4Imm8b0w8 + { + private readonly uint _value; + public InstWb21w1Rnb16w4Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint W => (_value >> 21) & 0x1; + } + + readonly struct InstUb23w1Imm12b0w12 + { + private readonly uint _value; + public InstUb23w1Imm12b0w12(uint value) => _value = value; + public readonly uint Imm12 => (_value >> 0) & 0xFFF; + public readonly uint U => (_value >> 23) & 0x1; + } + + readonly struct InstUb23w1Rb22w1Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4 + { + private readonly uint _value; + public InstUb23w1Rb22w1Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Stype => (_value >> 5) & 0x3; + public readonly uint Imm5 => (_value >> 7) & 0x1F; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint R => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + } + + readonly struct InstWb21w1Rnb16w4Imm2b4w2Rmb0w4 + { + private readonly uint _value; + public InstWb21w1Rnb16w4Imm2b4w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Imm2 => (_value >> 4) & 0x3; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint W => (_value >> 21) & 0x1; + } + + readonly struct InstUb23w1Rnb16w4Imm12b0w12 + { + private readonly uint _value; + public InstUb23w1Rnb16w4Imm12b0w12(uint value) => _value = value; + public readonly uint Imm12 => (_value >> 0) & 0xFFF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint U => (_value >> 23) & 0x1; + } + + readonly struct InstRnb16w4Imm12b0w12 + { + private readonly uint _value; + public InstRnb16w4Imm12b0w12(uint value) => _value = value; + public readonly uint Imm12 => (_value >> 0) & 0xFFF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstRnb16w4Imm8b0w8 + { + private readonly uint _value; + public InstRnb16w4Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstUb23w1Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4 + { + private readonly uint _value; + public InstUb23w1Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Stype => (_value >> 5) & 0x3; + public readonly uint Imm5 => (_value >> 7) & 0x1F; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint U => (_value >> 23) & 0x1; + } + + readonly struct InstRnb16w4Imm2b4w2Rmb0w4 + { + private readonly uint _value; + public InstRnb16w4Imm2b4w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Imm2 => (_value >> 4) & 0x3; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstPb24w1RegisterListb16w8 + { + private readonly uint _value; + public InstPb24w1RegisterListb16w8(uint value) => _value = value; + public readonly uint RegisterList => (_value >> 16) & 0xFF; + public readonly uint P => (_value >> 24) & 0x1; + } + + readonly struct InstMb24w1RegisterListb16w8 + { + private readonly uint _value; + public InstMb24w1RegisterListb16w8(uint value) => _value = value; + public readonly uint RegisterList => (_value >> 16) & 0xFF; + public readonly uint M => (_value >> 24) & 0x1; + } + + readonly struct InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 + { + private readonly uint _value; + public InstCondb28w4Rnb16w4Rdb12w4Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb19w3Rdb16w3 + { + private readonly uint _value; + public InstRnb19w3Rdb16w3(uint value) => _value = value; + public readonly uint Rd => (_value >> 16) & 0x7; + public readonly uint Rn => (_value >> 19) & 0x7; + } + + readonly struct InstCondb28w4Widthm1b16w5Rdb12w4Lsbb7w5Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4Widthm1b16w5Rdb12w4Lsbb7w5Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint Lsb => (_value >> 7) & 0x1F; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint Widthm1 => (_value >> 16) & 0x1F; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb16w4Imm3b12w3Rdb8w4Imm2b6w2Widthm1b0w5 + { + private readonly uint _value; + public InstRnb16w4Imm3b12w3Rdb8w4Imm2b6w2Widthm1b0w5(uint value) => _value = value; + public readonly uint Widthm1 => (_value >> 0) & 0x1F; + public readonly uint Imm2 => (_value >> 6) & 0x3; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Imm3 => (_value >> 12) & 0x7; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Rdb16w4Rmb8w4Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4Rdb16w4Rmb8w4Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint Rm => (_value >> 8) & 0xF; + public readonly uint Rd => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstEb9w1 + { + private readonly uint _value; + public InstEb9w1(uint value) => _value = value; + public readonly uint E => (_value >> 9) & 0x1; + } + + readonly struct InstEb19w1 + { + private readonly uint _value; + public InstEb19w1(uint value) => _value = value; + public readonly uint E => (_value >> 19) & 0x1; + } + + readonly struct InstImm1b9w1 + { + private readonly uint _value; + public InstImm1b9w1(uint value) => _value = value; + public readonly uint Imm1 => (_value >> 9) & 0x1; + } + + readonly struct InstImm1b19w1 + { + private readonly uint _value; + public InstImm1b19w1(uint value) => _value = value; + public readonly uint Imm1 => (_value >> 19) & 0x1; + } + + readonly struct InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstCondb28w4Rdb16w4Rab12w4Rmb8w4Mb6w1Nb5w1Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4Rdb16w4Rab12w4Rmb8w4Mb6w1Nb5w1Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint N => (_value >> 5) & 0x1; + public readonly uint M => (_value >> 6) & 0x1; + public readonly uint Rm => (_value >> 8) & 0xF; + public readonly uint Ra => (_value >> 12) & 0xF; + public readonly uint Rd => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb16w4Rab12w4Rdb8w4Nb5w1Mb4w1Rmb0w4 + { + private readonly uint _value; + public InstRnb16w4Rab12w4Rdb8w4Nb5w1Mb4w1Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 4) & 0x1; + public readonly uint N => (_value >> 5) & 0x1; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Ra => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Rdb16w4Rab12w4Rmb8w4Mb5w1Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4Rdb16w4Rab12w4Rmb8w4Mb5w1Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Rm => (_value >> 8) & 0xF; + public readonly uint Ra => (_value >> 12) & 0xF; + public readonly uint Rd => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb16w4Rab12w4Rdb8w4Mb4w1Rmb0w4 + { + private readonly uint _value; + public InstRnb16w4Rab12w4Rdb8w4Mb4w1Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 4) & 0x1; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Ra => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Sb20w1Rdhib16w4Rdlob12w4Rmb8w4Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4Sb20w1Rdhib16w4Rdlob12w4Rmb8w4Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint Rm => (_value >> 8) & 0xF; + public readonly uint Rdlo => (_value >> 12) & 0xF; + public readonly uint Rdhi => (_value >> 16) & 0xF; + public readonly uint S => (_value >> 20) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb16w4Rdlob12w4Rdhib8w4Rmb0w4 + { + private readonly uint _value; + public InstRnb16w4Rdlob12w4Rdhib8w4Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Rdhi => (_value >> 8) & 0xF; + public readonly uint Rdlo => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Rdhib16w4Rdlob12w4Rmb8w4Mb6w1Nb5w1Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4Rdhib16w4Rdlob12w4Rmb8w4Mb6w1Nb5w1Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint N => (_value >> 5) & 0x1; + public readonly uint M => (_value >> 6) & 0x1; + public readonly uint Rm => (_value >> 8) & 0xF; + public readonly uint Rdlo => (_value >> 12) & 0xF; + public readonly uint Rdhi => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb16w4Rdlob12w4Rdhib8w4Nb5w1Mb4w1Rmb0w4 + { + private readonly uint _value; + public InstRnb16w4Rdlob12w4Rdhib8w4Nb5w1Mb4w1Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 4) & 0x1; + public readonly uint N => (_value >> 5) & 0x1; + public readonly uint Rdhi => (_value >> 8) & 0xF; + public readonly uint Rdlo => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Rdhib16w4Rdlob12w4Rmb8w4Mb5w1Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4Rdhib16w4Rdlob12w4Rmb8w4Mb5w1Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Rm => (_value >> 8) & 0xF; + public readonly uint Rdlo => (_value >> 12) & 0xF; + public readonly uint Rdhi => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb16w4Rdlob12w4Rdhib8w4Mb4w1Rmb0w4 + { + private readonly uint _value; + public InstRnb16w4Rdlob12w4Rdhib8w4Mb4w1Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 4) & 0x1; + public readonly uint Rdhi => (_value >> 8) & 0xF; + public readonly uint Rdlo => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Rdb16w4Rab12w4Rmb8w4Mb6w1Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4Rdb16w4Rab12w4Rmb8w4Mb6w1Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 6) & 0x1; + public readonly uint Rm => (_value >> 8) & 0xF; + public readonly uint Ra => (_value >> 12) & 0xF; + public readonly uint Rd => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstCondb28w4Rdb16w4Rab12w4Rmb8w4Rb5w1Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4Rdb16w4Rab12w4Rmb8w4Rb5w1Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint R => (_value >> 5) & 0x1; + public readonly uint Rm => (_value >> 8) & 0xF; + public readonly uint Ra => (_value >> 12) & 0xF; + public readonly uint Rd => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb16w4Rab12w4Rdb8w4Rb4w1Rmb0w4 + { + private readonly uint _value; + public InstRnb16w4Rab12w4Rdb8w4Rb4w1Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint R => (_value >> 4) & 0x1; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Ra => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Rdb16w4Rmb8w4Rb5w1Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4Rdb16w4Rmb8w4Rb5w1Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint R => (_value >> 5) & 0x1; + public readonly uint Rm => (_value >> 8) & 0xF; + public readonly uint Rd => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb16w4Rdb8w4Rb4w1Rmb0w4 + { + private readonly uint _value; + public InstRnb16w4Rdb8w4Rb4w1Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint R => (_value >> 4) & 0x1; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Rdb16w4Rmb8w4Mb5w1Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4Rdb16w4Rmb8w4Mb5w1Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Rm => (_value >> 8) & 0xF; + public readonly uint Rd => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb16w4Rdb8w4Mb4w1Rmb0w4 + { + private readonly uint _value; + public InstRnb16w4Rdb8w4Mb4w1Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 4) & 0x1; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Rdb16w4Rmb8w4Mb6w1Nb5w1Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4Rdb16w4Rmb8w4Mb6w1Nb5w1Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint N => (_value >> 5) & 0x1; + public readonly uint M => (_value >> 6) & 0x1; + public readonly uint Rm => (_value >> 8) & 0xF; + public readonly uint Rd => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb16w4Rdb8w4Nb5w1Mb4w1Rmb0w4 + { + private readonly uint _value; + public InstRnb16w4Rdb8w4Nb5w1Mb4w1Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 4) & 0x1; + public readonly uint N => (_value >> 5) & 0x1; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Rdb16w4Rmb8w4Mb6w1Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4Rdb16w4Rmb8w4Mb6w1Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 6) & 0x1; + public readonly uint Rm => (_value >> 8) & 0xF; + public readonly uint Rd => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstCondb28w4SatImmb16w5Rdb12w4Imm5b7w5Shb6w1Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4SatImmb16w5Rdb12w4Imm5b7w5Shb6w1Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint Sh => (_value >> 6) & 0x1; + public readonly uint Imm5 => (_value >> 7) & 0x1F; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint SatImm => (_value >> 16) & 0x1F; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstShb21w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2SatImmb0w5 + { + private readonly uint _value; + public InstShb21w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2SatImmb0w5(uint value) => _value = value; + public readonly uint SatImm => (_value >> 0) & 0x1F; + public readonly uint Imm2 => (_value >> 6) & 0x3; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Imm3 => (_value >> 12) & 0x7; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint Sh => (_value >> 21) & 0x1; + } + + readonly struct InstCondb28w4SatImmb16w4Rdb12w4Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4SatImmb16w4Rdb12w4Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint SatImm => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb16w4Rdb8w4SatImmb0w4 + { + private readonly uint _value; + public InstRnb16w4Rdb8w4SatImmb0w4(uint value) => _value = value; + public readonly uint SatImm => (_value >> 0) & 0xF; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Rnb16w4Rtb0w4 + { + private readonly uint _value; + public InstCondb28w4Rnb16w4Rtb0w4(uint value) => _value = value; + public readonly uint Rt => (_value >> 0) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstCondb28w4Rnb16w4Rdb12w4Rtb0w4 + { + private readonly uint _value; + public InstCondb28w4Rnb16w4Rdb12w4Rtb0w4(uint value) => _value = value; + public readonly uint Rt => (_value >> 0) & 0xF; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb16w4Rtb12w4Rdb0w4 + { + private readonly uint _value; + public InstRnb16w4Rtb12w4Rdb0w4(uint value) => _value = value; + public readonly uint Rd => (_value >> 0) & 0xF; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstRnb16w4Rtb12w4Rt2b8w4Rdb0w4 + { + private readonly uint _value; + public InstRnb16w4Rtb12w4Rt2b8w4Rdb0w4(uint value) => _value = value; + public readonly uint Rd => (_value >> 0) & 0xF; + public readonly uint Rt2 => (_value >> 8) & 0xF; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstWb21w1Rnb16w4Mb14w1RegisterListb0w14 + { + private readonly uint _value; + public InstWb21w1Rnb16w4Mb14w1RegisterListb0w14(uint value) => _value = value; + public readonly uint RegisterList => (_value >> 0) & 0x3FFF; + public readonly uint M => (_value >> 14) & 0x1; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint W => (_value >> 21) & 0x1; + } + + readonly struct InstRnb16w4Rtb12w4Rdb8w4Imm8b0w8 + { + private readonly uint _value; + public InstRnb16w4Rtb12w4Rdb8w4Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Rnb16w4Rdb12w4Rotateb10w2Rmb0w4 + { + private readonly uint _value; + public InstCondb28w4Rnb16w4Rdb12w4Rotateb10w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Rotate => (_value >> 10) & 0x3; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRnb16w4Rdb8w4Rotateb4w2Rmb0w4 + { + private readonly uint _value; + public InstRnb16w4Rdb8w4Rotateb4w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Rotate => (_value >> 4) & 0x3; + public readonly uint Rd => (_value >> 8) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Rdb12w4Rotateb10w2Rmb0w4 + { + private readonly uint _value; + public InstCondb28w4Rdb12w4Rotateb10w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Rotate => (_value >> 10) & 0x3; + public readonly uint Rd => (_value >> 12) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRdb8w4Rotateb4w2Rmb0w4 + { + private readonly uint _value; + public InstRdb8w4Rotateb4w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Rotate => (_value >> 4) & 0x3; + public readonly uint Rd => (_value >> 8) & 0xF; + } + + readonly struct InstRnb16w4Hb4w1Rmb0w4 + { + private readonly uint _value; + public InstRnb16w4Hb4w1Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint H => (_value >> 4) & 0x1; + public readonly uint Rn => (_value >> 16) & 0xF; + } + + readonly struct InstImm12b8w12Imm4b0w4 + { + private readonly uint _value; + public InstImm12b8w12Imm4b0w4(uint value) => _value = value; + public readonly uint Imm4 => (_value >> 0) & 0xF; + public readonly uint Imm12 => (_value >> 8) & 0xFFF; + } + + readonly struct InstImm4b16w4Imm12b0w12 + { + private readonly uint _value; + public InstImm4b16w4Imm12b0w12(uint value) => _value = value; + public readonly uint Imm12 => (_value >> 0) & 0xFFF; + public readonly uint Imm4 => (_value >> 16) & 0xF; + } + + readonly struct InstCondb28w4Rdhib16w4Rdlob12w4Rmb8w4Rnb0w4 + { + private readonly uint _value; + public InstCondb28w4Rdhib16w4Rdlob12w4Rmb8w4Rnb0w4(uint value) => _value = value; + public readonly uint Rn => (_value >> 0) & 0xF; + public readonly uint Rm => (_value >> 8) & 0xF; + public readonly uint Rdlo => (_value >> 12) & 0xF; + public readonly uint Rdhi => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Size => (_value >> 20) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 24) & 0x1; + } + + readonly struct InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Size => (_value >> 20) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 28) & 0x1; + } + + readonly struct InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Size => (_value >> 20) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 24) & 0x1; + } + + readonly struct InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Size => (_value >> 20) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 28) & 0x1; + } + + readonly struct InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Sz => (_value >> 20) & 0x1; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint F => (_value >> 10) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Size => (_value >> 18) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Size => (_value >> 8) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Size => (_value >> 8) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Size => (_value >> 20) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Size => (_value >> 8) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Size => (_value >> 8) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Size => (_value >> 20) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 + { + private readonly uint _value; + public InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4(uint value) => _value = value; + public readonly uint Imm4 => (_value >> 0) & 0xF; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Imm3 => (_value >> 16) & 0x7; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint I => (_value >> 24) & 0x1; + } + + readonly struct InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 + { + private readonly uint _value; + public InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4(uint value) => _value = value; + public readonly uint Imm4 => (_value >> 0) & 0xF; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Imm3 => (_value >> 16) & 0x7; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint I => (_value >> 28) & 0x1; + } + + readonly struct InstRotb24w1Db22w1Sb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstRotb24w1Db22w1Sb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint S => (_value >> 20) & 0x1; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint Rot => (_value >> 24) & 0x1; + } + + readonly struct InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Size => (_value >> 18) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstRotb23w2Db22w1Sb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstRotb23w2Db22w1Sb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint S => (_value >> 20) & 0x1; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint Rot => (_value >> 23) & 0x3; + } + + readonly struct InstSb23w1Db22w1Rotb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstSb23w1Db22w1Rotb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Rot => (_value >> 20) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint S => (_value >> 23) & 0x1; + } + + readonly struct InstCondb28w4Db22w1Vdb12w4Sizeb8w2 + { + private readonly uint _value; + public InstCondb28w4Db22w1Vdb12w4Sizeb8w2(uint value) => _value = value; + public readonly uint Size => (_value >> 8) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstDb22w1Vdb12w4Sizeb8w2 + { + private readonly uint _value; + public InstDb22w1Vdb12w4Sizeb8w2(uint value) => _value = value; + public readonly uint Size => (_value >> 8) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint Op => (_value >> 7) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Size => (_value >> 18) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Op => (_value >> 7) & 0x1; + public readonly uint Size => (_value >> 8) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstCondb28w4Db22w1Opb16w1Vdb12w4Szb8w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstCondb28w4Db22w1Opb16w1Vdb12w4Szb8w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Sz => (_value >> 8) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Op => (_value >> 16) & 0x1; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstDb22w1Opb16w1Vdb12w4Szb8w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Opb16w1Vdb12w4Szb8w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Sz => (_value >> 8) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Op => (_value >> 16) & 0x1; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstCondb28w4Db22w1Vdb12w4Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstCondb28w4Db22w1Vdb12w4Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstDb22w1Vdb12w4Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Vdb12w4Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstDb22w1Sizeb18w2Vdb12w4Opb8w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Sizeb18w2Vdb12w4Opb8w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Op => (_value >> 8) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Size => (_value >> 18) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstDb22w1Sizeb18w2Vdb12w4Opb7w2Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Sizeb18w2Vdb12w4Opb7w2Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint Op => (_value >> 7) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Size => (_value >> 18) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstCondb28w4Db22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstCondb28w4Db22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Op => (_value >> 7) & 0x1; + public readonly uint Size => (_value >> 8) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstUb24w1Db22w1Imm6b16w6Vdb12w4Opb8w2Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstUb24w1Db22w1Imm6b16w6Vdb12w4Opb8w2Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint Op => (_value >> 8) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Imm6 => (_value >> 16) & 0x3F; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 24) & 0x1; + } + + readonly struct InstUb28w1Db22w1Imm6b16w6Vdb12w4Opb8w2Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstUb28w1Db22w1Imm6b16w6Vdb12w4Opb8w2Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint Op => (_value >> 8) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Imm6 => (_value >> 16) & 0x3F; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 28) & 0x1; + } + + readonly struct InstCondb28w4Db22w1Opb18w1Ub16w1Vdb12w4Sfb8w2Sxb7w1Ib5w1Imm4b0w4 + { + private readonly uint _value; + public InstCondb28w4Db22w1Opb18w1Ub16w1Vdb12w4Sfb8w2Sxb7w1Ib5w1Imm4b0w4(uint value) => _value = value; + public readonly uint Imm4 => (_value >> 0) & 0xF; + public readonly uint I => (_value >> 5) & 0x1; + public readonly uint Sx => (_value >> 7) & 0x1; + public readonly uint Sf => (_value >> 8) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint U => (_value >> 16) & 0x1; + public readonly uint Op => (_value >> 18) & 0x1; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstDb22w1Opb18w1Ub16w1Vdb12w4Sfb8w2Sxb7w1Ib5w1Imm4b0w4 + { + private readonly uint _value; + public InstDb22w1Opb18w1Ub16w1Vdb12w4Sfb8w2Sxb7w1Ib5w1Imm4b0w4(uint value) => _value = value; + public readonly uint Imm4 => (_value >> 0) & 0xF; + public readonly uint I => (_value >> 5) & 0x1; + public readonly uint Sx => (_value >> 7) & 0x1; + public readonly uint Sf => (_value >> 8) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint U => (_value >> 16) & 0x1; + public readonly uint Op => (_value >> 18) & 0x1; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstCondb28w4Bb22w1Qb21w1Vdb16w4Rtb12w4Db7w1Eb5w1 + { + private readonly uint _value; + public InstCondb28w4Bb22w1Qb21w1Vdb16w4Rtb12w4Db7w1Eb5w1(uint value) => _value = value; + public readonly uint E => (_value >> 5) & 0x1; + public readonly uint D => (_value >> 7) & 0x1; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Vd => (_value >> 16) & 0xF; + public readonly uint Q => (_value >> 21) & 0x1; + public readonly uint B => (_value >> 22) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstBb22w1Qb21w1Vdb16w4Rtb12w4Db7w1Eb5w1 + { + private readonly uint _value; + public InstBb22w1Qb21w1Vdb16w4Rtb12w4Db7w1Eb5w1(uint value) => _value = value; + public readonly uint E => (_value >> 5) & 0x1; + public readonly uint D => (_value >> 7) & 0x1; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Vd => (_value >> 16) & 0xF; + public readonly uint Q => (_value >> 21) & 0x1; + public readonly uint B => (_value >> 22) & 0x1; + } + + readonly struct InstDb22w1Imm4b16w4Vdb12w4Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Imm4b16w4Vdb12w4Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Imm4 => (_value >> 16) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstDb22w1Vnb16w4Vdb12w4Imm4b8w4Nb7w1Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Vnb16w4Vdb12w4Imm4b8w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Imm4 => (_value >> 8) & 0xF; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 + { + private readonly uint _value; + public InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint IndexAlign => (_value >> 4) & 0xF; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Ab4w1Rmb0w4 + { + private readonly uint _value; + public InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Ab4w1Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint A => (_value >> 4) & 0x1; + public readonly uint T => (_value >> 5) & 0x1; + public readonly uint Size => (_value >> 6) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 + { + private readonly uint _value; + public InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint Align => (_value >> 4) & 0x3; + public readonly uint Size => (_value >> 6) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Rmb0w4 + { + private readonly uint _value; + public InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Rmb0w4(uint value) => _value = value; + public readonly uint Rm => (_value >> 0) & 0xF; + public readonly uint T => (_value >> 5) & 0x1; + public readonly uint Size => (_value >> 6) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstCondb28w4Pb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm8b0w8 + { + private readonly uint _value; + public InstCondb28w4Pb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint W => (_value >> 21) & 0x1; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint P => (_value >> 24) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstPb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm8b0w8 + { + private readonly uint _value; + public InstPb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint W => (_value >> 21) & 0x1; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint P => (_value >> 24) & 0x1; + } + + readonly struct InstCondb28w4Ub23w1Db22w1Rnb16w4Vdb12w4Sizeb8w2Imm8b0w8 + { + private readonly uint _value; + public InstCondb28w4Ub23w1Db22w1Rnb16w4Vdb12w4Sizeb8w2Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint Size => (_value >> 8) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstUb23w1Db22w1Rnb16w4Vdb12w4Sizeb8w2Imm8b0w8 + { + private readonly uint _value; + public InstUb23w1Db22w1Rnb16w4Vdb12w4Sizeb8w2Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint Size => (_value >> 8) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Rn => (_value >> 16) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + } + + readonly struct InstCondb28w4Ub23w1Db22w1Vdb12w4Sizeb8w2Imm8b0w8 + { + private readonly uint _value; + public InstCondb28w4Ub23w1Db22w1Vdb12w4Sizeb8w2Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint Size => (_value >> 8) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstUb23w1Db22w1Vdb12w4Sizeb8w2Imm8b0w8 + { + private readonly uint _value; + public InstUb23w1Db22w1Vdb12w4Sizeb8w2Imm8b0w8(uint value) => _value = value; + public readonly uint Imm8 => (_value >> 0) & 0xFF; + public readonly uint Size => (_value >> 8) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 23) & 0x1; + } + + readonly struct InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Fb8w1Nb7w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Fb8w1Nb7w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint F => (_value >> 8) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Size => (_value >> 20) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint Q => (_value >> 24) & 0x1; + } + + readonly struct InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Fb8w1Nb7w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Fb8w1Nb7w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint F => (_value >> 8) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Size => (_value >> 20) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint Q => (_value >> 28) & 0x1; + } + + readonly struct InstDb22w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstUb24w1Db22w1Imm3hb19w3Vdb12w4Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstUb24w1Db22w1Imm3hb19w3Vdb12w4Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Imm3h => (_value >> 19) & 0x7; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 24) & 0x1; + } + + readonly struct InstUb28w1Db22w1Imm3hb19w3Vdb12w4Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstUb28w1Db22w1Imm3hb19w3Vdb12w4Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Imm3h => (_value >> 19) & 0x7; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 28) & 0x1; + } + + readonly struct InstCondb28w4Opb20w1Rt2b16w4Rtb12w4Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstCondb28w4Opb20w1Rt2b16w4Rtb12w4Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rt2 => (_value >> 16) & 0xF; + public readonly uint Op => (_value >> 20) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstOpb20w1Rt2b16w4Rtb12w4Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstOpb20w1Rt2b16w4Rtb12w4Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Rt2 => (_value >> 16) & 0xF; + public readonly uint Op => (_value >> 20) & 0x1; + } + + readonly struct InstCondb28w4Opb20w1Vnb16w4Rtb12w4Nb7w1 + { + private readonly uint _value; + public InstCondb28w4Opb20w1Vnb16w4Rtb12w4Nb7w1(uint value) => _value = value; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Op => (_value >> 20) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstOpb20w1Vnb16w4Rtb12w4Nb7w1 + { + private readonly uint _value; + public InstOpb20w1Vnb16w4Rtb12w4Nb7w1(uint value) => _value = value; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Op => (_value >> 20) & 0x1; + } + + readonly struct InstCondb28w4Db22w1Imm4hb16w4Vdb12w4Sizeb8w2Imm4lb0w4 + { + private readonly uint _value; + public InstCondb28w4Db22w1Imm4hb16w4Vdb12w4Sizeb8w2Imm4lb0w4(uint value) => _value = value; + public readonly uint Imm4l => (_value >> 0) & 0xF; + public readonly uint Size => (_value >> 8) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Imm4h => (_value >> 16) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstDb22w1Imm4hb16w4Vdb12w4Sizeb8w2Imm4lb0w4 + { + private readonly uint _value; + public InstDb22w1Imm4hb16w4Vdb12w4Sizeb8w2Imm4lb0w4(uint value) => _value = value; + public readonly uint Imm4l => (_value >> 0) & 0xF; + public readonly uint Size => (_value >> 8) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Imm4h => (_value >> 16) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstCondb28w4Opc1b21w2Vdb16w4Rtb12w4Db7w1Opc2b5w2 + { + private readonly uint _value; + public InstCondb28w4Opc1b21w2Vdb16w4Rtb12w4Db7w1Opc2b5w2(uint value) => _value = value; + public readonly uint Opc2 => (_value >> 5) & 0x3; + public readonly uint D => (_value >> 7) & 0x1; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Vd => (_value >> 16) & 0xF; + public readonly uint Opc1 => (_value >> 21) & 0x3; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstOpc1b21w2Vdb16w4Rtb12w4Db7w1Opc2b5w2 + { + private readonly uint _value; + public InstOpc1b21w2Vdb16w4Rtb12w4Db7w1Opc2b5w2(uint value) => _value = value; + public readonly uint Opc2 => (_value >> 5) & 0x3; + public readonly uint D => (_value >> 7) & 0x1; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Vd => (_value >> 16) & 0xF; + public readonly uint Opc1 => (_value >> 21) & 0x3; + } + + readonly struct InstCondb28w4Ub23w1Opc1b21w2Vnb16w4Rtb12w4Nb7w1Opc2b5w2 + { + private readonly uint _value; + public InstCondb28w4Ub23w1Opc1b21w2Vnb16w4Rtb12w4Nb7w1Opc2b5w2(uint value) => _value = value; + public readonly uint Opc2 => (_value >> 5) & 0x3; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Opc1 => (_value >> 21) & 0x3; + public readonly uint U => (_value >> 23) & 0x1; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstUb23w1Opc1b21w2Vnb16w4Rtb12w4Nb7w1Opc2b5w2 + { + private readonly uint _value; + public InstUb23w1Opc1b21w2Vnb16w4Rtb12w4Nb7w1Opc2b5w2(uint value) => _value = value; + public readonly uint Opc2 => (_value >> 5) & 0x3; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Opc1 => (_value >> 21) & 0x3; + public readonly uint U => (_value >> 23) & 0x1; + } + + readonly struct InstCondb28w4Regb16w4Rtb12w4 + { + private readonly uint _value; + public InstCondb28w4Regb16w4Rtb12w4(uint value) => _value = value; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Reg => (_value >> 16) & 0xF; + public readonly uint Cond => (_value >> 28) & 0xF; + } + + readonly struct InstRegb16w4Rtb12w4 + { + private readonly uint _value; + public InstRegb16w4Rtb12w4(uint value) => _value = value; + public readonly uint Rt => (_value >> 12) & 0xF; + public readonly uint Reg => (_value >> 16) & 0xF; + } + + readonly struct InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Opb9w1Nb7w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Opb9w1Nb7w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Op => (_value >> 9) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Size => (_value >> 20) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 24) & 0x1; + } + + readonly struct InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Opb9w1Nb7w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Opb9w1Nb7w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Op => (_value >> 9) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Size => (_value >> 20) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 28) & 0x1; + } + + readonly struct InstOpb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstOpb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Size => (_value >> 20) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint Op => (_value >> 24) & 0x1; + } + + readonly struct InstOpb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstOpb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Size => (_value >> 20) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint Op => (_value >> 28) & 0x1; + } + + readonly struct InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Sz => (_value >> 20) & 0x1; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Size => (_value >> 20) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint Q => (_value >> 24) & 0x1; + } + + readonly struct InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Size => (_value >> 20) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint Q => (_value >> 28) & 0x1; + } + + readonly struct InstDb22w1Sizeb18w2Vdb12w4Opb6w2Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Sizeb18w2Vdb12w4Opb6w2Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Op => (_value >> 6) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Size => (_value >> 18) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstUb24w1Db22w1Imm6b16w6Vdb12w4Opb8w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstUb24w1Db22w1Imm6b16w6Vdb12w4Opb8w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Op => (_value >> 8) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Imm6 => (_value >> 16) & 0x3F; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 24) & 0x1; + } + + readonly struct InstUb28w1Db22w1Imm6b16w6Vdb12w4Opb8w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstUb28w1Db22w1Imm6b16w6Vdb12w4Opb8w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Op => (_value >> 8) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Imm6 => (_value >> 16) & 0x3F; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 28) & 0x1; + } + + readonly struct InstUb24w1Db22w1Imm6b16w6Vdb12w4Opb8w1Lb7w1Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstUb24w1Db22w1Imm6b16w6Vdb12w4Opb8w1Lb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint L => (_value >> 7) & 0x1; + public readonly uint Op => (_value >> 8) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Imm6 => (_value >> 16) & 0x3F; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 24) & 0x1; + } + + readonly struct InstUb28w1Db22w1Imm6b16w6Vdb12w4Opb8w1Lb7w1Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstUb28w1Db22w1Imm6b16w6Vdb12w4Opb8w1Lb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint L => (_value >> 7) & 0x1; + public readonly uint Op => (_value >> 8) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Imm6 => (_value >> 16) & 0x3F; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 28) & 0x1; + } + + readonly struct InstDb22w1Sizeb18w2Vdb12w4Fb8w1Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Sizeb18w2Vdb12w4Fb8w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint F => (_value >> 8) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Size => (_value >> 18) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstUb24w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstUb24w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint L => (_value >> 7) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Imm6 => (_value >> 16) & 0x3F; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 24) & 0x1; + } + + readonly struct InstUb28w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstUb28w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint L => (_value >> 7) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Imm6 => (_value >> 16) & 0x3F; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 28) & 0x1; + } + + readonly struct InstDb22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Imm6 => (_value >> 16) & 0x3F; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstDb22w1Ccb20w2Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Ccb20w2Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Size => (_value >> 8) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint Cc => (_value >> 20) & 0x3; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstUb24w1Db22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstUb24w1Db22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Imm6 => (_value >> 16) & 0x3F; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 24) & 0x1; + } + + readonly struct InstUb28w1Db22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstUb28w1Db22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Imm6 => (_value >> 16) & 0x3F; + public readonly uint D => (_value >> 22) & 0x1; + public readonly uint U => (_value >> 28) & 0x1; + } + + readonly struct InstDb22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint L => (_value >> 7) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Imm6 => (_value >> 16) & 0x3F; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstDb22w1Vdb12w4Qb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Vdb12w4Qb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Q => (_value >> 6) & 0x1; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + } + + readonly struct InstDb22w1Vnb16w4Vdb12w4Lenb8w2Nb7w1Opb6w1Mb5w1Vmb0w4 + { + private readonly uint _value; + public InstDb22w1Vnb16w4Vdb12w4Lenb8w2Nb7w1Opb6w1Mb5w1Vmb0w4(uint value) => _value = value; + public readonly uint Vm => (_value >> 0) & 0xF; + public readonly uint M => (_value >> 5) & 0x1; + public readonly uint Op => (_value >> 6) & 0x1; + public readonly uint N => (_value >> 7) & 0x1; + public readonly uint Len => (_value >> 8) & 0x3; + public readonly uint Vd => (_value >> 12) & 0xF; + public readonly uint Vn => (_value >> 16) & 0xF; + public readonly uint D => (_value >> 22) & 0x1; + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/InstFlags.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/InstFlags.cs new file mode 100644 index 000000000..a1937e088 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/InstFlags.cs @@ -0,0 +1,63 @@ +using System; + +namespace Ryujinx.Cpu.LightningJit.Arm32 +{ + [Flags] + enum InstFlags + { + None = 0, + Cond = 1 << 0, + Rd = 1 << 1, + RdLo = 1 << 2, + RdHi = 1 << 3, + Rdn = 1 << 4, + Dn = 1 << 5, + Rt = 1 << 6, + Rt2 = 1 << 7, + Rlist = 1 << 8, + Rd16 = 1 << 9, + ReadRd = 1 << 10, + WBack = 1 << 11, + Thumb16 = 1 << 12, + + RdnDn = Rdn | Dn, + RdRd16 = Rd | Rd16, + RtRt2 = Rt | Rt2, + RdLoRdHi = RdLo | RdHi, + RdLoHi = Rd | RdHi, + RdRtRead = Rd | RtRead, + RdRtReadRd16 = Rd | RtRead | Rd16, + RdRt2Read = Rd | Rt2 | RtRead, + RdRt2ReadRd16 = Rd | Rt2 | RtRead | Rd16, + RtRd16 = Rt | Rd16, + RtWBack = Rt | WBack, + Rt2WBack = Rt2 | RtWBack, + RtRead = Rt | ReadRd, + RtReadRd16 = Rt | ReadRd | Rd16, + Rt2Read = Rt2 | RtRead, + RtReadWBack = RtRead | WBack, + Rt2ReadWBack = Rt2 | RtReadWBack, + RlistWBack = Rlist | WBack, + RlistRead = Rlist | ReadRd, + RlistReadWBack = Rlist | ReadRd | WBack, + + CondRd = Cond | Rd, + CondRdLoHi = Cond | Rd | RdHi, + CondRt = Cond | Rt, + CondRt2 = Cond | Rt | Rt2, + CondRd16 = Cond | Rd | Rd16, + CondWBack = Cond | WBack, + CondRdRtRead = Cond | Rd | RtRead, + CondRdRt2Read = Cond | Rd | Rt2 | RtRead, + CondRtWBack = Cond | RtWBack, + CondRt2WBack = Cond | Rt2 | RtWBack, + CondRtRead = Cond | RtRead, + CondRt2Read = Cond | Rt2 | RtRead, + CondRtReadWBack = Cond | RtReadWBack, + CondRt2ReadWBack = Cond | Rt2 | RtReadWBack, + CondRlist = Cond | Rlist, + CondRlistWBack = Cond | Rlist | WBack, + CondRlistRead = Cond | Rlist | ReadRd, + CondRlistReadWBack = Cond | Rlist | ReadRd | WBack, + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/InstInfo.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/InstInfo.cs new file mode 100644 index 000000000..80481ec69 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/InstInfo.cs @@ -0,0 +1,20 @@ +using System; + +namespace Ryujinx.Cpu.LightningJit.Arm32 +{ + readonly struct InstInfo + { + public readonly uint Encoding; + public readonly InstName Name; + public readonly Action EmitFunc; + public readonly InstFlags Flags; + + public InstInfo(uint encoding, InstName name, Action emitFunc, InstFlags flags) + { + Encoding = encoding; + Name = name; + EmitFunc = emitFunc; + Flags = flags; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/InstInfoForTable.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/InstInfoForTable.cs new file mode 100644 index 000000000..25739d564 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/InstInfoForTable.cs @@ -0,0 +1,79 @@ +using Ryujinx.Cpu.LightningJit.Table; +using System; + +namespace Ryujinx.Cpu.LightningJit.Arm32 +{ + readonly struct InstInfoForTable : IInstInfo + { + public uint Encoding { get; } + public uint EncodingMask { get; } + public InstEncoding[] Constraints { get; } + public InstMeta Meta { get; } + public IsaVersion Version => Meta.Version; + public IsaFeature Feature => Meta.Feature; + + public InstInfoForTable( + uint encoding, + uint encodingMask, + InstEncoding[] constraints, + InstName name, + Action emitFunc, + IsaVersion isaVersion, + IsaFeature isaFeature, + InstFlags flags) + { + Encoding = encoding; + EncodingMask = encodingMask; + Constraints = constraints; + Meta = new(name, emitFunc, isaVersion, isaFeature, flags); + } + + public InstInfoForTable( + uint encoding, + uint encodingMask, + InstEncoding[] constraints, + InstName name, + Action emitFunc, + IsaVersion isaVersion, + InstFlags flags) : this(encoding, encodingMask, constraints, name, emitFunc, isaVersion, IsaFeature.None, flags) + { + } + + public InstInfoForTable( + uint encoding, + uint encodingMask, + InstName name, + Action emitFunc, + IsaVersion isaVersion, + IsaFeature isaFeature, + InstFlags flags) : this(encoding, encodingMask, null, name, emitFunc, isaVersion, isaFeature, flags) + { + } + + public InstInfoForTable( + uint encoding, + uint encodingMask, + InstName name, + Action emitFunc, + IsaVersion isaVersion, + InstFlags flags) : this(encoding, encodingMask, null, name, emitFunc, isaVersion, IsaFeature.None, flags) + { + } + + public bool IsConstrained(uint encoding) + { + if (Constraints != null) + { + foreach (InstEncoding constraint in Constraints) + { + if ((encoding & constraint.EncodingMask) == constraint.Encoding) + { + return true; + } + } + } + + return false; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/InstMeta.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/InstMeta.cs new file mode 100644 index 000000000..64eb41bb7 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/InstMeta.cs @@ -0,0 +1,22 @@ +using System; + +namespace Ryujinx.Cpu.LightningJit.Arm32 +{ + readonly struct InstMeta + { + public readonly InstName Name; + public readonly Action EmitFunc; + public readonly IsaVersion Version; + public readonly IsaFeature Feature; + public readonly InstFlags Flags; + + public InstMeta(InstName name, Action emitFunc, IsaVersion isaVersion, IsaFeature isaFeature, InstFlags flags) + { + Name = name; + EmitFunc = emitFunc; + Version = isaVersion; + Feature = isaFeature; + Flags = flags; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/InstName.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/InstName.cs new file mode 100644 index 000000000..2ee67aa0a --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/InstName.cs @@ -0,0 +1,562 @@ +namespace Ryujinx.Cpu.LightningJit.Arm32 +{ + enum InstName + { + AdcI, + AdcR, + AdcRr, + AddI, + AddR, + AddRr, + AddSpI, + AddSpR, + Adr, + Aesd, + Aese, + Aesimc, + Aesmc, + AndI, + AndR, + AndRr, + B, + Bfc, + Bfi, + BicI, + BicR, + BicRr, + Bkpt, + BlxR, + BlI, + Bx, + Bxj, + Cbnz, + Clrbhb, + Clrex, + Clz, + CmnI, + CmnR, + CmnRr, + CmpI, + CmpR, + CmpRr, + Cps, + Crc32, + Crc32c, + Csdb, + Dbg, + Dcps1, + Dcps2, + Dcps3, + Dmb, + Dsb, + EorI, + EorR, + EorRr, + Eret, + Esb, + Fldmx, + Fstmx, + Hlt, + Hvc, + Isb, + It, + Lda, + Ldab, + Ldaex, + Ldaexb, + Ldaexd, + Ldaexh, + Ldah, + LdcI, + LdcL, + Ldm, + Ldmda, + Ldmdb, + Ldmib, + LdmE, + LdmU, + Ldrbt, + LdrbI, + LdrbL, + LdrbR, + LdrdI, + LdrdL, + LdrdR, + Ldrex, + Ldrexb, + Ldrexd, + Ldrexh, + Ldrht, + LdrhI, + LdrhL, + LdrhR, + Ldrsbt, + LdrsbI, + LdrsbL, + LdrsbR, + Ldrsht, + LdrshI, + LdrshL, + LdrshR, + Ldrt, + LdrI, + LdrL, + LdrR, + Mcr, + Mcrr, + Mla, + Mls, + Movt, + MovI, + MovR, + MovRr, + Mrc, + Mrrc, + Mrs, + MrsBr, + MsrBr, + MsrI, + MsrR, + Mul, + MvnI, + MvnR, + MvnRr, + Nop, + OrnI, + OrnR, + OrrI, + OrrR, + OrrRr, + Pkh, + PldI, + PldL, + PldR, + PliI, + PliR, + Pop, + Pssbb, + Push, + Qadd, + Qadd16, + Qadd8, + Qasx, + Qdadd, + Qdsub, + Qsax, + Qsub, + Qsub16, + Qsub8, + Rbit, + Rev, + Rev16, + Revsh, + Rfe, + RsbI, + RsbR, + RsbRr, + RscI, + RscR, + RscRr, + Sadd16, + Sadd8, + Sasx, + Sb, + SbcI, + SbcR, + SbcRr, + Sbfx, + Sdiv, + Sel, + Setend, + Setpan, + Sev, + Sevl, + Sha1c, + Sha1h, + Sha1m, + Sha1p, + Sha1su0, + Sha1su1, + Sha256h, + Sha256h2, + Sha256su0, + Sha256su1, + Shadd16, + Shadd8, + Shasx, + Shsax, + Shsub16, + Shsub8, + Smc, + Smlabb, + Smlad, + Smlal, + Smlalbb, + Smlald, + Smlawb, + Smlsd, + Smlsld, + Smmla, + Smmls, + Smmul, + Smuad, + Smulbb, + Smull, + Smulwb, + Smusd, + Srs, + Ssat, + Ssat16, + Ssax, + Ssbb, + Ssub16, + Ssub8, + Stc, + Stl, + Stlb, + Stlex, + Stlexb, + Stlexd, + Stlexh, + Stlh, + Stm, + Stmda, + Stmdb, + Stmib, + StmU, + Strbt, + StrbI, + StrbR, + StrdI, + StrdR, + Strex, + Strexb, + Strexd, + Strexh, + Strht, + StrhI, + StrhR, + Strt, + StrI, + StrR, + SubI, + SubR, + SubRr, + SubSpI, + SubSpR, + Svc, + Sxtab, + Sxtab16, + Sxtah, + Sxtb, + Sxtb16, + Sxth, + Tbb, + TeqI, + TeqR, + TeqRr, + Tsb, + TstI, + TstR, + TstRr, + Uadd16, + Uadd8, + Uasx, + Ubfx, + Udf, + Udiv, + Uhadd16, + Uhadd8, + Uhasx, + Uhsax, + Uhsub16, + Uhsub8, + Umaal, + Umlal, + Umull, + Uqadd16, + Uqadd8, + Uqasx, + Uqsax, + Uqsub16, + Uqsub8, + Usad8, + Usada8, + Usat, + Usat16, + Usax, + Usub16, + Usub8, + Uxtab, + Uxtab16, + Uxtah, + Uxtb, + Uxtb16, + Uxth, + Vaba, + Vabal, + VabdlI, + VabdF, + VabdI, + Vabs, + Vacge, + Vacgt, + Vaddhn, + Vaddl, + Vaddw, + VaddF, + VaddI, + VandR, + VbicI, + VbicR, + Vbif, + Vbit, + Vbsl, + Vcadd, + VceqI, + VceqR, + VcgeI, + VcgeR, + VcgtI, + VcgtR, + VcleI, + Vcls, + VcltI, + Vclz, + Vcmla, + VcmlaS, + Vcmp, + Vcmpe, + Vcnt, + VcvtaAsimd, + VcvtaVfp, + Vcvtb, + VcvtbBfs, + VcvtmAsimd, + VcvtmVfp, + VcvtnAsimd, + VcvtnVfp, + VcvtpAsimd, + VcvtpVfp, + VcvtrIv, + Vcvtt, + VcvttBfs, + VcvtBfs, + VcvtDs, + VcvtHs, + VcvtIs, + VcvtIv, + VcvtVi, + VcvtXs, + VcvtXv, + Vdiv, + Vdot, + VdotS, + VdupR, + VdupS, + Veor, + Vext, + Vfma, + Vfmal, + VfmalS, + VfmaBf, + VfmaBfs, + Vfms, + Vfmsl, + VfmslS, + Vfnma, + Vfnms, + Vhadd, + Vhsub, + Vins, + Vjcvt, + Vld11, + Vld1A, + Vld1M, + Vld21, + Vld2A, + Vld2M, + Vld31, + Vld3A, + Vld3M, + Vld41, + Vld4A, + Vld4M, + Vldm, + VldrI, + VldrL, + Vmaxnm, + VmaxF, + VmaxI, + Vminnm, + VminF, + VminI, + VmlalI, + VmlalS, + VmlaF, + VmlaI, + VmlaS, + VmlslI, + VmlslS, + VmlsF, + VmlsI, + VmlsS, + Vmmla, + Vmovl, + Vmovn, + Vmovx, + VmovD, + VmovH, + VmovI, + VmovR, + VmovRs, + VmovS, + VmovSr, + VmovSs, + Vmrs, + Vmsr, + VmullI, + VmullS, + VmulF, + VmulI, + VmulS, + VmvnI, + VmvnR, + Vneg, + Vnmla, + Vnmls, + Vnmul, + VornR, + VorrI, + VorrR, + Vpadal, + Vpaddl, + VpaddF, + VpaddI, + VpmaxF, + VpmaxI, + VpminF, + VpminI, + Vqabs, + Vqadd, + Vqdmlal, + Vqdmlsl, + Vqdmulh, + Vqdmull, + Vqmovn, + Vqneg, + Vqrdmlah, + Vqrdmlsh, + Vqrdmulh, + Vqrshl, + Vqrshrn, + VqshlI, + VqshlR, + Vqshrn, + Vqsub, + Vraddhn, + Vrecpe, + Vrecps, + Vrev16, + Vrev32, + Vrev64, + Vrhadd, + VrintaAsimd, + VrintaVfp, + VrintmAsimd, + VrintmVfp, + VrintnAsimd, + VrintnVfp, + VrintpAsimd, + VrintpVfp, + VrintrVfp, + VrintxAsimd, + VrintxVfp, + VrintzAsimd, + VrintzVfp, + Vrshl, + Vrshr, + Vrshrn, + Vrsqrte, + Vrsqrts, + Vrsra, + Vrsubhn, + Vsdot, + VsdotS, + Vsel, + Vshll, + VshlI, + VshlR, + Vshr, + Vshrn, + Vsli, + Vsmmla, + Vsqrt, + Vsra, + Vsri, + Vst11, + Vst1M, + Vst21, + Vst2M, + Vst31, + Vst3M, + Vst41, + Vst4M, + Vstm, + Vstr, + Vsubhn, + Vsubl, + Vsubw, + VsubF, + VsubI, + VsudotS, + Vswp, + Vtbl, + Vtrn, + Vtst, + Vudot, + VudotS, + Vummla, + Vusdot, + VusdotS, + Vusmmla, + Vuzp, + Vzip, + Wfe, + Wfi, + Yield, + } + + static class InstNameExtensions + { + public static bool IsCall(this InstName name) + { + return name == InstName.BlI || name == InstName.BlxR; + } + + public static bool IsSystem(this InstName name) + { + switch (name) + { + case InstName.Mcr: + case InstName.Mcrr: + case InstName.Mrc: + case InstName.Mrs: + case InstName.MrsBr: + case InstName.MsrBr: + case InstName.MsrI: + case InstName.MsrR: + case InstName.Mrrc: + case InstName.Svc: + return true; + } + + return false; + } + + public static bool IsSystemOrCall(this InstName name) + { + return name.IsSystem() || name.IsCall(); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/InstTableA32.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/InstTableA32.cs new file mode 100644 index 000000000..2168c0b9f --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/InstTableA32.cs @@ -0,0 +1,1194 @@ +using Ryujinx.Cpu.LightningJit.Table; +using System.Collections.Generic; + +namespace Ryujinx.Cpu.LightningJit.Arm32 +{ + static class InstTableA32 where T : IInstEmit + { + private static readonly InstTableLevel _table; + + static InstTableA32() + { + InstEncoding[] condConstraints = new InstEncoding[] + { + new(0xF0000000, 0xF0000000), + }; + + InstEncoding[] condRnsRnConstraints = new InstEncoding[] + { + new(0xF0000000, 0xF0000000), + new(0x000F0000, 0x001F0000), + new(0x000D0000, 0x000F0000), + }; + + InstEncoding[] condRnConstraints = new InstEncoding[] + { + new(0xF0000000, 0xF0000000), + new(0x000D0000, 0x000F0000), + }; + + InstEncoding[] vdVmConstraints = new InstEncoding[] + { + new(0x00001000, 0x00001000), + new(0x00000001, 0x00000001), + }; + + InstEncoding[] condRnConstraints2 = new InstEncoding[] + { + new(0xF0000000, 0xF0000000), + new(0x0000000F, 0x0000000F), + }; + + InstEncoding[] optionConstraints = new InstEncoding[] + { + new(0x00000000, 0x0000000F), + }; + + InstEncoding[] condPuwPwPuwPuwConstraints = new InstEncoding[] + { + new(0xF0000000, 0xF0000000), + new(0x00000000, 0x01A00000), + new(0x01000000, 0x01200000), + new(0x00200000, 0x01A00000), + new(0x01A00000, 0x01A00000), + }; + + InstEncoding[] condRnPuwConstraints = new InstEncoding[] + { + new(0xF0000000, 0xF0000000), + new(0x000F0000, 0x000F0000), + new(0x00000000, 0x01A00000), + }; + + InstEncoding[] condPuwConstraints = new InstEncoding[] + { + new(0xF0000000, 0xF0000000), + new(0x00000000, 0x01A00000), + }; + + InstEncoding[] condRnPwConstraints = new InstEncoding[] + { + new(0xF0000000, 0xF0000000), + new(0x000F0000, 0x000F0000), + new(0x00200000, 0x01200000), + }; + + InstEncoding[] condPwConstraints = new InstEncoding[] + { + new(0xF0000000, 0xF0000000), + new(0x00200000, 0x01200000), + }; + + InstEncoding[] condRnConstraints3 = new InstEncoding[] + { + new(0xF0000000, 0xF0000000), + new(0x000F0000, 0x000F0000), + }; + + InstEncoding[] condMaskrConstraints = new InstEncoding[] + { + new(0xF0000000, 0xF0000000), + new(0x00000000, 0x004F0000), + }; + + InstEncoding[] rnConstraints = new InstEncoding[] + { + new(0x000F0000, 0x000F0000), + }; + + InstEncoding[] vdVnVmConstraints = new InstEncoding[] + { + new(0x00001000, 0x00001000), + new(0x00010000, 0x00010000), + new(0x00000001, 0x00000001), + }; + + InstEncoding[] condRaConstraints = new InstEncoding[] + { + new(0xF0000000, 0xF0000000), + new(0x0000F000, 0x0000F000), + }; + + InstEncoding[] sizeQvdQvnQvmConstraints = new InstEncoding[] + { + new(0x00300000, 0x00300000), + new(0x00001040, 0x00001040), + new(0x00010040, 0x00010040), + new(0x00000041, 0x00000041), + }; + + InstEncoding[] sizeVdConstraints = new InstEncoding[] + { + new(0x00300000, 0x00300000), + new(0x00001000, 0x00001000), + }; + + InstEncoding[] qvdQvnQvmConstraints = new InstEncoding[] + { + new(0x00001040, 0x00001040), + new(0x00010040, 0x00010040), + new(0x00000041, 0x00000041), + }; + + InstEncoding[] sizeQvdQvmConstraints = new InstEncoding[] + { + new(0x000C0000, 0x000C0000), + new(0x00001040, 0x00001040), + new(0x00000041, 0x00000041), + }; + + InstEncoding[] sizeVnVmConstraints = new InstEncoding[] + { + new(0x00300000, 0x00300000), + new(0x00010000, 0x00010000), + new(0x00000001, 0x00000001), + }; + + InstEncoding[] sizeVdOpvnConstraints = new InstEncoding[] + { + new(0x00300000, 0x00300000), + new(0x00001000, 0x00001000), + new(0x00010100, 0x00010100), + }; + + InstEncoding[] cmodeCmodeQvdConstraints = new InstEncoding[] + { + new(0x00000000, 0x00000100), + new(0x00000C00, 0x00000C00), + new(0x00001040, 0x00001040), + }; + + InstEncoding[] qvdQvnQvmOpConstraints = new InstEncoding[] + { + new(0x00001040, 0x00001040), + new(0x00010040, 0x00010040), + new(0x00000041, 0x00000041), + new(0x00000000, 0x00300000), + }; + + InstEncoding[] qvdQvnQvmSizeConstraints = new InstEncoding[] + { + new(0x00001040, 0x00001040), + new(0x00010040, 0x00010040), + new(0x00000041, 0x00000041), + new(0x00300000, 0x00300000), + }; + + InstEncoding[] qvdQvnConstraints = new InstEncoding[] + { + new(0x00001040, 0x00001040), + new(0x00010040, 0x00010040), + }; + + InstEncoding[] qvdQvmConstraints = new InstEncoding[] + { + new(0x00001040, 0x00001040), + new(0x00000041, 0x00000041), + }; + + InstEncoding[] sizeConstraints = new InstEncoding[] + { + new(0x00000000, 0x00000300), + }; + + InstEncoding[] vmConstraints = new InstEncoding[] + { + new(0x00000001, 0x00000001), + }; + + InstEncoding[] opvdOpvmConstraints = new InstEncoding[] + { + new(0x00001100, 0x00001100), + new(0x00000001, 0x00000101), + }; + + InstEncoding[] imm6Opimm6Imm6QvdQvmConstraints = new InstEncoding[] + { + new(0x00000000, 0x00380000), + new(0x00200000, 0x00300200), + new(0x00000000, 0x00200000), + new(0x00001040, 0x00001040), + new(0x00000041, 0x00000041), + }; + + InstEncoding[] condQvdEbConstraints = new InstEncoding[] + { + new(0xF0000000, 0xF0000000), + new(0x00210000, 0x00210000), + new(0x00400020, 0x00400020), + }; + + InstEncoding[] imm4QvdConstraints = new InstEncoding[] + { + new(0x00000000, 0x00070000), + new(0x00001040, 0x00001040), + }; + + InstEncoding[] qvdQvnQvmQimm4Constraints = new InstEncoding[] + { + new(0x00001040, 0x00001040), + new(0x00010040, 0x00010040), + new(0x00000041, 0x00000041), + new(0x00000800, 0x00000840), + }; + + InstEncoding[] qvdConstraints = new InstEncoding[] + { + new(0x00001040, 0x00001040), + }; + + InstEncoding[] vdVnConstraints = new InstEncoding[] + { + new(0x00001000, 0x00001000), + new(0x00010000, 0x00010000), + }; + + InstEncoding[] sizeConstraints2 = new InstEncoding[] + { + new(0x00000C00, 0x00000C00), + }; + + InstEncoding[] sizeIndexAlignIndexAlignConstraints = new InstEncoding[] + { + new(0x00000C00, 0x00000C00), + new(0x00000010, 0x00000030), + new(0x00000020, 0x00000030), + }; + + InstEncoding[] sizeSizeaConstraints = new InstEncoding[] + { + new(0x000000C0, 0x000000C0), + new(0x00000010, 0x000000D0), + }; + + InstEncoding[] alignConstraints = new InstEncoding[] + { + new(0x00000020, 0x00000020), + }; + + InstEncoding[] alignConstraints2 = new InstEncoding[] + { + new(0x00000030, 0x00000030), + }; + + InstEncoding[] sizeConstraints3 = new InstEncoding[] + { + new(0x000000C0, 0x000000C0), + }; + + InstEncoding[] alignSizeConstraints = new InstEncoding[] + { + new(0x00000030, 0x00000030), + new(0x000000C0, 0x000000C0), + }; + + InstEncoding[] sizeAConstraints = new InstEncoding[] + { + new(0x000000C0, 0x000000C0), + new(0x00000010, 0x00000010), + }; + + InstEncoding[] sizeAlignConstraints = new InstEncoding[] + { + new(0x000000C0, 0x000000C0), + new(0x00000020, 0x00000020), + }; + + InstEncoding[] sizeIndexAlignConstraints = new InstEncoding[] + { + new(0x00000C00, 0x00000C00), + new(0x00000030, 0x00000030), + }; + + InstEncoding[] sizeaConstraints = new InstEncoding[] + { + new(0x000000C0, 0x000000D0), + }; + + InstEncoding[] sizeSizeVdConstraints = new InstEncoding[] + { + new(0x00300000, 0x00300000), + new(0x00000000, 0x00300000), + new(0x00001000, 0x00001000), + }; + + InstEncoding[] sizeQvdQvnConstraints = new InstEncoding[] + { + new(0x00300000, 0x00300000), + new(0x01001000, 0x01001000), + new(0x01010000, 0x01010000), + }; + + InstEncoding[] imm3hImm3hImm3hImm3hImm3hVdConstraints = new InstEncoding[] + { + new(0x00000000, 0x00380000), + new(0x00180000, 0x00380000), + new(0x00280000, 0x00380000), + new(0x00300000, 0x00380000), + new(0x00380000, 0x00380000), + new(0x00001000, 0x00001000), + }; + + InstEncoding[] sizeVmConstraints = new InstEncoding[] + { + new(0x000C0000, 0x000C0000), + new(0x00000001, 0x00000001), + }; + + InstEncoding[] condOpc1opc2Constraints = new InstEncoding[] + { + new(0xF0000000, 0xF0000000), + new(0x00000040, 0x00400060), + }; + + InstEncoding[] condUopc1opc2Uopc1opc2Constraints = new InstEncoding[] + { + new(0xF0000000, 0xF0000000), + new(0x00800000, 0x00C00060), + new(0x00000040, 0x00400060), + }; + + InstEncoding[] sizeOpuOpsizeVdConstraints = new InstEncoding[] + { + new(0x00300000, 0x00300000), + new(0x01000200, 0x01000200), + new(0x00100200, 0x00300200), + new(0x00001000, 0x00001000), + }; + + InstEncoding[] sizeOpsizeOpsizeQvdQvnQvmConstraints = new InstEncoding[] + { + new(0x00300000, 0x00300000), + new(0x01100000, 0x01300000), + new(0x01200000, 0x01300000), + new(0x00001040, 0x00001040), + new(0x00010040, 0x00010040), + new(0x00000041, 0x00000041), + }; + + InstEncoding[] cmodeQvdConstraints = new InstEncoding[] + { + new(0x00000E00, 0x00000E00), + new(0x00001040, 0x00001040), + }; + + InstEncoding[] qConstraints = new InstEncoding[] + { + new(0x00000040, 0x00000040), + }; + + InstEncoding[] sizeQConstraints = new InstEncoding[] + { + new(0x00300000, 0x00300000), + new(0x00000040, 0x00000040), + }; + + InstEncoding[] sizeConstraints4 = new InstEncoding[] + { + new(0x00300000, 0x00300000), + }; + + InstEncoding[] qvdQvnQvmSizeSizeConstraints = new InstEncoding[] + { + new(0x00001040, 0x00001040), + new(0x00010040, 0x00010040), + new(0x00000041, 0x00000041), + new(0x00000000, 0x00300000), + new(0x00300000, 0x00300000), + }; + + InstEncoding[] sizeSizeQvdQvnConstraints = new InstEncoding[] + { + new(0x00300000, 0x00300000), + new(0x00000000, 0x00300000), + new(0x01001000, 0x01001000), + new(0x01010000, 0x01010000), + }; + + InstEncoding[] opSizeVmConstraints = new InstEncoding[] + { + new(0x00000000, 0x000000C0), + new(0x000C0000, 0x000C0000), + new(0x00000001, 0x00000001), + }; + + InstEncoding[] qvdQvmQvnConstraints = new InstEncoding[] + { + new(0x00001040, 0x00001040), + new(0x00000041, 0x00000041), + new(0x00010040, 0x00010040), + }; + + InstEncoding[] imm6UopVmConstraints = new InstEncoding[] + { + new(0x00000000, 0x00380000), + new(0x00000000, 0x01000100), + new(0x00000001, 0x00000001), + }; + + InstEncoding[] imm6lUopQvdQvmConstraints = new InstEncoding[] + { + new(0x00000000, 0x00380080), + new(0x00000000, 0x01000100), + new(0x00001040, 0x00001040), + new(0x00000041, 0x00000041), + }; + + InstEncoding[] qvdQvmSizeSizeConstraints = new InstEncoding[] + { + new(0x00001040, 0x00001040), + new(0x00000041, 0x00000041), + new(0x00000000, 0x000C0000), + new(0x000C0000, 0x000C0000), + }; + + InstEncoding[] sizeSizeSizeQvdQvmConstraints = new InstEncoding[] + { + new(0x00040000, 0x000C0000), + new(0x00080000, 0x000C0000), + new(0x000C0000, 0x000C0000), + new(0x00001040, 0x00001040), + new(0x00000041, 0x00000041), + }; + + InstEncoding[] sizeSizeQvdQvmConstraints = new InstEncoding[] + { + new(0x00080000, 0x000C0000), + new(0x000C0000, 0x000C0000), + new(0x00001040, 0x00001040), + new(0x00000041, 0x00000041), + }; + + InstEncoding[] imm6lQvdQvmConstraints = new InstEncoding[] + { + new(0x00000000, 0x00380080), + new(0x00001040, 0x00001040), + new(0x00000041, 0x00000041), + }; + + InstEncoding[] imm6VmConstraints = new InstEncoding[] + { + new(0x00000000, 0x00380000), + new(0x00000001, 0x00000001), + }; + + InstEncoding[] imm6VdImm6Imm6Imm6Constraints = new InstEncoding[] + { + new(0x00000000, 0x00380000), + new(0x00001000, 0x00001000), + new(0x00080000, 0x003F0000), + new(0x00100000, 0x003F0000), + new(0x00200000, 0x003F0000), + }; + + InstEncoding[] sizeVdConstraints2 = new InstEncoding[] + { + new(0x000C0000, 0x000C0000), + new(0x00001000, 0x00001000), + }; + + InstEncoding[] sizeQsizeQvdQvmConstraints = new InstEncoding[] + { + new(0x000C0000, 0x000C0000), + new(0x00080000, 0x000C0040), + new(0x00001040, 0x00001040), + new(0x00000041, 0x00000041), + }; + + List insts = new() + { + new(0x02A00000, 0x0FE00000, condConstraints, InstName.AdcI, T.AdcIA1, IsaVersion.v80, InstFlags.CondRd), + new(0x00A00000, 0x0FE00010, condConstraints, InstName.AdcR, T.AdcRA1, IsaVersion.v80, InstFlags.CondRd), + new(0x00A00010, 0x0FE00090, condConstraints, InstName.AdcRr, T.AdcRrA1, IsaVersion.v80, InstFlags.CondRd), + new(0x02800000, 0x0FE00000, condRnsRnConstraints, InstName.AddI, T.AddIA1, IsaVersion.v80, InstFlags.CondRd), + new(0x00800000, 0x0FE00010, condRnConstraints, InstName.AddR, T.AddRA1, IsaVersion.v80, InstFlags.CondRd), + new(0x00800010, 0x0FE00090, condConstraints, InstName.AddRr, T.AddRrA1, IsaVersion.v80, InstFlags.CondRd), + new(0x028D0000, 0x0FEF0000, condConstraints, InstName.AddSpI, T.AddSpIA1, IsaVersion.v80, InstFlags.CondRd), + new(0x008D0000, 0x0FEF0010, condConstraints, InstName.AddSpR, T.AddSpRA1, IsaVersion.v80, InstFlags.CondRd), + new(0x028F0000, 0x0FFF0000, condConstraints, InstName.Adr, T.AdrA1, IsaVersion.v80, InstFlags.CondRd), + new(0x024F0000, 0x0FFF0000, condConstraints, InstName.Adr, T.AdrA2, IsaVersion.v80, InstFlags.CondRd), + new(0xF3B00340, 0xFFBF0FD0, vdVmConstraints, InstName.Aesd, T.AesdA1, IsaVersion.v80, IsaFeature.FeatAes, InstFlags.None), + new(0xF3B00300, 0xFFBF0FD0, vdVmConstraints, InstName.Aese, T.AeseA1, IsaVersion.v80, IsaFeature.FeatAes, InstFlags.None), + new(0xF3B003C0, 0xFFBF0FD0, vdVmConstraints, InstName.Aesimc, T.AesimcA1, IsaVersion.v80, IsaFeature.FeatAes, InstFlags.None), + new(0xF3B00380, 0xFFBF0FD0, vdVmConstraints, InstName.Aesmc, T.AesmcA1, IsaVersion.v80, IsaFeature.FeatAes, InstFlags.None), + new(0x02000000, 0x0FE00000, condConstraints, InstName.AndI, T.AndIA1, IsaVersion.v80, InstFlags.CondRd), + new(0x00000000, 0x0FE00010, condConstraints, InstName.AndR, T.AndRA1, IsaVersion.v80, InstFlags.CondRd), + new(0x00000010, 0x0FE00090, condConstraints, InstName.AndRr, T.AndRrA1, IsaVersion.v80, InstFlags.CondRd), + new(0x0A000000, 0x0F000000, condConstraints, InstName.B, T.BA1, IsaVersion.v80, InstFlags.Cond), + new(0x07C0001F, 0x0FE0007F, condConstraints, InstName.Bfc, T.BfcA1, IsaVersion.v80, InstFlags.CondRd), + new(0x07C00010, 0x0FE00070, condRnConstraints2, InstName.Bfi, T.BfiA1, IsaVersion.v80, InstFlags.CondRd), + new(0x03C00000, 0x0FE00000, condConstraints, InstName.BicI, T.BicIA1, IsaVersion.v80, InstFlags.CondRd), + new(0x01C00000, 0x0FE00010, condConstraints, InstName.BicR, T.BicRA1, IsaVersion.v80, InstFlags.CondRd), + new(0x01C00010, 0x0FE00090, condConstraints, InstName.BicRr, T.BicRrA1, IsaVersion.v80, InstFlags.CondRd), + new(0x01200070, 0x0FF000F0, condConstraints, InstName.Bkpt, T.BkptA1, IsaVersion.v80, InstFlags.Cond), + new(0x012FFF30, 0x0FFFFFF0, condConstraints, InstName.BlxR, T.BlxRA1, IsaVersion.v80, InstFlags.Cond), + new(0x0B000000, 0x0F000000, condConstraints, InstName.BlI, T.BlIA1, IsaVersion.v80, InstFlags.Cond), + new(0xFA000000, 0xFE000000, InstName.BlI, T.BlIA2, IsaVersion.v80, InstFlags.None), + new(0x012FFF10, 0x0FFFFFF0, condConstraints, InstName.Bx, T.BxA1, IsaVersion.v80, InstFlags.Cond), + new(0x012FFF20, 0x0FFFFFF0, condConstraints, InstName.Bxj, T.BxjA1, IsaVersion.v80, InstFlags.Cond), + new(0x0320F016, 0x0FFFFFFF, condConstraints, InstName.Clrbhb, T.ClrbhbA1, IsaVersion.v89, IsaFeature.FeatClrbhb, InstFlags.Cond), + new(0xF57FF01F, 0xFFFFFFFF, InstName.Clrex, T.ClrexA1, IsaVersion.v80, InstFlags.None), + new(0x016F0F10, 0x0FFF0FF0, condConstraints, InstName.Clz, T.ClzA1, IsaVersion.v80, InstFlags.CondRd), + new(0x03700000, 0x0FF0F000, condConstraints, InstName.CmnI, T.CmnIA1, IsaVersion.v80, InstFlags.Cond), + new(0x01700000, 0x0FF0F010, condConstraints, InstName.CmnR, T.CmnRA1, IsaVersion.v80, InstFlags.Cond), + new(0x01700010, 0x0FF0F090, condConstraints, InstName.CmnRr, T.CmnRrA1, IsaVersion.v80, InstFlags.Cond), + new(0x03500000, 0x0FF0F000, condConstraints, InstName.CmpI, T.CmpIA1, IsaVersion.v80, InstFlags.Cond), + new(0x01500000, 0x0FF0F010, condConstraints, InstName.CmpR, T.CmpRA1, IsaVersion.v80, InstFlags.Cond), + new(0x01500010, 0x0FF0F090, condConstraints, InstName.CmpRr, T.CmpRrA1, IsaVersion.v80, InstFlags.Cond), + new(0xF1000000, 0xFFF1FE20, InstName.Cps, T.CpsA1, IsaVersion.v80, InstFlags.None), + new(0x01000040, 0x0F900FF0, condConstraints, InstName.Crc32, T.Crc32A1, IsaVersion.v80, IsaFeature.FeatCrc32, InstFlags.CondRd), + new(0x01000240, 0x0F900FF0, condConstraints, InstName.Crc32c, T.Crc32cA1, IsaVersion.v80, IsaFeature.FeatCrc32, InstFlags.CondRd), + new(0x0320F014, 0x0FFFFFFF, condConstraints, InstName.Csdb, T.CsdbA1, IsaVersion.v80, InstFlags.Cond), + new(0x0320F0F0, 0x0FFFFFF0, condConstraints, InstName.Dbg, T.DbgA1, IsaVersion.v80, InstFlags.Cond), + new(0xF57FF050, 0xFFFFFFF0, InstName.Dmb, T.DmbA1, IsaVersion.v80, InstFlags.None), + new(0xF57FF040, 0xFFFFFFF0, optionConstraints, InstName.Dsb, T.DsbA1, IsaVersion.v80, InstFlags.None), + new(0x02200000, 0x0FE00000, condConstraints, InstName.EorI, T.EorIA1, IsaVersion.v80, InstFlags.CondRd), + new(0x00200000, 0x0FE00010, condConstraints, InstName.EorR, T.EorRA1, IsaVersion.v80, InstFlags.CondRd), + new(0x00200010, 0x0FE00090, condConstraints, InstName.EorRr, T.EorRrA1, IsaVersion.v80, InstFlags.CondRd), + new(0x0160006E, 0x0FFFFFFF, condConstraints, InstName.Eret, T.EretA1, IsaVersion.v80, InstFlags.Cond), + new(0x0320F010, 0x0FFFFFFF, condConstraints, InstName.Esb, T.EsbA1, IsaVersion.v82, IsaFeature.FeatRas, InstFlags.Cond), + new(0x0C100B01, 0x0E100F01, condPuwPwPuwPuwConstraints, InstName.Fldmx, T.FldmxA1, IsaVersion.v80, InstFlags.CondWBack), + new(0x0C000B01, 0x0E100F01, condPuwPwPuwPuwConstraints, InstName.Fstmx, T.FstmxA1, IsaVersion.v80, InstFlags.CondWBack), + new(0x01000070, 0x0FF000F0, condConstraints, InstName.Hlt, T.HltA1, IsaVersion.v80, InstFlags.Cond), + new(0x01400070, 0x0FF000F0, condConstraints, InstName.Hvc, T.HvcA1, IsaVersion.v80, InstFlags.Cond), + new(0xF57FF060, 0xFFFFFFF0, InstName.Isb, T.IsbA1, IsaVersion.v80, InstFlags.None), + new(0x01900C9F, 0x0FF00FFF, condConstraints, InstName.Lda, T.LdaA1, IsaVersion.v80, InstFlags.CondRt), + new(0x01D00C9F, 0x0FF00FFF, condConstraints, InstName.Ldab, T.LdabA1, IsaVersion.v80, InstFlags.CondRt), + new(0x01900E9F, 0x0FF00FFF, condConstraints, InstName.Ldaex, T.LdaexA1, IsaVersion.v80, InstFlags.CondRt), + new(0x01D00E9F, 0x0FF00FFF, condConstraints, InstName.Ldaexb, T.LdaexbA1, IsaVersion.v80, InstFlags.CondRt), + new(0x01B00E9F, 0x0FF00FFF, condConstraints, InstName.Ldaexd, T.LdaexdA1, IsaVersion.v80, InstFlags.CondRt2), + new(0x01F00E9F, 0x0FF00FFF, condConstraints, InstName.Ldaexh, T.LdaexhA1, IsaVersion.v80, InstFlags.CondRt), + new(0x01F00C9F, 0x0FF00FFF, condConstraints, InstName.Ldah, T.LdahA1, IsaVersion.v80, InstFlags.CondRt), + new(0x0C105E00, 0x0E50FF00, condRnPuwConstraints, InstName.LdcI, T.LdcIA1, IsaVersion.v80, InstFlags.CondWBack), + new(0x0C1F5E00, 0x0E5FFF00, condPuwConstraints, InstName.LdcL, T.LdcLA1, IsaVersion.v80, InstFlags.CondWBack), + new(0x08900000, 0x0FD00000, condConstraints, InstName.Ldm, T.LdmA1, IsaVersion.v80, InstFlags.CondRlistWBack), + new(0x08100000, 0x0FD00000, condConstraints, InstName.Ldmda, T.LdmdaA1, IsaVersion.v80, InstFlags.CondRlistWBack), + new(0x09100000, 0x0FD00000, condConstraints, InstName.Ldmdb, T.LdmdbA1, IsaVersion.v80, InstFlags.CondRlistWBack), + new(0x09900000, 0x0FD00000, condConstraints, InstName.Ldmib, T.LdmibA1, IsaVersion.v80, InstFlags.CondRlistWBack), + new(0x08508000, 0x0E508000, condConstraints, InstName.LdmE, T.LdmEA1, IsaVersion.v80, InstFlags.CondRlistWBack), + new(0x08500000, 0x0E708000, condConstraints, InstName.LdmU, T.LdmUA1, IsaVersion.v80, InstFlags.CondRlist), + new(0x04700000, 0x0F700000, condConstraints, InstName.Ldrbt, T.LdrbtA1, IsaVersion.v80, InstFlags.CondRt), + new(0x06700000, 0x0F700010, condConstraints, InstName.Ldrbt, T.LdrbtA2, IsaVersion.v80, InstFlags.CondRt), + new(0x04500000, 0x0E500000, condRnPwConstraints, InstName.LdrbI, T.LdrbIA1, IsaVersion.v80, InstFlags.CondRtWBack), + new(0x045F0000, 0x0E5F0000, condPwConstraints, InstName.LdrbL, T.LdrbLA1, IsaVersion.v80, InstFlags.CondRtWBack), + new(0x06500000, 0x0E500010, condPwConstraints, InstName.LdrbR, T.LdrbRA1, IsaVersion.v80, InstFlags.CondRtWBack), + new(0x004000D0, 0x0E5000F0, condRnConstraints3, InstName.LdrdI, T.LdrdIA1, IsaVersion.v80, InstFlags.CondRt2WBack), + new(0x014F00D0, 0x0F7F00F0, condConstraints, InstName.LdrdL, T.LdrdLA1, IsaVersion.v80, InstFlags.CondRt2), + new(0x000000D0, 0x0E500FF0, condConstraints, InstName.LdrdR, T.LdrdRA1, IsaVersion.v80, InstFlags.CondRt2WBack), + new(0x01900F9F, 0x0FF00FFF, condConstraints, InstName.Ldrex, T.LdrexA1, IsaVersion.v80, InstFlags.CondRt), + new(0x01D00F9F, 0x0FF00FFF, condConstraints, InstName.Ldrexb, T.LdrexbA1, IsaVersion.v80, InstFlags.CondRt), + new(0x01B00F9F, 0x0FF00FFF, condConstraints, InstName.Ldrexd, T.LdrexdA1, IsaVersion.v80, InstFlags.CondRt2), + new(0x01F00F9F, 0x0FF00FFF, condConstraints, InstName.Ldrexh, T.LdrexhA1, IsaVersion.v80, InstFlags.CondRt), + new(0x007000B0, 0x0F7000F0, condConstraints, InstName.Ldrht, T.LdrhtA1, IsaVersion.v80, InstFlags.CondRt), + new(0x003000B0, 0x0F700FF0, condConstraints, InstName.Ldrht, T.LdrhtA2, IsaVersion.v80, InstFlags.CondRt), + new(0x005000B0, 0x0E5000F0, condRnPwConstraints, InstName.LdrhI, T.LdrhIA1, IsaVersion.v80, InstFlags.CondRtWBack), + new(0x005F00B0, 0x0E5F00F0, condPwConstraints, InstName.LdrhL, T.LdrhLA1, IsaVersion.v80, InstFlags.CondRtWBack), + new(0x001000B0, 0x0E500FF0, condPwConstraints, InstName.LdrhR, T.LdrhRA1, IsaVersion.v80, InstFlags.CondRtWBack), + new(0x007000D0, 0x0F7000F0, condConstraints, InstName.Ldrsbt, T.LdrsbtA1, IsaVersion.v80, InstFlags.CondRt), + new(0x003000D0, 0x0F700FF0, condConstraints, InstName.Ldrsbt, T.LdrsbtA2, IsaVersion.v80, InstFlags.CondRt), + new(0x005000D0, 0x0E5000F0, condRnPwConstraints, InstName.LdrsbI, T.LdrsbIA1, IsaVersion.v80, InstFlags.CondRtWBack), + new(0x005F00D0, 0x0E5F00F0, condPwConstraints, InstName.LdrsbL, T.LdrsbLA1, IsaVersion.v80, InstFlags.CondRtWBack), + new(0x001000D0, 0x0E500FF0, condPwConstraints, InstName.LdrsbR, T.LdrsbRA1, IsaVersion.v80, InstFlags.CondRtWBack), + new(0x007000F0, 0x0F7000F0, condConstraints, InstName.Ldrsht, T.LdrshtA1, IsaVersion.v80, InstFlags.CondRt), + new(0x003000F0, 0x0F700FF0, condConstraints, InstName.Ldrsht, T.LdrshtA2, IsaVersion.v80, InstFlags.CondRt), + new(0x005000F0, 0x0E5000F0, condRnPwConstraints, InstName.LdrshI, T.LdrshIA1, IsaVersion.v80, InstFlags.CondRtWBack), + new(0x005F00F0, 0x0E5F00F0, condPwConstraints, InstName.LdrshL, T.LdrshLA1, IsaVersion.v80, InstFlags.CondRtWBack), + new(0x001000F0, 0x0E500FF0, condPwConstraints, InstName.LdrshR, T.LdrshRA1, IsaVersion.v80, InstFlags.CondRtWBack), + new(0x04300000, 0x0F700000, condConstraints, InstName.Ldrt, T.LdrtA1, IsaVersion.v80, InstFlags.CondRt), + new(0x06300000, 0x0F700010, condConstraints, InstName.Ldrt, T.LdrtA2, IsaVersion.v80, InstFlags.CondRt), + new(0x04100000, 0x0E500000, condRnPwConstraints, InstName.LdrI, T.LdrIA1, IsaVersion.v80, InstFlags.CondRtWBack), + new(0x041F0000, 0x0E5F0000, condPwConstraints, InstName.LdrL, T.LdrLA1, IsaVersion.v80, InstFlags.CondRtWBack), + new(0x06100000, 0x0E500010, condPwConstraints, InstName.LdrR, T.LdrRA1, IsaVersion.v80, InstFlags.CondRtWBack), + new(0x0E000E10, 0x0F100E10, condConstraints, InstName.Mcr, T.McrA1, IsaVersion.v80, InstFlags.CondRt), + new(0x0C400E00, 0x0FF00E00, condConstraints, InstName.Mcrr, T.McrrA1, IsaVersion.v80, InstFlags.CondRt), + new(0x00200090, 0x0FE000F0, condConstraints, InstName.Mla, T.MlaA1, IsaVersion.v80, InstFlags.CondRd16), + new(0x00600090, 0x0FF000F0, condConstraints, InstName.Mls, T.MlsA1, IsaVersion.v80, InstFlags.CondRd16), + new(0x03400000, 0x0FF00000, condConstraints, InstName.Movt, T.MovtA1, IsaVersion.v80, InstFlags.CondRd), + new(0x03A00000, 0x0FEF0000, condConstraints, InstName.MovI, T.MovIA1, IsaVersion.v80, InstFlags.CondRd), + new(0x03000000, 0x0FF00000, condConstraints, InstName.MovI, T.MovIA2, IsaVersion.v80, InstFlags.CondRd), + new(0x01A00000, 0x0FEF0010, condConstraints, InstName.MovR, T.MovRA1, IsaVersion.v80, InstFlags.CondRd), + new(0x01A00010, 0x0FEF0090, condConstraints, InstName.MovRr, T.MovRrA1, IsaVersion.v80, InstFlags.CondRd), + new(0x0E100E10, 0x0F100E10, condConstraints, InstName.Mrc, T.MrcA1, IsaVersion.v80, InstFlags.CondRt), + new(0x0C500E00, 0x0FF00E00, condConstraints, InstName.Mrrc, T.MrrcA1, IsaVersion.v80, InstFlags.CondRt), + new(0x010F0000, 0x0FBF0FFF, condConstraints, InstName.Mrs, T.MrsA1, IsaVersion.v80, InstFlags.CondRd), + new(0x01000200, 0x0FB00EFF, condConstraints, InstName.MrsBr, T.MrsBrA1, IsaVersion.v80, InstFlags.CondRd), + new(0x0120F200, 0x0FB0FEF0, condConstraints, InstName.MsrBr, T.MsrBrA1, IsaVersion.v80, InstFlags.Cond), + new(0x0320F000, 0x0FB0F000, condMaskrConstraints, InstName.MsrI, T.MsrIA1, IsaVersion.v80, InstFlags.Cond), + new(0x0120F000, 0x0FB0FFF0, condConstraints, InstName.MsrR, T.MsrRA1, IsaVersion.v80, InstFlags.Cond), + new(0x00000090, 0x0FE0F0F0, condConstraints, InstName.Mul, T.MulA1, IsaVersion.v80, InstFlags.CondRd16), + new(0x03E00000, 0x0FEF0000, condConstraints, InstName.MvnI, T.MvnIA1, IsaVersion.v80, InstFlags.CondRd), + new(0x01E00000, 0x0FEF0010, condConstraints, InstName.MvnR, T.MvnRA1, IsaVersion.v80, InstFlags.CondRd), + new(0x01E00010, 0x0FEF0090, condConstraints, InstName.MvnRr, T.MvnRrA1, IsaVersion.v80, InstFlags.CondRd), + new(0x0320F000, 0x0FFFFFFF, condConstraints, InstName.Nop, T.NopA1, IsaVersion.v80, InstFlags.Cond), + new(0x03800000, 0x0FE00000, condConstraints, InstName.OrrI, T.OrrIA1, IsaVersion.v80, InstFlags.CondRd), + new(0x01800000, 0x0FE00010, condConstraints, InstName.OrrR, T.OrrRA1, IsaVersion.v80, InstFlags.CondRd), + new(0x01800010, 0x0FE00090, condConstraints, InstName.OrrRr, T.OrrRrA1, IsaVersion.v80, InstFlags.CondRd), + new(0x06800010, 0x0FF00030, condConstraints, InstName.Pkh, T.PkhA1, IsaVersion.v80, InstFlags.CondRd), + new(0xF510F000, 0xFF30F000, rnConstraints, InstName.PldI, T.PldIA1, IsaVersion.v80, InstFlags.None), + new(0xF55FF000, 0xFF7FF000, InstName.PldL, T.PldLA1, IsaVersion.v80, InstFlags.None), + new(0xF710F000, 0xFF30F010, InstName.PldR, T.PldRA1, IsaVersion.v80, InstFlags.None), + new(0xF450F000, 0xFF70F000, InstName.PliI, T.PliIA1, IsaVersion.v80, InstFlags.None), + new(0xF650F000, 0xFF70F010, InstName.PliR, T.PliRA1, IsaVersion.v80, InstFlags.None), + new(0xF57FF044, 0xFFFFFFFF, InstName.Pssbb, T.PssbbA1, IsaVersion.v80, InstFlags.None), + new(0x01000050, 0x0FF00FF0, condConstraints, InstName.Qadd, T.QaddA1, IsaVersion.v80, InstFlags.CondRd), + new(0x06200F10, 0x0FF00FF0, condConstraints, InstName.Qadd16, T.Qadd16A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06200F90, 0x0FF00FF0, condConstraints, InstName.Qadd8, T.Qadd8A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06200F30, 0x0FF00FF0, condConstraints, InstName.Qasx, T.QasxA1, IsaVersion.v80, InstFlags.CondRd), + new(0x01400050, 0x0FF00FF0, condConstraints, InstName.Qdadd, T.QdaddA1, IsaVersion.v80, InstFlags.CondRd), + new(0x01600050, 0x0FF00FF0, condConstraints, InstName.Qdsub, T.QdsubA1, IsaVersion.v80, InstFlags.CondRd), + new(0x06200F50, 0x0FF00FF0, condConstraints, InstName.Qsax, T.QsaxA1, IsaVersion.v80, InstFlags.CondRd), + new(0x01200050, 0x0FF00FF0, condConstraints, InstName.Qsub, T.QsubA1, IsaVersion.v80, InstFlags.CondRd), + new(0x06200F70, 0x0FF00FF0, condConstraints, InstName.Qsub16, T.Qsub16A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06200FF0, 0x0FF00FF0, condConstraints, InstName.Qsub8, T.Qsub8A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06FF0F30, 0x0FFF0FF0, condConstraints, InstName.Rbit, T.RbitA1, IsaVersion.v80, InstFlags.CondRd), + new(0x06BF0F30, 0x0FFF0FF0, condConstraints, InstName.Rev, T.RevA1, IsaVersion.v80, InstFlags.CondRd), + new(0x06BF0FB0, 0x0FFF0FF0, condConstraints, InstName.Rev16, T.Rev16A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06FF0FB0, 0x0FFF0FF0, condConstraints, InstName.Revsh, T.RevshA1, IsaVersion.v80, InstFlags.CondRd), + new(0xF8100A00, 0xFE50FFFF, InstName.Rfe, T.RfeA1, IsaVersion.v80, InstFlags.WBack), + new(0x02600000, 0x0FE00000, condConstraints, InstName.RsbI, T.RsbIA1, IsaVersion.v80, InstFlags.CondRd), + new(0x00600000, 0x0FE00010, condConstraints, InstName.RsbR, T.RsbRA1, IsaVersion.v80, InstFlags.CondRd), + new(0x00600010, 0x0FE00090, condConstraints, InstName.RsbRr, T.RsbRrA1, IsaVersion.v80, InstFlags.CondRd), + new(0x02E00000, 0x0FE00000, condConstraints, InstName.RscI, T.RscIA1, IsaVersion.v80, InstFlags.CondRd), + new(0x00E00000, 0x0FE00010, condConstraints, InstName.RscR, T.RscRA1, IsaVersion.v80, InstFlags.CondRd), + new(0x00E00010, 0x0FE00090, condConstraints, InstName.RscRr, T.RscRrA1, IsaVersion.v80, InstFlags.CondRd), + new(0x06100F10, 0x0FF00FF0, condConstraints, InstName.Sadd16, T.Sadd16A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06100F90, 0x0FF00FF0, condConstraints, InstName.Sadd8, T.Sadd8A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06100F30, 0x0FF00FF0, condConstraints, InstName.Sasx, T.SasxA1, IsaVersion.v80, InstFlags.CondRd), + new(0xF57FF070, 0xFFFFFFFF, InstName.Sb, T.SbA1, IsaVersion.v85, IsaFeature.FeatSb, InstFlags.None), + new(0x02C00000, 0x0FE00000, condConstraints, InstName.SbcI, T.SbcIA1, IsaVersion.v80, InstFlags.CondRd), + new(0x00C00000, 0x0FE00010, condConstraints, InstName.SbcR, T.SbcRA1, IsaVersion.v80, InstFlags.CondRd), + new(0x00C00010, 0x0FE00090, condConstraints, InstName.SbcRr, T.SbcRrA1, IsaVersion.v80, InstFlags.CondRd), + new(0x07A00050, 0x0FE00070, condConstraints, InstName.Sbfx, T.SbfxA1, IsaVersion.v80, InstFlags.CondRd), + new(0x0710F010, 0x0FF0F0F0, condConstraints, InstName.Sdiv, T.SdivA1, IsaVersion.v80, InstFlags.CondRd16), + new(0x06800FB0, 0x0FF00FF0, condConstraints, InstName.Sel, T.SelA1, IsaVersion.v80, InstFlags.CondRd), + new(0xF1010000, 0xFFFFFDFF, InstName.Setend, T.SetendA1, IsaVersion.v80, InstFlags.None), + new(0xF1100000, 0xFFFFFDFF, InstName.Setpan, T.SetpanA1, IsaVersion.v81, IsaFeature.FeatPan, InstFlags.None), + new(0x0320F004, 0x0FFFFFFF, condConstraints, InstName.Sev, T.SevA1, IsaVersion.v80, InstFlags.Cond), + new(0x0320F005, 0x0FFFFFFF, condConstraints, InstName.Sevl, T.SevlA1, IsaVersion.v80, InstFlags.Cond), + new(0xF2000C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha1c, T.Sha1cA1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None), + new(0xF3B902C0, 0xFFBF0FD0, vdVmConstraints, InstName.Sha1h, T.Sha1hA1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None), + new(0xF2200C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha1m, T.Sha1mA1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None), + new(0xF2100C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha1p, T.Sha1pA1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None), + new(0xF2300C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha1su0, T.Sha1su0A1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None), + new(0xF3BA0380, 0xFFBF0FD0, vdVmConstraints, InstName.Sha1su1, T.Sha1su1A1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None), + new(0xF3000C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha256h, T.Sha256hA1, IsaVersion.v80, IsaFeature.FeatSha256, InstFlags.None), + new(0xF3100C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha256h2, T.Sha256h2A1, IsaVersion.v80, IsaFeature.FeatSha256, InstFlags.None), + new(0xF3BA03C0, 0xFFBF0FD0, vdVmConstraints, InstName.Sha256su0, T.Sha256su0A1, IsaVersion.v80, IsaFeature.FeatSha256, InstFlags.None), + new(0xF3200C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha256su1, T.Sha256su1A1, IsaVersion.v80, IsaFeature.FeatSha256, InstFlags.None), + new(0x06300F10, 0x0FF00FF0, condConstraints, InstName.Shadd16, T.Shadd16A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06300F90, 0x0FF00FF0, condConstraints, InstName.Shadd8, T.Shadd8A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06300F30, 0x0FF00FF0, condConstraints, InstName.Shasx, T.ShasxA1, IsaVersion.v80, InstFlags.CondRd), + new(0x06300F50, 0x0FF00FF0, condConstraints, InstName.Shsax, T.ShsaxA1, IsaVersion.v80, InstFlags.CondRd), + new(0x06300F70, 0x0FF00FF0, condConstraints, InstName.Shsub16, T.Shsub16A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06300FF0, 0x0FF00FF0, condConstraints, InstName.Shsub8, T.Shsub8A1, IsaVersion.v80, InstFlags.CondRd), + new(0x01600070, 0x0FFFFFF0, condConstraints, InstName.Smc, T.SmcA1, IsaVersion.v80, InstFlags.Cond), + new(0x01000080, 0x0FF00090, condConstraints, InstName.Smlabb, T.SmlabbA1, IsaVersion.v80, InstFlags.CondRd16), + new(0x07000010, 0x0FF000D0, condRaConstraints, InstName.Smlad, T.SmladA1, IsaVersion.v80, InstFlags.CondRd16), + new(0x00E00090, 0x0FE000F0, condConstraints, InstName.Smlal, T.SmlalA1, IsaVersion.v80, InstFlags.CondRdLoHi), + new(0x01400080, 0x0FF00090, condConstraints, InstName.Smlalbb, T.SmlalbbA1, IsaVersion.v80, InstFlags.CondRdLoHi), + new(0x07400010, 0x0FF000D0, condConstraints, InstName.Smlald, T.SmlaldA1, IsaVersion.v80, InstFlags.CondRdLoHi), + new(0x01200080, 0x0FF000B0, condConstraints, InstName.Smlawb, T.SmlawbA1, IsaVersion.v80, InstFlags.CondRd16), + new(0x07000050, 0x0FF000D0, condRaConstraints, InstName.Smlsd, T.SmlsdA1, IsaVersion.v80, InstFlags.CondRd16), + new(0x07400050, 0x0FF000D0, condConstraints, InstName.Smlsld, T.SmlsldA1, IsaVersion.v80, InstFlags.CondRdLoHi), + new(0x07500010, 0x0FF000D0, condRaConstraints, InstName.Smmla, T.SmmlaA1, IsaVersion.v80, InstFlags.CondRd16), + new(0x075000D0, 0x0FF000D0, condConstraints, InstName.Smmls, T.SmmlsA1, IsaVersion.v80, InstFlags.CondRd16), + new(0x0750F010, 0x0FF0F0D0, condConstraints, InstName.Smmul, T.SmmulA1, IsaVersion.v80, InstFlags.CondRd16), + new(0x0700F010, 0x0FF0F0D0, condConstraints, InstName.Smuad, T.SmuadA1, IsaVersion.v80, InstFlags.CondRd16), + new(0x01600080, 0x0FF0F090, condConstraints, InstName.Smulbb, T.SmulbbA1, IsaVersion.v80, InstFlags.CondRd16), + new(0x00C00090, 0x0FE000F0, condConstraints, InstName.Smull, T.SmullA1, IsaVersion.v80, InstFlags.CondRdLoHi), + new(0x012000A0, 0x0FF0F0B0, condConstraints, InstName.Smulwb, T.SmulwbA1, IsaVersion.v80, InstFlags.CondRd16), + new(0x0700F050, 0x0FF0F0D0, condConstraints, InstName.Smusd, T.SmusdA1, IsaVersion.v80, InstFlags.CondRd16), + new(0xF84D0500, 0xFE5FFFE0, InstName.Srs, T.SrsA1, IsaVersion.v80, InstFlags.WBack), + new(0x06A00010, 0x0FE00030, condConstraints, InstName.Ssat, T.SsatA1, IsaVersion.v80, InstFlags.CondRd), + new(0x06A00F30, 0x0FF00FF0, condConstraints, InstName.Ssat16, T.Ssat16A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06100F50, 0x0FF00FF0, condConstraints, InstName.Ssax, T.SsaxA1, IsaVersion.v80, InstFlags.CondRd), + new(0xF57FF040, 0xFFFFFFFF, InstName.Ssbb, T.SsbbA1, IsaVersion.v80, InstFlags.None), + new(0x06100F70, 0x0FF00FF0, condConstraints, InstName.Ssub16, T.Ssub16A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06100FF0, 0x0FF00FF0, condConstraints, InstName.Ssub8, T.Ssub8A1, IsaVersion.v80, InstFlags.CondRd), + new(0x0C005E00, 0x0E50FF00, condPuwConstraints, InstName.Stc, T.StcA1, IsaVersion.v80, InstFlags.CondWBack), + new(0x0180FC90, 0x0FF0FFF0, condConstraints, InstName.Stl, T.StlA1, IsaVersion.v80, InstFlags.CondRtRead), + new(0x01C0FC90, 0x0FF0FFF0, condConstraints, InstName.Stlb, T.StlbA1, IsaVersion.v80, InstFlags.CondRtRead), + new(0x01800E90, 0x0FF00FF0, condConstraints, InstName.Stlex, T.StlexA1, IsaVersion.v80, InstFlags.CondRdRtRead), + new(0x01C00E90, 0x0FF00FF0, condConstraints, InstName.Stlexb, T.StlexbA1, IsaVersion.v80, InstFlags.CondRdRtRead), + new(0x01A00E90, 0x0FF00FF0, condConstraints, InstName.Stlexd, T.StlexdA1, IsaVersion.v80, InstFlags.CondRdRt2Read), + new(0x01E00E90, 0x0FF00FF0, condConstraints, InstName.Stlexh, T.StlexhA1, IsaVersion.v80, InstFlags.CondRdRtRead), + new(0x01E0FC90, 0x0FF0FFF0, condConstraints, InstName.Stlh, T.StlhA1, IsaVersion.v80, InstFlags.CondRtRead), + new(0x08800000, 0x0FD00000, condConstraints, InstName.Stm, T.StmA1, IsaVersion.v80, InstFlags.CondRlistReadWBack), + new(0x08000000, 0x0FD00000, condConstraints, InstName.Stmda, T.StmdaA1, IsaVersion.v80, InstFlags.CondRlistReadWBack), + new(0x09000000, 0x0FD00000, condConstraints, InstName.Stmdb, T.StmdbA1, IsaVersion.v80, InstFlags.CondRlistReadWBack), + new(0x09800000, 0x0FD00000, condConstraints, InstName.Stmib, T.StmibA1, IsaVersion.v80, InstFlags.CondRlistReadWBack), + new(0x08400000, 0x0E700000, condConstraints, InstName.StmU, T.StmUA1, IsaVersion.v80, InstFlags.CondRlistRead), + new(0x04600000, 0x0F700000, condConstraints, InstName.Strbt, T.StrbtA1, IsaVersion.v80, InstFlags.CondRtRead), + new(0x06600000, 0x0F700010, condConstraints, InstName.Strbt, T.StrbtA2, IsaVersion.v80, InstFlags.CondRtRead), + new(0x04400000, 0x0E500000, condPwConstraints, InstName.StrbI, T.StrbIA1, IsaVersion.v80, InstFlags.CondRtReadWBack), + new(0x06400000, 0x0E500010, condPwConstraints, InstName.StrbR, T.StrbRA1, IsaVersion.v80, InstFlags.CondRtReadWBack), + new(0x004000F0, 0x0E5000F0, condConstraints, InstName.StrdI, T.StrdIA1, IsaVersion.v80, InstFlags.CondRt2ReadWBack), + new(0x000000F0, 0x0E500FF0, condConstraints, InstName.StrdR, T.StrdRA1, IsaVersion.v80, InstFlags.CondRt2ReadWBack), + new(0x01800F90, 0x0FF00FF0, condConstraints, InstName.Strex, T.StrexA1, IsaVersion.v80, InstFlags.CondRdRtRead), + new(0x01C00F90, 0x0FF00FF0, condConstraints, InstName.Strexb, T.StrexbA1, IsaVersion.v80, InstFlags.CondRdRtRead), + new(0x01A00F90, 0x0FF00FF0, condConstraints, InstName.Strexd, T.StrexdA1, IsaVersion.v80, InstFlags.CondRdRt2Read), + new(0x01E00F90, 0x0FF00FF0, condConstraints, InstName.Strexh, T.StrexhA1, IsaVersion.v80, InstFlags.CondRdRtRead), + new(0x006000B0, 0x0F7000F0, condConstraints, InstName.Strht, T.StrhtA1, IsaVersion.v80, InstFlags.CondRtRead), + new(0x002000B0, 0x0F700FF0, condConstraints, InstName.Strht, T.StrhtA2, IsaVersion.v80, InstFlags.CondRtRead), + new(0x004000B0, 0x0E5000F0, condPwConstraints, InstName.StrhI, T.StrhIA1, IsaVersion.v80, InstFlags.CondRtReadWBack), + new(0x000000B0, 0x0E500FF0, condPwConstraints, InstName.StrhR, T.StrhRA1, IsaVersion.v80, InstFlags.CondRtReadWBack), + new(0x04200000, 0x0F700000, condConstraints, InstName.Strt, T.StrtA1, IsaVersion.v80, InstFlags.CondRtRead), + new(0x06200000, 0x0F700010, condConstraints, InstName.Strt, T.StrtA2, IsaVersion.v80, InstFlags.CondRtRead), + new(0x04000000, 0x0E500000, condPwConstraints, InstName.StrI, T.StrIA1, IsaVersion.v80, InstFlags.CondRtReadWBack), + new(0x06000000, 0x0E500010, condPwConstraints, InstName.StrR, T.StrRA1, IsaVersion.v80, InstFlags.CondRtReadWBack), + new(0x02400000, 0x0FE00000, condRnsRnConstraints, InstName.SubI, T.SubIA1, IsaVersion.v80, InstFlags.CondRd), + new(0x00400000, 0x0FE00010, condRnConstraints, InstName.SubR, T.SubRA1, IsaVersion.v80, InstFlags.CondRd), + new(0x00400010, 0x0FE00090, condConstraints, InstName.SubRr, T.SubRrA1, IsaVersion.v80, InstFlags.CondRd), + new(0x024D0000, 0x0FEF0000, condConstraints, InstName.SubSpI, T.SubSpIA1, IsaVersion.v80, InstFlags.CondRd), + new(0x004D0000, 0x0FEF0010, condConstraints, InstName.SubSpR, T.SubSpRA1, IsaVersion.v80, InstFlags.CondRd), + new(0x0F000000, 0x0F000000, condConstraints, InstName.Svc, T.SvcA1, IsaVersion.v80, InstFlags.Cond), + new(0x06A00070, 0x0FF003F0, condRnConstraints3, InstName.Sxtab, T.SxtabA1, IsaVersion.v80, InstFlags.CondRd), + new(0x06800070, 0x0FF003F0, condRnConstraints3, InstName.Sxtab16, T.Sxtab16A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06B00070, 0x0FF003F0, condRnConstraints3, InstName.Sxtah, T.SxtahA1, IsaVersion.v80, InstFlags.CondRd), + new(0x06AF0070, 0x0FFF03F0, condConstraints, InstName.Sxtb, T.SxtbA1, IsaVersion.v80, InstFlags.CondRd), + new(0x068F0070, 0x0FFF03F0, condConstraints, InstName.Sxtb16, T.Sxtb16A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06BF0070, 0x0FFF03F0, condConstraints, InstName.Sxth, T.SxthA1, IsaVersion.v80, InstFlags.CondRd), + new(0x03300000, 0x0FF0F000, condConstraints, InstName.TeqI, T.TeqIA1, IsaVersion.v80, InstFlags.Cond), + new(0x01300000, 0x0FF0F010, condConstraints, InstName.TeqR, T.TeqRA1, IsaVersion.v80, InstFlags.Cond), + new(0x01300010, 0x0FF0F090, condConstraints, InstName.TeqRr, T.TeqRrA1, IsaVersion.v80, InstFlags.Cond), + new(0x0320F012, 0x0FFFFFFF, condConstraints, InstName.Tsb, T.TsbA1, IsaVersion.v84, IsaFeature.FeatTrf, InstFlags.Cond), + new(0x03100000, 0x0FF0F000, condConstraints, InstName.TstI, T.TstIA1, IsaVersion.v80, InstFlags.Cond), + new(0x01100000, 0x0FF0F010, condConstraints, InstName.TstR, T.TstRA1, IsaVersion.v80, InstFlags.Cond), + new(0x01100010, 0x0FF0F090, condConstraints, InstName.TstRr, T.TstRrA1, IsaVersion.v80, InstFlags.Cond), + new(0x06500F10, 0x0FF00FF0, condConstraints, InstName.Uadd16, T.Uadd16A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06500F90, 0x0FF00FF0, condConstraints, InstName.Uadd8, T.Uadd8A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06500F30, 0x0FF00FF0, condConstraints, InstName.Uasx, T.UasxA1, IsaVersion.v80, InstFlags.CondRd), + new(0x07E00050, 0x0FE00070, condConstraints, InstName.Ubfx, T.UbfxA1, IsaVersion.v80, InstFlags.CondRd), + new(0xE7F000F0, 0xFFF000F0, InstName.Udf, T.UdfA1, IsaVersion.v80, InstFlags.None), + new(0x0730F010, 0x0FF0F0F0, condConstraints, InstName.Udiv, T.UdivA1, IsaVersion.v80, InstFlags.CondRd16), + new(0x06700F10, 0x0FF00FF0, condConstraints, InstName.Uhadd16, T.Uhadd16A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06700F90, 0x0FF00FF0, condConstraints, InstName.Uhadd8, T.Uhadd8A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06700F30, 0x0FF00FF0, condConstraints, InstName.Uhasx, T.UhasxA1, IsaVersion.v80, InstFlags.CondRd), + new(0x06700F50, 0x0FF00FF0, condConstraints, InstName.Uhsax, T.UhsaxA1, IsaVersion.v80, InstFlags.CondRd), + new(0x06700F70, 0x0FF00FF0, condConstraints, InstName.Uhsub16, T.Uhsub16A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06700FF0, 0x0FF00FF0, condConstraints, InstName.Uhsub8, T.Uhsub8A1, IsaVersion.v80, InstFlags.CondRd), + new(0x00400090, 0x0FF000F0, condConstraints, InstName.Umaal, T.UmaalA1, IsaVersion.v80, InstFlags.CondRdLoHi), + new(0x00A00090, 0x0FE000F0, condConstraints, InstName.Umlal, T.UmlalA1, IsaVersion.v80, InstFlags.CondRdLoHi), + new(0x00800090, 0x0FE000F0, condConstraints, InstName.Umull, T.UmullA1, IsaVersion.v80, InstFlags.CondRdLoHi), + new(0x06600F10, 0x0FF00FF0, condConstraints, InstName.Uqadd16, T.Uqadd16A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06600F90, 0x0FF00FF0, condConstraints, InstName.Uqadd8, T.Uqadd8A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06600F30, 0x0FF00FF0, condConstraints, InstName.Uqasx, T.UqasxA1, IsaVersion.v80, InstFlags.CondRd), + new(0x06600F50, 0x0FF00FF0, condConstraints, InstName.Uqsax, T.UqsaxA1, IsaVersion.v80, InstFlags.CondRd), + new(0x06600F70, 0x0FF00FF0, condConstraints, InstName.Uqsub16, T.Uqsub16A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06600FF0, 0x0FF00FF0, condConstraints, InstName.Uqsub8, T.Uqsub8A1, IsaVersion.v80, InstFlags.CondRd), + new(0x0780F010, 0x0FF0F0F0, condConstraints, InstName.Usad8, T.Usad8A1, IsaVersion.v80, InstFlags.CondRd16), + new(0x07800010, 0x0FF000F0, condRaConstraints, InstName.Usada8, T.Usada8A1, IsaVersion.v80, InstFlags.CondRd16), + new(0x06E00010, 0x0FE00030, condConstraints, InstName.Usat, T.UsatA1, IsaVersion.v80, InstFlags.CondRd), + new(0x06E00F30, 0x0FF00FF0, condConstraints, InstName.Usat16, T.Usat16A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06500F50, 0x0FF00FF0, condConstraints, InstName.Usax, T.UsaxA1, IsaVersion.v80, InstFlags.CondRd), + new(0x06500F70, 0x0FF00FF0, condConstraints, InstName.Usub16, T.Usub16A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06500FF0, 0x0FF00FF0, condConstraints, InstName.Usub8, T.Usub8A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06E00070, 0x0FF003F0, condRnConstraints3, InstName.Uxtab, T.UxtabA1, IsaVersion.v80, InstFlags.CondRd), + new(0x06C00070, 0x0FF003F0, condRnConstraints3, InstName.Uxtab16, T.Uxtab16A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06F00070, 0x0FF003F0, condRnConstraints3, InstName.Uxtah, T.UxtahA1, IsaVersion.v80, InstFlags.CondRd), + new(0x06EF0070, 0x0FFF03F0, condConstraints, InstName.Uxtb, T.UxtbA1, IsaVersion.v80, InstFlags.CondRd), + new(0x06CF0070, 0x0FFF03F0, condConstraints, InstName.Uxtb16, T.Uxtb16A1, IsaVersion.v80, InstFlags.CondRd), + new(0x06FF0070, 0x0FFF03F0, condConstraints, InstName.Uxth, T.UxthA1, IsaVersion.v80, InstFlags.CondRd), + new(0xF2000710, 0xFE800F10, sizeQvdQvnQvmConstraints, InstName.Vaba, T.VabaA1, IsaVersion.v80, InstFlags.None), + new(0xF2800500, 0xFE800F50, sizeVdConstraints, InstName.Vabal, T.VabalA1, IsaVersion.v80, InstFlags.None), + new(0xF2800700, 0xFE800F50, sizeVdConstraints, InstName.VabdlI, T.VabdlIA1, IsaVersion.v80, InstFlags.None), + new(0xF3200D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VabdF, T.VabdFA1, IsaVersion.v80, InstFlags.None), + new(0xF3300D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VabdF, T.VabdFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF2000700, 0xFE800F10, sizeQvdQvnQvmConstraints, InstName.VabdI, T.VabdIA1, IsaVersion.v80, InstFlags.None), + new(0xF3B10300, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vabs, T.VabsA1, IsaVersion.v80, InstFlags.None), + new(0xF3B90700, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.Vabs, T.VabsA1, IsaVersion.v80, InstFlags.None), + new(0xF3B50700, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.Vabs, T.VabsA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0x0EB00AC0, 0x0FBF0ED0, condConstraints, InstName.Vabs, T.VabsA2, IsaVersion.v80, InstFlags.Cond), + new(0x0EB009C0, 0x0FBF0FD0, condConstraints, InstName.Vabs, T.VabsA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0xF3000E10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vacge, T.VacgeA1, IsaVersion.v80, InstFlags.None), + new(0xF3100E10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vacge, T.VacgeA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF3200E10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vacgt, T.VacgtA1, IsaVersion.v80, InstFlags.None), + new(0xF3300E10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vacgt, T.VacgtA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF2800400, 0xFF800F50, sizeVnVmConstraints, InstName.Vaddhn, T.VaddhnA1, IsaVersion.v80, InstFlags.None), + new(0xF2800000, 0xFE800F50, sizeVdOpvnConstraints, InstName.Vaddl, T.VaddlA1, IsaVersion.v80, InstFlags.None), + new(0xF2800100, 0xFE800F50, sizeVdOpvnConstraints, InstName.Vaddw, T.VaddwA1, IsaVersion.v80, InstFlags.None), + new(0xF2000D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VaddF, T.VaddFA1, IsaVersion.v80, InstFlags.None), + new(0xF2100D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VaddF, T.VaddFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0x0E300A00, 0x0FB00E50, condConstraints, InstName.VaddF, T.VaddFA2, IsaVersion.v80, InstFlags.Cond), + new(0x0E300900, 0x0FB00F50, condConstraints, InstName.VaddF, T.VaddFA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0xF2000800, 0xFF800F10, qvdQvnQvmConstraints, InstName.VaddI, T.VaddIA1, IsaVersion.v80, InstFlags.None), + new(0xF2000110, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VandR, T.VandRA1, IsaVersion.v80, InstFlags.None), + new(0xF2800130, 0xFEB809B0, cmodeCmodeQvdConstraints, InstName.VbicI, T.VbicIA1, IsaVersion.v80, InstFlags.None), + new(0xF2800930, 0xFEB80DB0, cmodeCmodeQvdConstraints, InstName.VbicI, T.VbicIA2, IsaVersion.v80, InstFlags.None), + new(0xF2100110, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VbicR, T.VbicRA1, IsaVersion.v80, InstFlags.None), + new(0xF3300110, 0xFFB00F10, qvdQvnQvmOpConstraints, InstName.Vbif, T.VbifA1, IsaVersion.v80, InstFlags.None), + new(0xF3200110, 0xFFB00F10, qvdQvnQvmOpConstraints, InstName.Vbit, T.VbitA1, IsaVersion.v80, InstFlags.None), + new(0xF3100110, 0xFFB00F10, qvdQvnQvmOpConstraints, InstName.Vbsl, T.VbslA1, IsaVersion.v80, InstFlags.None), + new(0xFC900800, 0xFEB00F10, qvdQvnQvmConstraints, InstName.Vcadd, T.VcaddA1, IsaVersion.v83, IsaFeature.FeatFcma, InstFlags.None), + new(0xFC800800, 0xFEB00F10, qvdQvnQvmConstraints, InstName.Vcadd, T.VcaddA1, IsaVersion.v83, IsaFeature.FeatFcma | IsaFeature.FeatFp16, InstFlags.None), + new(0xF3B10100, 0xFFB30F90, sizeQvdQvmConstraints, InstName.VceqI, T.VceqIA1, IsaVersion.v80, InstFlags.None), + new(0xF3B90500, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.VceqI, T.VceqIA1, IsaVersion.v80, InstFlags.None), + new(0xF3B50500, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.VceqI, T.VceqIA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF3000810, 0xFF800F10, qvdQvnQvmSizeConstraints, InstName.VceqR, T.VceqRA1, IsaVersion.v80, InstFlags.None), + new(0xF2000E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VceqR, T.VceqRA2, IsaVersion.v80, InstFlags.None), + new(0xF2100E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VceqR, T.VceqRA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF3B10080, 0xFFB30F90, sizeQvdQvmConstraints, InstName.VcgeI, T.VcgeIA1, IsaVersion.v80, InstFlags.None), + new(0xF3B90480, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.VcgeI, T.VcgeIA1, IsaVersion.v80, InstFlags.None), + new(0xF3B50480, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.VcgeI, T.VcgeIA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF2000310, 0xFE800F10, qvdQvnQvmSizeConstraints, InstName.VcgeR, T.VcgeRA1, IsaVersion.v80, InstFlags.None), + new(0xF3000E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VcgeR, T.VcgeRA2, IsaVersion.v80, InstFlags.None), + new(0xF3100E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VcgeR, T.VcgeRA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF3B10000, 0xFFB30F90, sizeQvdQvmConstraints, InstName.VcgtI, T.VcgtIA1, IsaVersion.v80, InstFlags.None), + new(0xF3B90400, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.VcgtI, T.VcgtIA1, IsaVersion.v80, InstFlags.None), + new(0xF3B50400, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.VcgtI, T.VcgtIA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF2000300, 0xFE800F10, qvdQvnQvmSizeConstraints, InstName.VcgtR, T.VcgtRA1, IsaVersion.v80, InstFlags.None), + new(0xF3200E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VcgtR, T.VcgtRA2, IsaVersion.v80, InstFlags.None), + new(0xF3300E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VcgtR, T.VcgtRA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF3B10180, 0xFFB30F90, sizeQvdQvmConstraints, InstName.VcleI, T.VcleIA1, IsaVersion.v80, InstFlags.None), + new(0xF3B90580, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.VcleI, T.VcleIA1, IsaVersion.v80, InstFlags.None), + new(0xF3B50580, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.VcleI, T.VcleIA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF3B00400, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vcls, T.VclsA1, IsaVersion.v80, InstFlags.None), + new(0xF3B10200, 0xFFB30F90, sizeQvdQvmConstraints, InstName.VcltI, T.VcltIA1, IsaVersion.v80, InstFlags.None), + new(0xF3B90600, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.VcltI, T.VcltIA1, IsaVersion.v80, InstFlags.None), + new(0xF3B50600, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.VcltI, T.VcltIA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF3B00480, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vclz, T.VclzA1, IsaVersion.v80, InstFlags.None), + new(0xFC200800, 0xFE200F10, qvdQvnQvmConstraints, InstName.Vcmla, T.VcmlaA1, IsaVersion.v83, IsaFeature.FeatFcma, InstFlags.None), + new(0xFE000800, 0xFF000F10, qvdQvnConstraints, InstName.VcmlaS, T.VcmlaSA1, IsaVersion.v83, IsaFeature.FeatFcma, InstFlags.None), + new(0x0EB40A40, 0x0FBF0ED0, condConstraints, InstName.Vcmp, T.VcmpA1, IsaVersion.v80, InstFlags.Cond), + new(0x0EB40940, 0x0FBF0FD0, condConstraints, InstName.Vcmp, T.VcmpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0x0EB50A40, 0x0FBF0EFF, condConstraints, InstName.Vcmp, T.VcmpA2, IsaVersion.v80, InstFlags.Cond), + new(0x0EB50940, 0x0FBF0FFF, condConstraints, InstName.Vcmp, T.VcmpA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0x0EB40AC0, 0x0FBF0ED0, condConstraints, InstName.Vcmpe, T.VcmpeA1, IsaVersion.v80, InstFlags.Cond), + new(0x0EB409C0, 0x0FBF0FD0, condConstraints, InstName.Vcmpe, T.VcmpeA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0x0EB50AC0, 0x0FBF0EFF, condConstraints, InstName.Vcmpe, T.VcmpeA2, IsaVersion.v80, InstFlags.Cond), + new(0x0EB509C0, 0x0FBF0FFF, condConstraints, InstName.Vcmpe, T.VcmpeA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0xF3B00500, 0xFFBF0F90, qvdQvmConstraints, InstName.Vcnt, T.VcntA1, IsaVersion.v80, InstFlags.None), + new(0xF3BB0000, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtaAsimd, T.VcvtaAsimdA1, IsaVersion.v80, InstFlags.None), + new(0xF3B70000, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtaAsimd, T.VcvtaAsimdA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFEBC0A40, 0xFFBF0E50, sizeConstraints, InstName.VcvtaVfp, T.VcvtaVfpA1, IsaVersion.v80, InstFlags.None), + new(0xFEBC0940, 0xFFBF0F50, sizeConstraints, InstName.VcvtaVfp, T.VcvtaVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0x0EB20A40, 0x0FBE0ED0, condConstraints, InstName.Vcvtb, T.VcvtbA1, IsaVersion.v80, InstFlags.Cond), + new(0x0EB30940, 0x0FBF0FD0, condConstraints, InstName.VcvtbBfs, T.VcvtbBfsA1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.Cond), + new(0xF3BB0300, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtmAsimd, T.VcvtmAsimdA1, IsaVersion.v80, InstFlags.None), + new(0xF3B70300, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtmAsimd, T.VcvtmAsimdA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFEBF0A40, 0xFFBF0E50, sizeConstraints, InstName.VcvtmVfp, T.VcvtmVfpA1, IsaVersion.v80, InstFlags.None), + new(0xFEBF0940, 0xFFBF0F50, sizeConstraints, InstName.VcvtmVfp, T.VcvtmVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF3BB0100, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtnAsimd, T.VcvtnAsimdA1, IsaVersion.v80, InstFlags.None), + new(0xF3B70100, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtnAsimd, T.VcvtnAsimdA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFEBD0A40, 0xFFBF0E50, sizeConstraints, InstName.VcvtnVfp, T.VcvtnVfpA1, IsaVersion.v80, InstFlags.None), + new(0xFEBD0940, 0xFFBF0F50, sizeConstraints, InstName.VcvtnVfp, T.VcvtnVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF3BB0200, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtpAsimd, T.VcvtpAsimdA1, IsaVersion.v80, InstFlags.None), + new(0xF3B70200, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtpAsimd, T.VcvtpAsimdA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFEBE0A40, 0xFFBF0E50, sizeConstraints, InstName.VcvtpVfp, T.VcvtpVfpA1, IsaVersion.v80, InstFlags.None), + new(0xFEBE0940, 0xFFBF0F50, sizeConstraints, InstName.VcvtpVfp, T.VcvtpVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0x0EBC0A40, 0x0FBE0ED0, condConstraints, InstName.VcvtrIv, T.VcvtrIvA1, IsaVersion.v80, InstFlags.Cond), + new(0x0EBC0940, 0x0FBE0FD0, condConstraints, InstName.VcvtrIv, T.VcvtrIvA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0x0EB20AC0, 0x0FBE0ED0, condConstraints, InstName.Vcvtt, T.VcvttA1, IsaVersion.v80, InstFlags.Cond), + new(0x0EB309C0, 0x0FBF0FD0, condConstraints, InstName.VcvttBfs, T.VcvttBfsA1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.Cond), + new(0xF3B60640, 0xFFBF0FD0, vmConstraints, InstName.VcvtBfs, T.VcvtBfsA1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None), + new(0x0EB70AC0, 0x0FBF0ED0, condConstraints, InstName.VcvtDs, T.VcvtDsA1, IsaVersion.v80, InstFlags.Cond), + new(0xF3B60600, 0xFFBF0ED0, opvdOpvmConstraints, InstName.VcvtHs, T.VcvtHsA1, IsaVersion.v80, InstFlags.None), + new(0xF3BB0600, 0xFFBF0E10, qvdQvmConstraints, InstName.VcvtIs, T.VcvtIsA1, IsaVersion.v80, InstFlags.None), + new(0xF3B70600, 0xFFBF0E10, qvdQvmConstraints, InstName.VcvtIs, T.VcvtIsA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0x0EBC0AC0, 0x0FBE0ED0, condConstraints, InstName.VcvtIv, T.VcvtIvA1, IsaVersion.v80, InstFlags.Cond), + new(0x0EBC09C0, 0x0FBE0FD0, condConstraints, InstName.VcvtIv, T.VcvtIvA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0x0EB80A40, 0x0FBF0E50, condConstraints, InstName.VcvtVi, T.VcvtViA1, IsaVersion.v80, InstFlags.Cond), + new(0x0EB80940, 0x0FBF0F50, condConstraints, InstName.VcvtVi, T.VcvtViA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0xF2800E10, 0xFE800E90, imm6Opimm6Imm6QvdQvmConstraints, InstName.VcvtXs, T.VcvtXsA1, IsaVersion.v80, InstFlags.None), + new(0xF2800C10, 0xFE800E90, imm6Opimm6Imm6QvdQvmConstraints, InstName.VcvtXs, T.VcvtXsA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0x0EBA0A40, 0x0FBA0E50, condConstraints, InstName.VcvtXv, T.VcvtXvA1, IsaVersion.v80, InstFlags.Cond), + new(0x0EBA0940, 0x0FBA0F50, condConstraints, InstName.VcvtXv, T.VcvtXvA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0x0E800A00, 0x0FB00E50, condConstraints, InstName.Vdiv, T.VdivA1, IsaVersion.v80, InstFlags.Cond), + new(0x0E800900, 0x0FB00F50, condConstraints, InstName.Vdiv, T.VdivA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0xFC000D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vdot, T.VdotA1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None), + new(0xFE000D00, 0xFFB00F10, qvdQvnConstraints, InstName.VdotS, T.VdotSA1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None), + new(0x0E800B10, 0x0F900F5F, condQvdEbConstraints, InstName.VdupR, T.VdupRA1, IsaVersion.v80, InstFlags.CondRtRead), + new(0xF3B00C00, 0xFFB00F90, imm4QvdConstraints, InstName.VdupS, T.VdupSA1, IsaVersion.v80, InstFlags.None), + new(0xF3000110, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Veor, T.VeorA1, IsaVersion.v80, InstFlags.None), + new(0xF2B00000, 0xFFB00010, qvdQvnQvmQimm4Constraints, InstName.Vext, T.VextA1, IsaVersion.v80, InstFlags.None), + new(0xF2000C10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vfma, T.VfmaA1, IsaVersion.v80, InstFlags.None), + new(0xF2100C10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vfma, T.VfmaA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0x0EA00A00, 0x0FB00E50, condConstraints, InstName.Vfma, T.VfmaA2, IsaVersion.v80, InstFlags.Cond), + new(0x0EA00900, 0x0FB00F50, condConstraints, InstName.Vfma, T.VfmaA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0xFC200810, 0xFFB00F10, qvdConstraints, InstName.Vfmal, T.VfmalA1, IsaVersion.v82, IsaFeature.FeatFhm, InstFlags.None), + new(0xFE000810, 0xFFB00F10, qvdConstraints, InstName.VfmalS, T.VfmalSA1, IsaVersion.v82, IsaFeature.FeatFhm, InstFlags.None), + new(0xFC300810, 0xFFB00F10, vdVnVmConstraints, InstName.VfmaBf, T.VfmaBfA1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None), + new(0xFE300810, 0xFFB00F10, vdVnConstraints, InstName.VfmaBfs, T.VfmaBfsA1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None), + new(0xF2200C10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vfms, T.VfmsA1, IsaVersion.v80, InstFlags.None), + new(0xF2300C10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vfms, T.VfmsA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0x0EA00A40, 0x0FB00E50, condConstraints, InstName.Vfms, T.VfmsA2, IsaVersion.v80, InstFlags.Cond), + new(0x0EA00940, 0x0FB00F50, condConstraints, InstName.Vfms, T.VfmsA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0xFCA00810, 0xFFB00F10, qvdConstraints, InstName.Vfmsl, T.VfmslA1, IsaVersion.v82, IsaFeature.FeatFhm, InstFlags.None), + new(0xFE100810, 0xFFB00F10, qvdConstraints, InstName.VfmslS, T.VfmslSA1, IsaVersion.v82, IsaFeature.FeatFhm, InstFlags.None), + new(0x0E900A40, 0x0FB00E50, condConstraints, InstName.Vfnma, T.VfnmaA1, IsaVersion.v80, InstFlags.Cond), + new(0x0E900940, 0x0FB00F50, condConstraints, InstName.Vfnma, T.VfnmaA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0x0E900A00, 0x0FB00E50, condConstraints, InstName.Vfnms, T.VfnmsA1, IsaVersion.v80, InstFlags.Cond), + new(0x0E900900, 0x0FB00F50, condConstraints, InstName.Vfnms, T.VfnmsA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0xF2000000, 0xFE800F10, qvdQvnQvmSizeConstraints, InstName.Vhadd, T.VhaddA1, IsaVersion.v80, InstFlags.None), + new(0xF2000200, 0xFE800F10, qvdQvnQvmSizeConstraints, InstName.Vhsub, T.VhsubA1, IsaVersion.v80, InstFlags.None), + new(0xFEB00AC0, 0xFFBF0FD0, InstName.Vins, T.VinsA1, IsaVersion.v82, IsaFeature.FeatFp16, InstFlags.None), + new(0x0EB90BC0, 0x0FBF0FD0, condConstraints, InstName.Vjcvt, T.VjcvtA1, IsaVersion.v83, IsaFeature.FeatJscvt, InstFlags.Cond), + new(0xF4A00000, 0xFFB00F10, sizeConstraints2, InstName.Vld11, T.Vld11A1, IsaVersion.v80, InstFlags.None), + new(0xF4A00400, 0xFFB00F20, sizeConstraints2, InstName.Vld11, T.Vld11A2, IsaVersion.v80, InstFlags.None), + new(0xF4A00800, 0xFFB00F40, sizeIndexAlignIndexAlignConstraints, InstName.Vld11, T.Vld11A3, IsaVersion.v80, InstFlags.None), + new(0xF4A00C00, 0xFFB00F00, sizeSizeaConstraints, InstName.Vld1A, T.Vld1AA1, IsaVersion.v80, InstFlags.None), + new(0xF4200700, 0xFFB00F00, alignConstraints, InstName.Vld1M, T.Vld1MA1, IsaVersion.v80, InstFlags.None), + new(0xF4200A00, 0xFFB00F00, alignConstraints2, InstName.Vld1M, T.Vld1MA2, IsaVersion.v80, InstFlags.None), + new(0xF4200600, 0xFFB00F00, alignConstraints, InstName.Vld1M, T.Vld1MA3, IsaVersion.v80, InstFlags.None), + new(0xF4200200, 0xFFB00F00, InstName.Vld1M, T.Vld1MA4, IsaVersion.v80, InstFlags.None), + new(0xF4A00100, 0xFFB00F00, sizeConstraints2, InstName.Vld21, T.Vld21A1, IsaVersion.v80, InstFlags.None), + new(0xF4A00500, 0xFFB00F00, sizeConstraints2, InstName.Vld21, T.Vld21A2, IsaVersion.v80, InstFlags.None), + new(0xF4A00900, 0xFFB00F20, sizeConstraints2, InstName.Vld21, T.Vld21A3, IsaVersion.v80, InstFlags.None), + new(0xF4A00D00, 0xFFB00F00, sizeConstraints3, InstName.Vld2A, T.Vld2AA1, IsaVersion.v80, InstFlags.None), + new(0xF4200800, 0xFFB00E00, alignSizeConstraints, InstName.Vld2M, T.Vld2MA1, IsaVersion.v80, InstFlags.None), + new(0xF4200300, 0xFFB00F00, sizeConstraints3, InstName.Vld2M, T.Vld2MA2, IsaVersion.v80, InstFlags.None), + new(0xF4A00200, 0xFFB00F10, sizeConstraints2, InstName.Vld31, T.Vld31A1, IsaVersion.v80, InstFlags.None), + new(0xF4A00600, 0xFFB00F10, sizeConstraints2, InstName.Vld31, T.Vld31A2, IsaVersion.v80, InstFlags.None), + new(0xF4A00A00, 0xFFB00F30, sizeConstraints2, InstName.Vld31, T.Vld31A3, IsaVersion.v80, InstFlags.None), + new(0xF4A00E00, 0xFFB00F10, sizeAConstraints, InstName.Vld3A, T.Vld3AA1, IsaVersion.v80, InstFlags.None), + new(0xF4200400, 0xFFB00E00, sizeAlignConstraints, InstName.Vld3M, T.Vld3MA1, IsaVersion.v80, InstFlags.None), + new(0xF4A00300, 0xFFB00F00, sizeConstraints2, InstName.Vld41, T.Vld41A1, IsaVersion.v80, InstFlags.None), + new(0xF4A00700, 0xFFB00F00, sizeConstraints2, InstName.Vld41, T.Vld41A2, IsaVersion.v80, InstFlags.None), + new(0xF4A00B00, 0xFFB00F00, sizeIndexAlignConstraints, InstName.Vld41, T.Vld41A3, IsaVersion.v80, InstFlags.None), + new(0xF4A00F00, 0xFFB00F00, sizeaConstraints, InstName.Vld4A, T.Vld4AA1, IsaVersion.v80, InstFlags.None), + new(0xF4200000, 0xFFB00E00, sizeConstraints3, InstName.Vld4M, T.Vld4MA1, IsaVersion.v80, InstFlags.None), + new(0x0C100B00, 0x0E100F01, condPuwPwPuwPuwConstraints, InstName.Vldm, T.VldmA1, IsaVersion.v80, InstFlags.CondWBack), + new(0x0C100A00, 0x0E100F00, condPuwPwPuwPuwConstraints, InstName.Vldm, T.VldmA2, IsaVersion.v80, InstFlags.CondWBack), + new(0x0D100A00, 0x0F300E00, condRnConstraints3, InstName.VldrI, T.VldrIA1, IsaVersion.v80, InstFlags.Cond), + new(0x0D100900, 0x0F300F00, condRnConstraints3, InstName.VldrI, T.VldrIA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0x0D1F0A00, 0x0F3F0E00, condConstraints, InstName.VldrL, T.VldrLA1, IsaVersion.v80, InstFlags.Cond), + new(0x0D1F0900, 0x0F3F0F00, condConstraints, InstName.VldrL, T.VldrLA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0xF3000F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vmaxnm, T.VmaxnmA1, IsaVersion.v80, InstFlags.None), + new(0xF3100F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vmaxnm, T.VmaxnmA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFE800A00, 0xFFB00E50, sizeConstraints, InstName.Vmaxnm, T.VmaxnmA2, IsaVersion.v80, InstFlags.None), + new(0xFE800900, 0xFFB00F50, sizeConstraints, InstName.Vmaxnm, T.VmaxnmA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF2000F00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmaxF, T.VmaxFA1, IsaVersion.v80, InstFlags.None), + new(0xF2100F00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmaxF, T.VmaxFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF2000600, 0xFE800F10, qvdQvnQvmSizeConstraints, InstName.VmaxI, T.VmaxIA1, IsaVersion.v80, InstFlags.None), + new(0xF3200F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vminnm, T.VminnmA1, IsaVersion.v80, InstFlags.None), + new(0xF3300F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vminnm, T.VminnmA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFE800A40, 0xFFB00E50, sizeConstraints, InstName.Vminnm, T.VminnmA2, IsaVersion.v80, InstFlags.None), + new(0xFE800940, 0xFFB00F50, sizeConstraints, InstName.Vminnm, T.VminnmA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF2200F00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VminF, T.VminFA1, IsaVersion.v80, InstFlags.None), + new(0xF2300F00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VminF, T.VminFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF2000610, 0xFE800F10, qvdQvnQvmSizeConstraints, InstName.VminI, T.VminIA1, IsaVersion.v80, InstFlags.None), + new(0xF2800800, 0xFE800F50, sizeVdConstraints, InstName.VmlalI, T.VmlalIA1, IsaVersion.v80, InstFlags.None), + new(0xF2800240, 0xFE800F50, sizeSizeVdConstraints, InstName.VmlalS, T.VmlalSA1, IsaVersion.v80, InstFlags.None), + new(0xF2000D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmlaF, T.VmlaFA1, IsaVersion.v80, InstFlags.None), + new(0xF2100D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmlaF, T.VmlaFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0x0E000A00, 0x0FB00E50, condConstraints, InstName.VmlaF, T.VmlaFA2, IsaVersion.v80, InstFlags.Cond), + new(0x0E000900, 0x0FB00F50, condConstraints, InstName.VmlaF, T.VmlaFA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0xF2000900, 0xFF800F10, sizeQvdQvnQvmConstraints, InstName.VmlaI, T.VmlaIA1, IsaVersion.v80, InstFlags.None), + new(0xF2A00040, 0xFEA00E50, sizeQvdQvnConstraints, InstName.VmlaS, T.VmlaSA1, IsaVersion.v80, InstFlags.None), + new(0xF2900040, 0xFEB00F50, sizeQvdQvnConstraints, InstName.VmlaS, T.VmlaSA1, IsaVersion.v80, InstFlags.None), + new(0xF2900140, 0xFEB00F50, sizeQvdQvnConstraints, InstName.VmlaS, T.VmlaSA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF2800A00, 0xFE800F50, sizeVdConstraints, InstName.VmlslI, T.VmlslIA1, IsaVersion.v80, InstFlags.None), + new(0xF2800640, 0xFE800F50, sizeSizeVdConstraints, InstName.VmlslS, T.VmlslSA1, IsaVersion.v80, InstFlags.None), + new(0xF2200D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmlsF, T.VmlsFA1, IsaVersion.v80, InstFlags.None), + new(0xF2300D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmlsF, T.VmlsFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0x0E000A40, 0x0FB00E50, condConstraints, InstName.VmlsF, T.VmlsFA2, IsaVersion.v80, InstFlags.Cond), + new(0x0E000940, 0x0FB00F50, condConstraints, InstName.VmlsF, T.VmlsFA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0xF3000900, 0xFF800F10, sizeQvdQvnQvmConstraints, InstName.VmlsI, T.VmlsIA1, IsaVersion.v80, InstFlags.None), + new(0xF2A00440, 0xFEA00E50, sizeQvdQvnConstraints, InstName.VmlsS, T.VmlsSA1, IsaVersion.v80, InstFlags.None), + new(0xF2900440, 0xFEB00F50, sizeQvdQvnConstraints, InstName.VmlsS, T.VmlsSA1, IsaVersion.v80, InstFlags.None), + new(0xF2900540, 0xFEB00F50, sizeQvdQvnConstraints, InstName.VmlsS, T.VmlsSA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFC000C40, 0xFFB00F50, vdVnVmConstraints, InstName.Vmmla, T.VmmlaA1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None), + new(0xF2800A10, 0xFE870FD0, imm3hImm3hImm3hImm3hImm3hVdConstraints, InstName.Vmovl, T.VmovlA1, IsaVersion.v80, InstFlags.None), + new(0xF3B20200, 0xFFB30FD0, sizeVmConstraints, InstName.Vmovn, T.VmovnA1, IsaVersion.v80, InstFlags.None), + new(0xFEB00A40, 0xFFBF0FD0, InstName.Vmovx, T.VmovxA1, IsaVersion.v82, IsaFeature.FeatFp16, InstFlags.None), + new(0x0C400B10, 0x0FE00FD0, condConstraints, InstName.VmovD, T.VmovDA1, IsaVersion.v80, InstFlags.CondRt2Read), + new(0x0E000910, 0x0FE00F7F, condConstraints, InstName.VmovH, T.VmovHA1, IsaVersion.v82, IsaFeature.FeatFp16, InstFlags.CondRt), + new(0xF2800010, 0xFEB809B0, qvdConstraints, InstName.VmovI, T.VmovIA1, IsaVersion.v80, InstFlags.None), + new(0x0EB00A00, 0x0FB00EF0, condConstraints, InstName.VmovI, T.VmovIA2, IsaVersion.v80, InstFlags.Cond), + new(0x0EB00900, 0x0FB00FF0, condConstraints, InstName.VmovI, T.VmovIA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0xF2800810, 0xFEB80DB0, qvdConstraints, InstName.VmovI, T.VmovIA3, IsaVersion.v80, InstFlags.None), + new(0xF2800C10, 0xFEB80CB0, qvdConstraints, InstName.VmovI, T.VmovIA4, IsaVersion.v80, InstFlags.None), + new(0xF2800E30, 0xFEB80FB0, qvdConstraints, InstName.VmovI, T.VmovIA5, IsaVersion.v80, InstFlags.None), + new(0x0EB00A40, 0x0FBF0ED0, condConstraints, InstName.VmovR, T.VmovRA2, IsaVersion.v80, InstFlags.Cond), + new(0x0E000B10, 0x0F900F1F, condOpc1opc2Constraints, InstName.VmovRs, T.VmovRsA1, IsaVersion.v80, InstFlags.CondRtRead), + new(0x0E000A10, 0x0FE00F7F, condConstraints, InstName.VmovS, T.VmovSA1, IsaVersion.v80, InstFlags.CondRtRead), + new(0x0E100B10, 0x0F100F1F, condUopc1opc2Uopc1opc2Constraints, InstName.VmovSr, T.VmovSrA1, IsaVersion.v80, InstFlags.CondRt), + new(0x0C400A10, 0x0FE00FD0, condConstraints, InstName.VmovSs, T.VmovSsA1, IsaVersion.v80, InstFlags.CondRt2Read), + new(0x0EF00A10, 0x0FF00FFF, condConstraints, InstName.Vmrs, T.VmrsA1, IsaVersion.v80, InstFlags.CondRt), + new(0x0EE00A10, 0x0FF00FFF, condConstraints, InstName.Vmsr, T.VmsrA1, IsaVersion.v80, InstFlags.CondRtRead), + new(0xF2800C00, 0xFE800D50, sizeOpuOpsizeVdConstraints, InstName.VmullI, T.VmullIA1, IsaVersion.v80, InstFlags.None), + new(0xF2800A40, 0xFE800F50, sizeSizeVdConstraints, InstName.VmullS, T.VmullSA1, IsaVersion.v80, InstFlags.None), + new(0xF3000D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmulF, T.VmulFA1, IsaVersion.v80, InstFlags.None), + new(0xF3100D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmulF, T.VmulFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0x0E200A00, 0x0FB00E50, condConstraints, InstName.VmulF, T.VmulFA2, IsaVersion.v80, InstFlags.Cond), + new(0x0E200900, 0x0FB00F50, condConstraints, InstName.VmulF, T.VmulFA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0xF2000910, 0xFE800F10, sizeOpsizeOpsizeQvdQvnQvmConstraints, InstName.VmulI, T.VmulIA1, IsaVersion.v80, InstFlags.None), + new(0xF2A00840, 0xFEA00E50, sizeQvdQvnConstraints, InstName.VmulS, T.VmulSA1, IsaVersion.v80, InstFlags.None), + new(0xF2900840, 0xFEB00F50, sizeQvdQvnConstraints, InstName.VmulS, T.VmulSA1, IsaVersion.v80, InstFlags.None), + new(0xF2900940, 0xFEB00F50, sizeQvdQvnConstraints, InstName.VmulS, T.VmulSA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF2800030, 0xFEB809B0, cmodeQvdConstraints, InstName.VmvnI, T.VmvnIA1, IsaVersion.v80, InstFlags.None), + new(0xF2800830, 0xFEB80DB0, cmodeQvdConstraints, InstName.VmvnI, T.VmvnIA2, IsaVersion.v80, InstFlags.None), + new(0xF2800C30, 0xFEB80EB0, cmodeQvdConstraints, InstName.VmvnI, T.VmvnIA3, IsaVersion.v80, InstFlags.None), + new(0xF3B00580, 0xFFBF0F90, qvdQvmConstraints, InstName.VmvnR, T.VmvnRA1, IsaVersion.v80, InstFlags.None), + new(0xF3B10380, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vneg, T.VnegA1, IsaVersion.v80, InstFlags.None), + new(0xF3B90780, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.Vneg, T.VnegA1, IsaVersion.v80, InstFlags.None), + new(0xF3B50780, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.Vneg, T.VnegA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0x0EB10A40, 0x0FBF0ED0, condConstraints, InstName.Vneg, T.VnegA2, IsaVersion.v80, InstFlags.Cond), + new(0x0EB10940, 0x0FBF0FD0, condConstraints, InstName.Vneg, T.VnegA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0x0E100A40, 0x0FB00E50, condConstraints, InstName.Vnmla, T.VnmlaA1, IsaVersion.v80, InstFlags.Cond), + new(0x0E100940, 0x0FB00F50, condConstraints, InstName.Vnmla, T.VnmlaA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0x0E100A00, 0x0FB00E50, condConstraints, InstName.Vnmls, T.VnmlsA1, IsaVersion.v80, InstFlags.Cond), + new(0x0E100900, 0x0FB00F50, condConstraints, InstName.Vnmls, T.VnmlsA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0x0E200A40, 0x0FB00E50, condConstraints, InstName.Vnmul, T.VnmulA1, IsaVersion.v80, InstFlags.Cond), + new(0x0E200940, 0x0FB00F50, condConstraints, InstName.Vnmul, T.VnmulA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0xF2300110, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VornR, T.VornRA1, IsaVersion.v80, InstFlags.None), + new(0xF2800110, 0xFEB809B0, cmodeCmodeQvdConstraints, InstName.VorrI, T.VorrIA1, IsaVersion.v80, InstFlags.None), + new(0xF2800910, 0xFEB80DB0, cmodeCmodeQvdConstraints, InstName.VorrI, T.VorrIA2, IsaVersion.v80, InstFlags.None), + new(0xF2200110, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VorrR, T.VorrRA1, IsaVersion.v80, InstFlags.None), + new(0xF3B00600, 0xFFB30F10, sizeQvdQvmConstraints, InstName.Vpadal, T.VpadalA1, IsaVersion.v80, InstFlags.None), + new(0xF3B00200, 0xFFB30F10, sizeQvdQvmConstraints, InstName.Vpaddl, T.VpaddlA1, IsaVersion.v80, InstFlags.None), + new(0xF3000D00, 0xFFB00F10, qConstraints, InstName.VpaddF, T.VpaddFA1, IsaVersion.v80, InstFlags.None), + new(0xF3100D00, 0xFFB00F10, qConstraints, InstName.VpaddF, T.VpaddFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF2000B10, 0xFF800F10, sizeQConstraints, InstName.VpaddI, T.VpaddIA1, IsaVersion.v80, InstFlags.None), + new(0xF3000F00, 0xFFB00F50, InstName.VpmaxF, T.VpmaxFA1, IsaVersion.v80, InstFlags.None), + new(0xF3100F00, 0xFFB00F50, InstName.VpmaxF, T.VpmaxFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF2000A00, 0xFE800F50, sizeConstraints4, InstName.VpmaxI, T.VpmaxIA1, IsaVersion.v80, InstFlags.None), + new(0xF3200F00, 0xFFB00F50, InstName.VpminF, T.VpminFA1, IsaVersion.v80, InstFlags.None), + new(0xF3300F00, 0xFFB00F50, InstName.VpminF, T.VpminFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF2000A10, 0xFE800F50, sizeConstraints4, InstName.VpminI, T.VpminIA1, IsaVersion.v80, InstFlags.None), + new(0xF3B00700, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vqabs, T.VqabsA1, IsaVersion.v80, InstFlags.None), + new(0xF2000010, 0xFE800F10, qvdQvnQvmConstraints, InstName.Vqadd, T.VqaddA1, IsaVersion.v80, InstFlags.None), + new(0xF2800900, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmlal, T.VqdmlalA1, IsaVersion.v80, InstFlags.None), + new(0xF2800340, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmlal, T.VqdmlalA2, IsaVersion.v80, InstFlags.None), + new(0xF2800B00, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmlsl, T.VqdmlslA1, IsaVersion.v80, InstFlags.None), + new(0xF2800740, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmlsl, T.VqdmlslA2, IsaVersion.v80, InstFlags.None), + new(0xF2000B00, 0xFF800F10, qvdQvnQvmSizeSizeConstraints, InstName.Vqdmulh, T.VqdmulhA1, IsaVersion.v80, InstFlags.None), + new(0xF2800C40, 0xFE800F50, sizeSizeQvdQvnConstraints, InstName.Vqdmulh, T.VqdmulhA2, IsaVersion.v80, InstFlags.None), + new(0xF2800D00, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmull, T.VqdmullA1, IsaVersion.v80, InstFlags.None), + new(0xF2800B40, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmull, T.VqdmullA2, IsaVersion.v80, InstFlags.None), + new(0xF3B20200, 0xFFB30F10, opSizeVmConstraints, InstName.Vqmovn, T.VqmovnA1, IsaVersion.v80, InstFlags.None), + new(0xF3B00780, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vqneg, T.VqnegA1, IsaVersion.v80, InstFlags.None), + new(0xF3000B10, 0xFF800F10, qvdQvnQvmSizeSizeConstraints, InstName.Vqrdmlah, T.VqrdmlahA1, IsaVersion.v81, IsaFeature.FeatRdm, InstFlags.None), + new(0xF2800E40, 0xFE800F50, sizeSizeQvdQvnConstraints, InstName.Vqrdmlah, T.VqrdmlahA2, IsaVersion.v81, IsaFeature.FeatRdm, InstFlags.None), + new(0xF3000C10, 0xFF800F10, qvdQvnQvmSizeSizeConstraints, InstName.Vqrdmlsh, T.VqrdmlshA1, IsaVersion.v81, IsaFeature.FeatRdm, InstFlags.None), + new(0xF2800F40, 0xFE800F50, sizeSizeQvdQvnConstraints, InstName.Vqrdmlsh, T.VqrdmlshA2, IsaVersion.v81, IsaFeature.FeatRdm, InstFlags.None), + new(0xF3000B00, 0xFF800F10, qvdQvnQvmSizeSizeConstraints, InstName.Vqrdmulh, T.VqrdmulhA1, IsaVersion.v80, InstFlags.None), + new(0xF2800D40, 0xFE800F50, sizeSizeQvdQvnConstraints, InstName.Vqrdmulh, T.VqrdmulhA2, IsaVersion.v80, InstFlags.None), + new(0xF2000510, 0xFE800F10, qvdQvmQvnConstraints, InstName.Vqrshl, T.VqrshlA1, IsaVersion.v80, InstFlags.None), + new(0xF2800850, 0xFE800ED0, imm6UopVmConstraints, InstName.Vqrshrn, T.VqrshrnA1, IsaVersion.v80, InstFlags.None), + new(0xF2800610, 0xFE800E10, imm6lUopQvdQvmConstraints, InstName.VqshlI, T.VqshlIA1, IsaVersion.v80, InstFlags.None), + new(0xF2000410, 0xFE800F10, qvdQvmQvnConstraints, InstName.VqshlR, T.VqshlRA1, IsaVersion.v80, InstFlags.None), + new(0xF2800810, 0xFE800ED0, imm6UopVmConstraints, InstName.Vqshrn, T.VqshrnA1, IsaVersion.v80, InstFlags.None), + new(0xF2000210, 0xFE800F10, qvdQvnQvmConstraints, InstName.Vqsub, T.VqsubA1, IsaVersion.v80, InstFlags.None), + new(0xF3800400, 0xFF800F50, sizeVnVmConstraints, InstName.Vraddhn, T.VraddhnA1, IsaVersion.v80, InstFlags.None), + new(0xF3B30400, 0xFFB30E90, qvdQvmSizeSizeConstraints, InstName.Vrecpe, T.VrecpeA1, IsaVersion.v80, InstFlags.None), + new(0xF2000F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vrecps, T.VrecpsA1, IsaVersion.v80, InstFlags.None), + new(0xF2100F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vrecps, T.VrecpsA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF3B00100, 0xFFB30F90, sizeSizeSizeQvdQvmConstraints, InstName.Vrev16, T.Vrev16A1, IsaVersion.v80, InstFlags.None), + new(0xF3B00080, 0xFFB30F90, sizeSizeQvdQvmConstraints, InstName.Vrev32, T.Vrev32A1, IsaVersion.v80, InstFlags.None), + new(0xF3B00000, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vrev64, T.Vrev64A1, IsaVersion.v80, InstFlags.None), + new(0xF2000100, 0xFE800F10, qvdQvnQvmSizeConstraints, InstName.Vrhadd, T.VrhaddA1, IsaVersion.v80, InstFlags.None), + new(0xF3BA0500, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintaAsimd, T.VrintaAsimdA1, IsaVersion.v80, InstFlags.None), + new(0xF3B60500, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintaAsimd, T.VrintaAsimdA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFEB80A40, 0xFFBF0ED0, sizeConstraints, InstName.VrintaVfp, T.VrintaVfpA1, IsaVersion.v80, InstFlags.None), + new(0xFEB80940, 0xFFBF0FD0, sizeConstraints, InstName.VrintaVfp, T.VrintaVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF3BA0680, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintmAsimd, T.VrintmAsimdA1, IsaVersion.v80, InstFlags.None), + new(0xF3B60680, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintmAsimd, T.VrintmAsimdA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFEBB0A40, 0xFFBF0ED0, sizeConstraints, InstName.VrintmVfp, T.VrintmVfpA1, IsaVersion.v80, InstFlags.None), + new(0xFEBB0940, 0xFFBF0FD0, sizeConstraints, InstName.VrintmVfp, T.VrintmVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF3BA0400, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintnAsimd, T.VrintnAsimdA1, IsaVersion.v80, InstFlags.None), + new(0xF3B60400, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintnAsimd, T.VrintnAsimdA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFEB90A40, 0xFFBF0ED0, sizeConstraints, InstName.VrintnVfp, T.VrintnVfpA1, IsaVersion.v80, InstFlags.None), + new(0xFEB90940, 0xFFBF0FD0, sizeConstraints, InstName.VrintnVfp, T.VrintnVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF3BA0780, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintpAsimd, T.VrintpAsimdA1, IsaVersion.v80, InstFlags.None), + new(0xF3B60780, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintpAsimd, T.VrintpAsimdA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFEBA0A40, 0xFFBF0ED0, sizeConstraints, InstName.VrintpVfp, T.VrintpVfpA1, IsaVersion.v80, InstFlags.None), + new(0xFEBA0940, 0xFFBF0FD0, sizeConstraints, InstName.VrintpVfp, T.VrintpVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0x0EB60A40, 0x0FBF0ED0, condConstraints, InstName.VrintrVfp, T.VrintrVfpA1, IsaVersion.v80, InstFlags.Cond), + new(0x0EB60940, 0x0FBF0FD0, condConstraints, InstName.VrintrVfp, T.VrintrVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0xF3BA0480, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintxAsimd, T.VrintxAsimdA1, IsaVersion.v80, InstFlags.None), + new(0xF3B60480, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintxAsimd, T.VrintxAsimdA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0x0EB70A40, 0x0FBF0ED0, condConstraints, InstName.VrintxVfp, T.VrintxVfpA1, IsaVersion.v80, InstFlags.Cond), + new(0x0EB70940, 0x0FBF0FD0, condConstraints, InstName.VrintxVfp, T.VrintxVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0xF3BA0580, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintzAsimd, T.VrintzAsimdA1, IsaVersion.v80, InstFlags.None), + new(0xF3B60580, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintzAsimd, T.VrintzAsimdA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0x0EB60AC0, 0x0FBF0ED0, condConstraints, InstName.VrintzVfp, T.VrintzVfpA1, IsaVersion.v80, InstFlags.Cond), + new(0x0EB609C0, 0x0FBF0FD0, condConstraints, InstName.VrintzVfp, T.VrintzVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0xF2000500, 0xFE800F10, qvdQvmQvnConstraints, InstName.Vrshl, T.VrshlA1, IsaVersion.v80, InstFlags.None), + new(0xF2800210, 0xFE800F10, imm6lQvdQvmConstraints, InstName.Vrshr, T.VrshrA1, IsaVersion.v80, InstFlags.None), + new(0xF2800850, 0xFF800FD0, imm6VmConstraints, InstName.Vrshrn, T.VrshrnA1, IsaVersion.v80, InstFlags.None), + new(0xF3B30480, 0xFFB30E90, qvdQvmSizeSizeConstraints, InstName.Vrsqrte, T.VrsqrteA1, IsaVersion.v80, InstFlags.None), + new(0xF2200F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vrsqrts, T.VrsqrtsA1, IsaVersion.v80, InstFlags.None), + new(0xF2300F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vrsqrts, T.VrsqrtsA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF2800310, 0xFE800F10, imm6lQvdQvmConstraints, InstName.Vrsra, T.VrsraA1, IsaVersion.v80, InstFlags.None), + new(0xF3800600, 0xFF800F50, sizeVnVmConstraints, InstName.Vrsubhn, T.VrsubhnA1, IsaVersion.v80, InstFlags.None), + new(0xFC200D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vsdot, T.VsdotA1, IsaVersion.v82, IsaFeature.FeatDotprod, InstFlags.None), + new(0xFE200D00, 0xFFB00F10, qvdQvnConstraints, InstName.VsdotS, T.VsdotSA1, IsaVersion.v82, IsaFeature.FeatDotprod, InstFlags.None), + new(0xFE000A00, 0xFF800E50, sizeConstraints, InstName.Vsel, T.VselA1, IsaVersion.v80, InstFlags.None), + new(0xFE000900, 0xFF800F50, sizeConstraints, InstName.Vsel, T.VselA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xF2800A10, 0xFE800FD0, imm6VdImm6Imm6Imm6Constraints, InstName.Vshll, T.VshllA1, IsaVersion.v80, InstFlags.None), + new(0xF3B20300, 0xFFB30FD0, sizeVdConstraints2, InstName.Vshll, T.VshllA2, IsaVersion.v80, InstFlags.None), + new(0xF2800510, 0xFF800F10, imm6lQvdQvmConstraints, InstName.VshlI, T.VshlIA1, IsaVersion.v80, InstFlags.None), + new(0xF2000400, 0xFE800F10, qvdQvmQvnConstraints, InstName.VshlR, T.VshlRA1, IsaVersion.v80, InstFlags.None), + new(0xF2800010, 0xFE800F10, imm6lQvdQvmConstraints, InstName.Vshr, T.VshrA1, IsaVersion.v80, InstFlags.None), + new(0xF2800810, 0xFF800FD0, imm6VmConstraints, InstName.Vshrn, T.VshrnA1, IsaVersion.v80, InstFlags.None), + new(0xF3800510, 0xFF800F10, imm6lQvdQvmConstraints, InstName.Vsli, T.VsliA1, IsaVersion.v80, InstFlags.None), + new(0xFC200C40, 0xFFB00F50, vdVnVmConstraints, InstName.Vsmmla, T.VsmmlaA1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None), + new(0x0EB10AC0, 0x0FBF0ED0, condConstraints, InstName.Vsqrt, T.VsqrtA1, IsaVersion.v80, InstFlags.Cond), + new(0x0EB109C0, 0x0FBF0FD0, condConstraints, InstName.Vsqrt, T.VsqrtA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0xF2800110, 0xFE800F10, imm6lQvdQvmConstraints, InstName.Vsra, T.VsraA1, IsaVersion.v80, InstFlags.None), + new(0xF3800410, 0xFF800F10, imm6lQvdQvmConstraints, InstName.Vsri, T.VsriA1, IsaVersion.v80, InstFlags.None), + new(0xF4800000, 0xFFB00F10, sizeConstraints2, InstName.Vst11, T.Vst11A1, IsaVersion.v80, InstFlags.None), + new(0xF4800400, 0xFFB00F20, sizeConstraints2, InstName.Vst11, T.Vst11A2, IsaVersion.v80, InstFlags.None), + new(0xF4800800, 0xFFB00F40, sizeIndexAlignIndexAlignConstraints, InstName.Vst11, T.Vst11A3, IsaVersion.v80, InstFlags.None), + new(0xF4000700, 0xFFB00F00, alignConstraints, InstName.Vst1M, T.Vst1MA1, IsaVersion.v80, InstFlags.None), + new(0xF4000A00, 0xFFB00F00, alignConstraints2, InstName.Vst1M, T.Vst1MA2, IsaVersion.v80, InstFlags.None), + new(0xF4000600, 0xFFB00F00, alignConstraints, InstName.Vst1M, T.Vst1MA3, IsaVersion.v80, InstFlags.None), + new(0xF4000200, 0xFFB00F00, InstName.Vst1M, T.Vst1MA4, IsaVersion.v80, InstFlags.None), + new(0xF4800100, 0xFFB00F00, sizeConstraints2, InstName.Vst21, T.Vst21A1, IsaVersion.v80, InstFlags.None), + new(0xF4800500, 0xFFB00F00, sizeConstraints2, InstName.Vst21, T.Vst21A2, IsaVersion.v80, InstFlags.None), + new(0xF4800900, 0xFFB00F20, sizeConstraints2, InstName.Vst21, T.Vst21A3, IsaVersion.v80, InstFlags.None), + new(0xF4000800, 0xFFB00E00, alignSizeConstraints, InstName.Vst2M, T.Vst2MA1, IsaVersion.v80, InstFlags.None), + new(0xF4000300, 0xFFB00F00, sizeConstraints3, InstName.Vst2M, T.Vst2MA2, IsaVersion.v80, InstFlags.None), + new(0xF4800200, 0xFFB00F10, sizeConstraints2, InstName.Vst31, T.Vst31A1, IsaVersion.v80, InstFlags.None), + new(0xF4800600, 0xFFB00F10, sizeConstraints2, InstName.Vst31, T.Vst31A2, IsaVersion.v80, InstFlags.None), + new(0xF4800A00, 0xFFB00F30, sizeConstraints2, InstName.Vst31, T.Vst31A3, IsaVersion.v80, InstFlags.None), + new(0xF4000400, 0xFFB00E00, sizeAlignConstraints, InstName.Vst3M, T.Vst3MA1, IsaVersion.v80, InstFlags.None), + new(0xF4800300, 0xFFB00F00, sizeConstraints2, InstName.Vst41, T.Vst41A1, IsaVersion.v80, InstFlags.None), + new(0xF4800700, 0xFFB00F00, sizeConstraints2, InstName.Vst41, T.Vst41A2, IsaVersion.v80, InstFlags.None), + new(0xF4800B00, 0xFFB00F00, sizeIndexAlignConstraints, InstName.Vst41, T.Vst41A3, IsaVersion.v80, InstFlags.None), + new(0xF4000000, 0xFFB00E00, sizeConstraints3, InstName.Vst4M, T.Vst4MA1, IsaVersion.v80, InstFlags.None), + new(0x0C000B00, 0x0E100F01, condPuwPwPuwPuwConstraints, InstName.Vstm, T.VstmA1, IsaVersion.v80, InstFlags.CondWBack), + new(0x0C000A00, 0x0E100F00, condPuwPwPuwPuwConstraints, InstName.Vstm, T.VstmA2, IsaVersion.v80, InstFlags.CondWBack), + new(0x0D000A00, 0x0F300E00, condConstraints, InstName.Vstr, T.VstrA1, IsaVersion.v80, InstFlags.Cond), + new(0x0D000900, 0x0F300F00, condConstraints, InstName.Vstr, T.VstrA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0xF2800600, 0xFF800F50, sizeVnVmConstraints, InstName.Vsubhn, T.VsubhnA1, IsaVersion.v80, InstFlags.None), + new(0xF2800200, 0xFE800F50, sizeVdOpvnConstraints, InstName.Vsubl, T.VsublA1, IsaVersion.v80, InstFlags.None), + new(0xF2800300, 0xFE800F50, sizeVdOpvnConstraints, InstName.Vsubw, T.VsubwA1, IsaVersion.v80, InstFlags.None), + new(0xF2200D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VsubF, T.VsubFA1, IsaVersion.v80, InstFlags.None), + new(0xF2300D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VsubF, T.VsubFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0x0E300A40, 0x0FB00E50, condConstraints, InstName.VsubF, T.VsubFA2, IsaVersion.v80, InstFlags.Cond), + new(0x0E300940, 0x0FB00F50, condConstraints, InstName.VsubF, T.VsubFA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond), + new(0xF3000800, 0xFF800F10, qvdQvnQvmConstraints, InstName.VsubI, T.VsubIA1, IsaVersion.v80, InstFlags.None), + new(0xFE800D10, 0xFFB00F10, qvdQvnConstraints, InstName.VsudotS, T.VsudotSA1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None), + new(0xF3B20000, 0xFFBF0F90, qvdQvmConstraints, InstName.Vswp, T.VswpA1, IsaVersion.v80, InstFlags.None), + new(0xF3B00800, 0xFFB00C10, InstName.Vtbl, T.VtblA1, IsaVersion.v80, InstFlags.None), + new(0xF3B20080, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vtrn, T.VtrnA1, IsaVersion.v80, InstFlags.None), + new(0xF2000810, 0xFF800F10, qvdQvnQvmSizeConstraints, InstName.Vtst, T.VtstA1, IsaVersion.v80, InstFlags.None), + new(0xFC200D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vudot, T.VudotA1, IsaVersion.v82, IsaFeature.FeatDotprod, InstFlags.None), + new(0xFE200D10, 0xFFB00F10, qvdQvnConstraints, InstName.VudotS, T.VudotSA1, IsaVersion.v82, IsaFeature.FeatDotprod, InstFlags.None), + new(0xFC200C50, 0xFFB00F50, vdVnVmConstraints, InstName.Vummla, T.VummlaA1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None), + new(0xFCA00D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vusdot, T.VusdotA1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None), + new(0xFE800D00, 0xFFB00F10, qvdQvnConstraints, InstName.VusdotS, T.VusdotSA1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None), + new(0xFCA00C40, 0xFFB00F50, vdVnVmConstraints, InstName.Vusmmla, T.VusmmlaA1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None), + new(0xF3B20100, 0xFFB30F90, sizeQsizeQvdQvmConstraints, InstName.Vuzp, T.VuzpA1, IsaVersion.v80, InstFlags.None), + new(0xF3B20180, 0xFFB30F90, sizeQsizeQvdQvmConstraints, InstName.Vzip, T.VzipA1, IsaVersion.v80, InstFlags.None), + new(0x0320F002, 0x0FFFFFFF, condConstraints, InstName.Wfe, T.WfeA1, IsaVersion.v80, InstFlags.Cond), + new(0x0320F003, 0x0FFFFFFF, condConstraints, InstName.Wfi, T.WfiA1, IsaVersion.v80, InstFlags.Cond), + new(0x0320F001, 0x0FFFFFFF, condConstraints, InstName.Yield, T.YieldA1, IsaVersion.v80, InstFlags.Cond), + }; + + _table = new(insts); + } + + public static InstMeta GetMeta(uint encoding, IsaVersion version, IsaFeature features) + { + if (_table.TryFind(encoding, version, features, out InstInfoForTable info)) + { + return info.Meta; + } + + return new(InstName.Udf, T.UdfA1, IsaVersion.v80, IsaFeature.None, InstFlags.None); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/InstTableT16.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/InstTableT16.cs new file mode 100644 index 000000000..7ff5f6c90 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/InstTableT16.cs @@ -0,0 +1,146 @@ +using Ryujinx.Cpu.LightningJit.Table; +using System.Collections.Generic; + +namespace Ryujinx.Cpu.LightningJit.Arm32 +{ + static class InstTableT16 where T : IInstEmit + { + private static readonly InstTableLevel _table; + + static InstTableT16() + { + InstEncoding[] rmRdndnConstraints = new InstEncoding[] + { + new(0x00680000, 0x00780000), + new(0x00850000, 0x00870000), + }; + + InstEncoding[] rmConstraints = new InstEncoding[] + { + new(0x00680000, 0x00780000), + }; + + InstEncoding[] condCondConstraints = new InstEncoding[] + { + new(0x0E000000, 0x0F000000), + new(0x0F000000, 0x0F000000), + }; + + InstEncoding[] maskConstraints = new InstEncoding[] + { + new(0x00000000, 0x000F0000), + }; + + InstEncoding[] opConstraints = new InstEncoding[] + { + new(0x18000000, 0x18000000), + }; + + InstEncoding[] opOpOpOpConstraints = new InstEncoding[] + { + new(0x00000000, 0x03C00000), + new(0x00400000, 0x03C00000), + new(0x01400000, 0x03C00000), + new(0x01800000, 0x03C00000), + }; + + List insts = new() + { + new(0x41400000, 0xFFC00000, InstName.AdcR, T.AdcRT1, IsaVersion.v80, InstFlags.Rdn), + new(0x1C000000, 0xFE000000, InstName.AddI, T.AddIT1, IsaVersion.v80, InstFlags.Rd), + new(0x30000000, 0xF8000000, InstName.AddI, T.AddIT2, IsaVersion.v80, InstFlags.Rdn), + new(0x18000000, 0xFE000000, InstName.AddR, T.AddRT1, IsaVersion.v80, InstFlags.Rd), + new(0x44000000, 0xFF000000, rmRdndnConstraints, InstName.AddR, T.AddRT2, IsaVersion.v80, InstFlags.RdnDn), + new(0xA8000000, 0xF8000000, InstName.AddSpI, T.AddSpIT1, IsaVersion.v80, InstFlags.RdRd16), + new(0xB0000000, 0xFF800000, InstName.AddSpI, T.AddSpIT2, IsaVersion.v80, InstFlags.None), + new(0x44680000, 0xFF780000, InstName.AddSpR, T.AddSpRT1, IsaVersion.v80, InstFlags.None), + new(0x44850000, 0xFF870000, rmConstraints, InstName.AddSpR, T.AddSpRT2, IsaVersion.v80, InstFlags.None), + new(0xA0000000, 0xF8000000, InstName.Adr, T.AdrT1, IsaVersion.v80, InstFlags.RdRd16), + new(0x40000000, 0xFFC00000, InstName.AndR, T.AndRT1, IsaVersion.v80, InstFlags.Rdn), + new(0xD0000000, 0xF0000000, condCondConstraints, InstName.B, T.BT1, IsaVersion.v80, InstFlags.Cond), + new(0xE0000000, 0xF8000000, InstName.B, T.BT2, IsaVersion.v80, InstFlags.None), + new(0x43800000, 0xFFC00000, InstName.BicR, T.BicRT1, IsaVersion.v80, InstFlags.Rdn), + new(0xBE000000, 0xFF000000, InstName.Bkpt, T.BkptT1, IsaVersion.v80, InstFlags.None), + new(0x47800000, 0xFF870000, InstName.BlxR, T.BlxRT1, IsaVersion.v80, InstFlags.None), + new(0x47000000, 0xFF870000, InstName.Bx, T.BxT1, IsaVersion.v80, InstFlags.None), + new(0xB1000000, 0xF5000000, InstName.Cbnz, T.CbnzT1, IsaVersion.v80, InstFlags.None), + new(0x42C00000, 0xFFC00000, InstName.CmnR, T.CmnRT1, IsaVersion.v80, InstFlags.None), + new(0x28000000, 0xF8000000, InstName.CmpI, T.CmpIT1, IsaVersion.v80, InstFlags.None), + new(0x42800000, 0xFFC00000, InstName.CmpR, T.CmpRT1, IsaVersion.v80, InstFlags.None), + new(0x45000000, 0xFF000000, InstName.CmpR, T.CmpRT2, IsaVersion.v80, InstFlags.None), + new(0xB6600000, 0xFFE80000, InstName.Cps, T.CpsT1, IsaVersion.v80, InstFlags.None), + new(0x40400000, 0xFFC00000, InstName.EorR, T.EorRT1, IsaVersion.v80, InstFlags.Rdn), + new(0xBA800000, 0xFFC00000, InstName.Hlt, T.HltT1, IsaVersion.v80, InstFlags.None), + new(0xBF000000, 0xFF000000, maskConstraints, InstName.It, T.ItT1, IsaVersion.v80, InstFlags.None), + new(0xC8000000, 0xF8000000, InstName.Ldm, T.LdmT1, IsaVersion.v80, InstFlags.Rlist), + new(0x78000000, 0xF8000000, InstName.LdrbI, T.LdrbIT1, IsaVersion.v80, InstFlags.Rt), + new(0x5C000000, 0xFE000000, InstName.LdrbR, T.LdrbRT1, IsaVersion.v80, InstFlags.Rt), + new(0x88000000, 0xF8000000, InstName.LdrhI, T.LdrhIT1, IsaVersion.v80, InstFlags.Rt), + new(0x5A000000, 0xFE000000, InstName.LdrhR, T.LdrhRT1, IsaVersion.v80, InstFlags.Rt), + new(0x56000000, 0xFE000000, InstName.LdrsbR, T.LdrsbRT1, IsaVersion.v80, InstFlags.Rt), + new(0x5E000000, 0xFE000000, InstName.LdrshR, T.LdrshRT1, IsaVersion.v80, InstFlags.Rt), + new(0x68000000, 0xF8000000, InstName.LdrI, T.LdrIT1, IsaVersion.v80, InstFlags.Rt), + new(0x98000000, 0xF8000000, InstName.LdrI, T.LdrIT2, IsaVersion.v80, InstFlags.RtRd16), + new(0x48000000, 0xF8000000, InstName.LdrL, T.LdrLT1, IsaVersion.v80, InstFlags.RtRd16), + new(0x58000000, 0xFE000000, InstName.LdrR, T.LdrRT1, IsaVersion.v80, InstFlags.Rt), + new(0x20000000, 0xF8000000, InstName.MovI, T.MovIT1, IsaVersion.v80, InstFlags.RdRd16), + new(0x46000000, 0xFF000000, InstName.MovR, T.MovRT1, IsaVersion.v80, InstFlags.Rd), + new(0x00000000, 0xE0000000, opConstraints, InstName.MovR, T.MovRT2, IsaVersion.v80, InstFlags.Rd), + new(0x40000000, 0xFE000000, opOpOpOpConstraints, InstName.MovRr, T.MovRrT1, IsaVersion.v80, InstFlags.None), + new(0x43400000, 0xFFC00000, InstName.Mul, T.MulT1, IsaVersion.v80, InstFlags.None), + new(0x43C00000, 0xFFC00000, InstName.MvnR, T.MvnRT1, IsaVersion.v80, InstFlags.Rd), + new(0xBF000000, 0xFFFF0000, InstName.Nop, T.NopT1, IsaVersion.v80, InstFlags.None), + new(0x43000000, 0xFFC00000, InstName.OrrR, T.OrrRT1, IsaVersion.v80, InstFlags.Rdn), + new(0xBC000000, 0xFE000000, InstName.Pop, T.PopT1, IsaVersion.v80, InstFlags.Rlist), + new(0xB4000000, 0xFE000000, InstName.Push, T.PushT1, IsaVersion.v80, InstFlags.RlistRead), + new(0xBA000000, 0xFFC00000, InstName.Rev, T.RevT1, IsaVersion.v80, InstFlags.Rd), + new(0xBA400000, 0xFFC00000, InstName.Rev16, T.Rev16T1, IsaVersion.v80, InstFlags.Rd), + new(0xBAC00000, 0xFFC00000, InstName.Revsh, T.RevshT1, IsaVersion.v80, InstFlags.Rd), + new(0x42400000, 0xFFC00000, InstName.RsbI, T.RsbIT1, IsaVersion.v80, InstFlags.Rd), + new(0x41800000, 0xFFC00000, InstName.SbcR, T.SbcRT1, IsaVersion.v80, InstFlags.Rdn), + new(0xB6500000, 0xFFF70000, InstName.Setend, T.SetendT1, IsaVersion.v80, InstFlags.None), + new(0xB6100000, 0xFFF70000, InstName.Setpan, T.SetpanT1, IsaVersion.v81, IsaFeature.FeatPan, InstFlags.None), + new(0xBF400000, 0xFFFF0000, InstName.Sev, T.SevT1, IsaVersion.v80, InstFlags.None), + new(0xBF500000, 0xFFFF0000, InstName.Sevl, T.SevlT1, IsaVersion.v80, InstFlags.None), + new(0xC0000000, 0xF8000000, InstName.Stm, T.StmT1, IsaVersion.v80, InstFlags.RlistRead), + new(0x70000000, 0xF8000000, InstName.StrbI, T.StrbIT1, IsaVersion.v80, InstFlags.RtRead), + new(0x54000000, 0xFE000000, InstName.StrbR, T.StrbRT1, IsaVersion.v80, InstFlags.RtRead), + new(0x80000000, 0xF8000000, InstName.StrhI, T.StrhIT1, IsaVersion.v80, InstFlags.RtRead), + new(0x52000000, 0xFE000000, InstName.StrhR, T.StrhRT1, IsaVersion.v80, InstFlags.RtRead), + new(0x60000000, 0xF8000000, InstName.StrI, T.StrIT1, IsaVersion.v80, InstFlags.RtRead), + new(0x90000000, 0xF8000000, InstName.StrI, T.StrIT2, IsaVersion.v80, InstFlags.RtReadRd16), + new(0x50000000, 0xFE000000, InstName.StrR, T.StrRT1, IsaVersion.v80, InstFlags.RtRead), + new(0x1E000000, 0xFE000000, InstName.SubI, T.SubIT1, IsaVersion.v80, InstFlags.Rd), + new(0x38000000, 0xF8000000, InstName.SubI, T.SubIT2, IsaVersion.v80, InstFlags.Rdn), + new(0x1A000000, 0xFE000000, InstName.SubR, T.SubRT1, IsaVersion.v80, InstFlags.Rd), + new(0xB0800000, 0xFF800000, InstName.SubSpI, T.SubSpIT1, IsaVersion.v80, InstFlags.None), + new(0xDF000000, 0xFF000000, InstName.Svc, T.SvcT1, IsaVersion.v80, InstFlags.None), + new(0xB2400000, 0xFFC00000, InstName.Sxtb, T.SxtbT1, IsaVersion.v80, InstFlags.Rd), + new(0xB2000000, 0xFFC00000, InstName.Sxth, T.SxthT1, IsaVersion.v80, InstFlags.Rd), + new(0x42000000, 0xFFC00000, InstName.TstR, T.TstRT1, IsaVersion.v80, InstFlags.None), + new(0xDE000000, 0xFF000000, InstName.Udf, T.UdfT1, IsaVersion.v80, InstFlags.None), + new(0xB2C00000, 0xFFC00000, InstName.Uxtb, T.UxtbT1, IsaVersion.v80, InstFlags.Rd), + new(0xB2800000, 0xFFC00000, InstName.Uxth, T.UxthT1, IsaVersion.v80, InstFlags.Rd), + new(0xBF200000, 0xFFFF0000, InstName.Wfe, T.WfeT1, IsaVersion.v80, InstFlags.None), + new(0xBF300000, 0xFFFF0000, InstName.Wfi, T.WfiT1, IsaVersion.v80, InstFlags.None), + new(0xBF100000, 0xFFFF0000, InstName.Yield, T.YieldT1, IsaVersion.v80, InstFlags.None), + }; + + _table = new(insts); + } + + public static bool TryGetMeta(uint encoding, IsaVersion version, IsaFeature features, out InstMeta meta) + { + if (_table.TryFind(encoding, version, features, out InstInfoForTable info)) + { + meta = info.Meta; + + return true; + } + + meta = new(InstName.Udf, T.UdfA1, IsaVersion.v80, IsaFeature.None, InstFlags.None); + + return false; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/InstTableT32.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/InstTableT32.cs new file mode 100644 index 000000000..4a11effdb --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/InstTableT32.cs @@ -0,0 +1,1212 @@ +using Ryujinx.Cpu.LightningJit.Table; +using System.Collections.Generic; + +namespace Ryujinx.Cpu.LightningJit.Arm32 +{ + static class InstTableT32 where T : IInstEmit + { + private static readonly InstTableLevel _table; + + static InstTableT32() + { + InstEncoding[] rnRdsConstraints = new InstEncoding[] + { + new(0x000D0000, 0x000F0000), + new(0x00100F00, 0x00100F00), + }; + + InstEncoding[] rnRnConstraints = new InstEncoding[] + { + new(0x000D0000, 0x000F0000), + new(0x000F0000, 0x000F0000), + }; + + InstEncoding[] rdsConstraints = new InstEncoding[] + { + new(0x00100F00, 0x00100F00), + }; + + InstEncoding[] vdVmConstraints = new InstEncoding[] + { + new(0x00001000, 0x00001000), + new(0x00000001, 0x00000001), + }; + + InstEncoding[] condCondCondConstraints = new InstEncoding[] + { + new(0x03800000, 0x03C00000), + new(0x03C00000, 0x03C00000), + new(0x03800000, 0x03800000), + }; + + InstEncoding[] rnConstraints = new InstEncoding[] + { + new(0x000F0000, 0x000F0000), + }; + + InstEncoding[] hConstraints = new InstEncoding[] + { + new(0x00000001, 0x00000001), + }; + + InstEncoding[] imodmConstraints = new InstEncoding[] + { + new(0x00000000, 0x00000700), + }; + + InstEncoding[] optionConstraints = new InstEncoding[] + { + new(0x00000000, 0x0000000F), + }; + + InstEncoding[] puwPwPuwPuwConstraints = new InstEncoding[] + { + new(0x00000000, 0x01A00000), + new(0x01000000, 0x01200000), + new(0x00200000, 0x01A00000), + new(0x01A00000, 0x01A00000), + }; + + InstEncoding[] rnPuwConstraints = new InstEncoding[] + { + new(0x000F0000, 0x000F0000), + new(0x00000000, 0x01A00000), + }; + + InstEncoding[] puwConstraints = new InstEncoding[] + { + new(0x00000000, 0x01A00000), + }; + + InstEncoding[] rnRtConstraints = new InstEncoding[] + { + new(0x000F0000, 0x000F0000), + new(0x0000F000, 0x0000F000), + }; + + InstEncoding[] rnRtpuwPuwPwConstraints = new InstEncoding[] + { + new(0x000F0000, 0x000F0000), + new(0x0000F400, 0x0000F700), + new(0x00000600, 0x00000700), + new(0x00000000, 0x00000500), + }; + + InstEncoding[] rtConstraints = new InstEncoding[] + { + new(0x0000F000, 0x0000F000), + }; + + InstEncoding[] rnPwConstraints = new InstEncoding[] + { + new(0x000F0000, 0x000F0000), + new(0x00000000, 0x01200000), + }; + + InstEncoding[] pwConstraints = new InstEncoding[] + { + new(0x00000000, 0x01200000), + }; + + InstEncoding[] rnPuwPwConstraints = new InstEncoding[] + { + new(0x000F0000, 0x000F0000), + new(0x00000600, 0x00000700), + new(0x00000000, 0x00000500), + }; + + InstEncoding[] raConstraints = new InstEncoding[] + { + new(0x0000F000, 0x0000F000), + }; + + InstEncoding[] sTConstraints = new InstEncoding[] + { + new(0x00100000, 0x00100000), + new(0x00000010, 0x00000010), + }; + + InstEncoding[] vdVnVmConstraints = new InstEncoding[] + { + new(0x00001000, 0x00001000), + new(0x00010000, 0x00010000), + new(0x00000001, 0x00000001), + }; + + InstEncoding[] shimm2imm3Constraints = new InstEncoding[] + { + new(0x00200000, 0x002070C0), + }; + + InstEncoding[] rnimm8Constraints = new InstEncoding[] + { + new(0x000E0000, 0x000F00FF), + }; + + InstEncoding[] sizeQvdQvnQvmConstraints = new InstEncoding[] + { + new(0x00300000, 0x00300000), + new(0x00001040, 0x00001040), + new(0x00010040, 0x00010040), + new(0x00000041, 0x00000041), + }; + + InstEncoding[] sizeVdConstraints = new InstEncoding[] + { + new(0x00300000, 0x00300000), + new(0x00001000, 0x00001000), + }; + + InstEncoding[] qvdQvnQvmConstraints = new InstEncoding[] + { + new(0x00001040, 0x00001040), + new(0x00010040, 0x00010040), + new(0x00000041, 0x00000041), + }; + + InstEncoding[] sizeQvdQvmConstraints = new InstEncoding[] + { + new(0x000C0000, 0x000C0000), + new(0x00001040, 0x00001040), + new(0x00000041, 0x00000041), + }; + + InstEncoding[] sizeVnVmConstraints = new InstEncoding[] + { + new(0x00300000, 0x00300000), + new(0x00010000, 0x00010000), + new(0x00000001, 0x00000001), + }; + + InstEncoding[] sizeVdOpvnConstraints = new InstEncoding[] + { + new(0x00300000, 0x00300000), + new(0x00001000, 0x00001000), + new(0x00010100, 0x00010100), + }; + + InstEncoding[] cmodeCmodeQvdConstraints = new InstEncoding[] + { + new(0x00000000, 0x00000100), + new(0x00000C00, 0x00000C00), + new(0x00001040, 0x00001040), + }; + + InstEncoding[] qvdQvnQvmOpConstraints = new InstEncoding[] + { + new(0x00001040, 0x00001040), + new(0x00010040, 0x00010040), + new(0x00000041, 0x00000041), + new(0x00000000, 0x00300000), + }; + + InstEncoding[] qvdQvnQvmSizeConstraints = new InstEncoding[] + { + new(0x00001040, 0x00001040), + new(0x00010040, 0x00010040), + new(0x00000041, 0x00000041), + new(0x00300000, 0x00300000), + }; + + InstEncoding[] qvdQvnConstraints = new InstEncoding[] + { + new(0x00001040, 0x00001040), + new(0x00010040, 0x00010040), + }; + + InstEncoding[] qvdQvmConstraints = new InstEncoding[] + { + new(0x00001040, 0x00001040), + new(0x00000041, 0x00000041), + }; + + InstEncoding[] sizeConstraints = new InstEncoding[] + { + new(0x00000000, 0x00000300), + }; + + InstEncoding[] vmConstraints = new InstEncoding[] + { + new(0x00000001, 0x00000001), + }; + + InstEncoding[] opvdOpvmConstraints = new InstEncoding[] + { + new(0x00001100, 0x00001100), + new(0x00000001, 0x00000101), + }; + + InstEncoding[] imm6Opimm6Imm6QvdQvmConstraints = new InstEncoding[] + { + new(0x00000000, 0x00380000), + new(0x00200000, 0x00300200), + new(0x00000000, 0x00200000), + new(0x00001040, 0x00001040), + new(0x00000041, 0x00000041), + }; + + InstEncoding[] qvdEbConstraints = new InstEncoding[] + { + new(0x00210000, 0x00210000), + new(0x00400020, 0x00400020), + }; + + InstEncoding[] imm4QvdConstraints = new InstEncoding[] + { + new(0x00000000, 0x00070000), + new(0x00001040, 0x00001040), + }; + + InstEncoding[] qvdQvnQvmQimm4Constraints = new InstEncoding[] + { + new(0x00001040, 0x00001040), + new(0x00010040, 0x00010040), + new(0x00000041, 0x00000041), + new(0x00000800, 0x00000840), + }; + + InstEncoding[] qvdConstraints = new InstEncoding[] + { + new(0x00001040, 0x00001040), + }; + + InstEncoding[] vdVnConstraints = new InstEncoding[] + { + new(0x00001000, 0x00001000), + new(0x00010000, 0x00010000), + }; + + InstEncoding[] sizeConstraints2 = new InstEncoding[] + { + new(0x00000C00, 0x00000C00), + }; + + InstEncoding[] sizeIndexAlignIndexAlignConstraints = new InstEncoding[] + { + new(0x00000C00, 0x00000C00), + new(0x00000010, 0x00000030), + new(0x00000020, 0x00000030), + }; + + InstEncoding[] sizeSizeaConstraints = new InstEncoding[] + { + new(0x000000C0, 0x000000C0), + new(0x00000010, 0x000000D0), + }; + + InstEncoding[] alignConstraints = new InstEncoding[] + { + new(0x00000020, 0x00000020), + }; + + InstEncoding[] alignConstraints2 = new InstEncoding[] + { + new(0x00000030, 0x00000030), + }; + + InstEncoding[] sizeConstraints3 = new InstEncoding[] + { + new(0x000000C0, 0x000000C0), + }; + + InstEncoding[] alignSizeConstraints = new InstEncoding[] + { + new(0x00000030, 0x00000030), + new(0x000000C0, 0x000000C0), + }; + + InstEncoding[] sizeAConstraints = new InstEncoding[] + { + new(0x000000C0, 0x000000C0), + new(0x00000010, 0x00000010), + }; + + InstEncoding[] sizeAlignConstraints = new InstEncoding[] + { + new(0x000000C0, 0x000000C0), + new(0x00000020, 0x00000020), + }; + + InstEncoding[] sizeIndexAlignConstraints = new InstEncoding[] + { + new(0x00000C00, 0x00000C00), + new(0x00000030, 0x00000030), + }; + + InstEncoding[] sizeaConstraints = new InstEncoding[] + { + new(0x000000C0, 0x000000D0), + }; + + InstEncoding[] sizeSizeVdConstraints = new InstEncoding[] + { + new(0x00300000, 0x00300000), + new(0x00000000, 0x00300000), + new(0x00001000, 0x00001000), + }; + + InstEncoding[] sizeQvdQvnConstraints = new InstEncoding[] + { + new(0x00300000, 0x00300000), + new(0x10001000, 0x10001000), + new(0x10010000, 0x10010000), + }; + + InstEncoding[] imm3hImm3hImm3hImm3hImm3hVdConstraints = new InstEncoding[] + { + new(0x00000000, 0x00380000), + new(0x00180000, 0x00380000), + new(0x00280000, 0x00380000), + new(0x00300000, 0x00380000), + new(0x00380000, 0x00380000), + new(0x00001000, 0x00001000), + }; + + InstEncoding[] sizeVmConstraints = new InstEncoding[] + { + new(0x000C0000, 0x000C0000), + new(0x00000001, 0x00000001), + }; + + InstEncoding[] opc1opc2Constraints = new InstEncoding[] + { + new(0x00000040, 0x00400060), + }; + + InstEncoding[] uopc1opc2Uopc1opc2Constraints = new InstEncoding[] + { + new(0x00800000, 0x00C00060), + new(0x00000040, 0x00400060), + }; + + InstEncoding[] sizeOpuOpsizeVdConstraints = new InstEncoding[] + { + new(0x00300000, 0x00300000), + new(0x10000200, 0x10000200), + new(0x00100200, 0x00300200), + new(0x00001000, 0x00001000), + }; + + InstEncoding[] sizeOpsizeOpsizeQvdQvnQvmConstraints = new InstEncoding[] + { + new(0x00300000, 0x00300000), + new(0x10100000, 0x10300000), + new(0x10200000, 0x10300000), + new(0x00001040, 0x00001040), + new(0x00010040, 0x00010040), + new(0x00000041, 0x00000041), + }; + + InstEncoding[] cmodeQvdConstraints = new InstEncoding[] + { + new(0x00000E00, 0x00000E00), + new(0x00001040, 0x00001040), + }; + + InstEncoding[] qConstraints = new InstEncoding[] + { + new(0x00000040, 0x00000040), + }; + + InstEncoding[] sizeQConstraints = new InstEncoding[] + { + new(0x00300000, 0x00300000), + new(0x00000040, 0x00000040), + }; + + InstEncoding[] sizeConstraints4 = new InstEncoding[] + { + new(0x00300000, 0x00300000), + }; + + InstEncoding[] qvdQvnQvmSizeSizeConstraints = new InstEncoding[] + { + new(0x00001040, 0x00001040), + new(0x00010040, 0x00010040), + new(0x00000041, 0x00000041), + new(0x00000000, 0x00300000), + new(0x00300000, 0x00300000), + }; + + InstEncoding[] sizeSizeQvdQvnConstraints = new InstEncoding[] + { + new(0x00300000, 0x00300000), + new(0x00000000, 0x00300000), + new(0x10001000, 0x10001000), + new(0x10010000, 0x10010000), + }; + + InstEncoding[] opSizeVmConstraints = new InstEncoding[] + { + new(0x00000000, 0x000000C0), + new(0x000C0000, 0x000C0000), + new(0x00000001, 0x00000001), + }; + + InstEncoding[] qvdQvmQvnConstraints = new InstEncoding[] + { + new(0x00001040, 0x00001040), + new(0x00000041, 0x00000041), + new(0x00010040, 0x00010040), + }; + + InstEncoding[] imm6UopVmConstraints = new InstEncoding[] + { + new(0x00000000, 0x00380000), + new(0x00000000, 0x10000100), + new(0x00000001, 0x00000001), + }; + + InstEncoding[] imm6lUopQvdQvmConstraints = new InstEncoding[] + { + new(0x00000000, 0x00380080), + new(0x00000000, 0x10000100), + new(0x00001040, 0x00001040), + new(0x00000041, 0x00000041), + }; + + InstEncoding[] qvdQvmSizeSizeConstraints = new InstEncoding[] + { + new(0x00001040, 0x00001040), + new(0x00000041, 0x00000041), + new(0x00000000, 0x000C0000), + new(0x000C0000, 0x000C0000), + }; + + InstEncoding[] sizeSizeSizeQvdQvmConstraints = new InstEncoding[] + { + new(0x00040000, 0x000C0000), + new(0x00080000, 0x000C0000), + new(0x000C0000, 0x000C0000), + new(0x00001040, 0x00001040), + new(0x00000041, 0x00000041), + }; + + InstEncoding[] sizeSizeQvdQvmConstraints = new InstEncoding[] + { + new(0x00080000, 0x000C0000), + new(0x000C0000, 0x000C0000), + new(0x00001040, 0x00001040), + new(0x00000041, 0x00000041), + }; + + InstEncoding[] imm6lQvdQvmConstraints = new InstEncoding[] + { + new(0x00000000, 0x00380080), + new(0x00001040, 0x00001040), + new(0x00000041, 0x00000041), + }; + + InstEncoding[] imm6VmConstraints = new InstEncoding[] + { + new(0x00000000, 0x00380000), + new(0x00000001, 0x00000001), + }; + + InstEncoding[] imm6VdImm6Imm6Imm6Constraints = new InstEncoding[] + { + new(0x00000000, 0x00380000), + new(0x00001000, 0x00001000), + new(0x00080000, 0x003F0000), + new(0x00100000, 0x003F0000), + new(0x00200000, 0x003F0000), + }; + + InstEncoding[] sizeVdConstraints2 = new InstEncoding[] + { + new(0x000C0000, 0x000C0000), + new(0x00001000, 0x00001000), + }; + + InstEncoding[] sizeQsizeQvdQvmConstraints = new InstEncoding[] + { + new(0x000C0000, 0x000C0000), + new(0x00080000, 0x000C0040), + new(0x00001040, 0x00001040), + new(0x00000041, 0x00000041), + }; + + List insts = new() + { + new(0xF1400000, 0xFBE08000, InstName.AdcI, T.AdcIT1, IsaVersion.v80, InstFlags.Rd), + new(0xEB400000, 0xFFE08000, InstName.AdcR, T.AdcRT2, IsaVersion.v80, InstFlags.Rd), + new(0xF1000000, 0xFBE08000, rnRdsConstraints, InstName.AddI, T.AddIT3, IsaVersion.v80, InstFlags.Rd), + new(0xF2000000, 0xFBF08000, rnRnConstraints, InstName.AddI, T.AddIT4, IsaVersion.v80, InstFlags.Rd), + new(0xEB000000, 0xFFE08000, rnRdsConstraints, InstName.AddR, T.AddRT3, IsaVersion.v80, InstFlags.Rd), + new(0xF10D0000, 0xFBEF8000, rdsConstraints, InstName.AddSpI, T.AddSpIT3, IsaVersion.v80, InstFlags.Rd), + new(0xF20D0000, 0xFBFF8000, InstName.AddSpI, T.AddSpIT4, IsaVersion.v80, InstFlags.Rd), + new(0xEB0D0000, 0xFFEF8000, rdsConstraints, InstName.AddSpR, T.AddSpRT3, IsaVersion.v80, InstFlags.Rd), + new(0xF2AF0000, 0xFBFF8000, InstName.Adr, T.AdrT2, IsaVersion.v80, InstFlags.Rd), + new(0xF20F0000, 0xFBFF8000, InstName.Adr, T.AdrT3, IsaVersion.v80, InstFlags.Rd), + new(0xFFB00340, 0xFFBF0FD0, vdVmConstraints, InstName.Aesd, T.AesdT1, IsaVersion.v80, IsaFeature.FeatAes, InstFlags.None), + new(0xFFB00300, 0xFFBF0FD0, vdVmConstraints, InstName.Aese, T.AeseT1, IsaVersion.v80, IsaFeature.FeatAes, InstFlags.None), + new(0xFFB003C0, 0xFFBF0FD0, vdVmConstraints, InstName.Aesimc, T.AesimcT1, IsaVersion.v80, IsaFeature.FeatAes, InstFlags.None), + new(0xFFB00380, 0xFFBF0FD0, vdVmConstraints, InstName.Aesmc, T.AesmcT1, IsaVersion.v80, IsaFeature.FeatAes, InstFlags.None), + new(0xF0000000, 0xFBE08000, rdsConstraints, InstName.AndI, T.AndIT1, IsaVersion.v80, InstFlags.Rd), + new(0xEA000000, 0xFFE08000, rdsConstraints, InstName.AndR, T.AndRT2, IsaVersion.v80, InstFlags.Rd), + new(0xF0008000, 0xF800D000, condCondCondConstraints, InstName.B, T.BT3, IsaVersion.v80, InstFlags.Cond), + new(0xF0009000, 0xF800D000, InstName.B, T.BT4, IsaVersion.v80, InstFlags.None), + new(0xF36F0000, 0xFFFF8020, InstName.Bfc, T.BfcT1, IsaVersion.v80, InstFlags.Rd), + new(0xF3600000, 0xFFF08020, rnConstraints, InstName.Bfi, T.BfiT1, IsaVersion.v80, InstFlags.Rd), + new(0xF0200000, 0xFBE08000, InstName.BicI, T.BicIT1, IsaVersion.v80, InstFlags.Rd), + new(0xEA200000, 0xFFE08000, InstName.BicR, T.BicRT2, IsaVersion.v80, InstFlags.Rd), + new(0xF000D000, 0xF800D000, InstName.BlI, T.BlIT1, IsaVersion.v80, InstFlags.None), + new(0xF000C000, 0xF800D000, hConstraints, InstName.BlI, T.BlIT2, IsaVersion.v80, InstFlags.None), + new(0xF3C08F00, 0xFFF0FFFF, InstName.Bxj, T.BxjT1, IsaVersion.v80, InstFlags.None), + new(0xF3AF8016, 0xFFFFFFFF, InstName.Clrbhb, T.ClrbhbT1, IsaVersion.v89, IsaFeature.FeatClrbhb, InstFlags.None), + new(0xF3BF8F2F, 0xFFFFFFFF, InstName.Clrex, T.ClrexT1, IsaVersion.v80, InstFlags.None), + new(0xFAB0F080, 0xFFF0F0F0, InstName.Clz, T.ClzT1, IsaVersion.v80, InstFlags.Rd), + new(0xF1100F00, 0xFBF08F00, InstName.CmnI, T.CmnIT1, IsaVersion.v80, InstFlags.None), + new(0xEB100F00, 0xFFF08F00, InstName.CmnR, T.CmnRT2, IsaVersion.v80, InstFlags.None), + new(0xF1B00F00, 0xFBF08F00, InstName.CmpI, T.CmpIT2, IsaVersion.v80, InstFlags.None), + new(0xEBB00F00, 0xFFF08F00, InstName.CmpR, T.CmpRT3, IsaVersion.v80, InstFlags.None), + new(0xF3AF8000, 0xFFFFF800, imodmConstraints, InstName.Cps, T.CpsT2, IsaVersion.v80, InstFlags.None), + new(0xFAC0F080, 0xFFF0F0C0, InstName.Crc32, T.Crc32T1, IsaVersion.v80, IsaFeature.FeatCrc32, InstFlags.Rd), + new(0xFAD0F080, 0xFFF0F0C0, InstName.Crc32c, T.Crc32cT1, IsaVersion.v80, IsaFeature.FeatCrc32, InstFlags.Rd), + new(0xF3AF8014, 0xFFFFFFFF, InstName.Csdb, T.CsdbT1, IsaVersion.v80, InstFlags.None), + new(0xF3AF80F0, 0xFFFFFFF0, InstName.Dbg, T.DbgT1, IsaVersion.v80, InstFlags.None), + new(0xF78F8001, 0xFFFFFFFF, InstName.Dcps1, T.Dcps1T1, IsaVersion.v80, InstFlags.None), + new(0xF78F8002, 0xFFFFFFFF, InstName.Dcps2, T.Dcps2T1, IsaVersion.v80, InstFlags.None), + new(0xF78F8003, 0xFFFFFFFF, InstName.Dcps3, T.Dcps3T1, IsaVersion.v80, InstFlags.None), + new(0xF3BF8F50, 0xFFFFFFF0, InstName.Dmb, T.DmbT1, IsaVersion.v80, InstFlags.None), + new(0xF3BF8F40, 0xFFFFFFF0, optionConstraints, InstName.Dsb, T.DsbT1, IsaVersion.v80, InstFlags.None), + new(0xF0800000, 0xFBE08000, rdsConstraints, InstName.EorI, T.EorIT1, IsaVersion.v80, InstFlags.Rd), + new(0xEA800000, 0xFFE08000, rdsConstraints, InstName.EorR, T.EorRT2, IsaVersion.v80, InstFlags.Rd), + new(0xF3DE8F00, 0xFFFFFFFF, InstName.Eret, T.EretT1, IsaVersion.v80, InstFlags.None), + new(0xF3AF8010, 0xFFFFFFFF, InstName.Esb, T.EsbT1, IsaVersion.v82, IsaFeature.FeatRas, InstFlags.None), + new(0xEC100B01, 0xFE100F01, puwPwPuwPuwConstraints, InstName.Fldmx, T.FldmxT1, IsaVersion.v80, InstFlags.WBack), + new(0xEC000B01, 0xFE100F01, puwPwPuwPuwConstraints, InstName.Fstmx, T.FstmxT1, IsaVersion.v80, InstFlags.WBack), + new(0xF7E08000, 0xFFF0F000, InstName.Hvc, T.HvcT1, IsaVersion.v80, InstFlags.None), + new(0xF3BF8F60, 0xFFFFFFF0, InstName.Isb, T.IsbT1, IsaVersion.v80, InstFlags.None), + new(0xE8D00FAF, 0xFFF00FFF, InstName.Lda, T.LdaT1, IsaVersion.v80, InstFlags.Rt), + new(0xE8D00F8F, 0xFFF00FFF, InstName.Ldab, T.LdabT1, IsaVersion.v80, InstFlags.Rt), + new(0xE8D00FEF, 0xFFF00FFF, InstName.Ldaex, T.LdaexT1, IsaVersion.v80, InstFlags.Rt), + new(0xE8D00FCF, 0xFFF00FFF, InstName.Ldaexb, T.LdaexbT1, IsaVersion.v80, InstFlags.Rt), + new(0xE8D000FF, 0xFFF000FF, InstName.Ldaexd, T.LdaexdT1, IsaVersion.v80, InstFlags.RtRt2), + new(0xE8D00FDF, 0xFFF00FFF, InstName.Ldaexh, T.LdaexhT1, IsaVersion.v80, InstFlags.Rt), + new(0xE8D00F9F, 0xFFF00FFF, InstName.Ldah, T.LdahT1, IsaVersion.v80, InstFlags.Rt), + new(0xEC105E00, 0xFE50FF00, rnPuwConstraints, InstName.LdcI, T.LdcIT1, IsaVersion.v80, InstFlags.WBack), + new(0xEC1F5E00, 0xFE5FFF00, puwConstraints, InstName.LdcL, T.LdcLT1, IsaVersion.v80, InstFlags.WBack), + new(0xE8900000, 0xFFD00000, InstName.Ldm, T.LdmT2, IsaVersion.v80, InstFlags.RlistWBack), + new(0xE9100000, 0xFFD00000, InstName.Ldmdb, T.LdmdbT1, IsaVersion.v80, InstFlags.RlistWBack), + new(0xF8100E00, 0xFFF00F00, rnConstraints, InstName.Ldrbt, T.LdrbtT1, IsaVersion.v80, InstFlags.Rt), + new(0xF8900000, 0xFFF00000, rnRtConstraints, InstName.LdrbI, T.LdrbIT2, IsaVersion.v80, InstFlags.Rt), + new(0xF8100800, 0xFFF00800, rnRtpuwPuwPwConstraints, InstName.LdrbI, T.LdrbIT3, IsaVersion.v80, InstFlags.RtWBack), + new(0xF81F0000, 0xFF7F0000, rtConstraints, InstName.LdrbL, T.LdrbLT1, IsaVersion.v80, InstFlags.Rt), + new(0xF8100000, 0xFFF00FC0, rnRtConstraints, InstName.LdrbR, T.LdrbRT2, IsaVersion.v80, InstFlags.Rt), + new(0xE8500000, 0xFE500000, rnPwConstraints, InstName.LdrdI, T.LdrdIT1, IsaVersion.v80, InstFlags.Rt2WBack), + new(0xE85F0000, 0xFE5F0000, pwConstraints, InstName.LdrdL, T.LdrdLT1, IsaVersion.v80, InstFlags.Rt2WBack), + new(0xE8500F00, 0xFFF00F00, InstName.Ldrex, T.LdrexT1, IsaVersion.v80, InstFlags.Rt), + new(0xE8D00F4F, 0xFFF00FFF, InstName.Ldrexb, T.LdrexbT1, IsaVersion.v80, InstFlags.Rt), + new(0xE8D0007F, 0xFFF000FF, InstName.Ldrexd, T.LdrexdT1, IsaVersion.v80, InstFlags.RtRt2), + new(0xE8D00F5F, 0xFFF00FFF, InstName.Ldrexh, T.LdrexhT1, IsaVersion.v80, InstFlags.Rt), + new(0xF8300E00, 0xFFF00F00, rnConstraints, InstName.Ldrht, T.LdrhtT1, IsaVersion.v80, InstFlags.Rt), + new(0xF8B00000, 0xFFF00000, rnRtConstraints, InstName.LdrhI, T.LdrhIT2, IsaVersion.v80, InstFlags.Rt), + new(0xF8300800, 0xFFF00800, rnRtpuwPuwPwConstraints, InstName.LdrhI, T.LdrhIT3, IsaVersion.v80, InstFlags.RtWBack), + new(0xF83F0000, 0xFF7F0000, rtConstraints, InstName.LdrhL, T.LdrhLT1, IsaVersion.v80, InstFlags.Rt), + new(0xF8300000, 0xFFF00FC0, rnRtConstraints, InstName.LdrhR, T.LdrhRT2, IsaVersion.v80, InstFlags.Rt), + new(0xF9100E00, 0xFFF00F00, rnConstraints, InstName.Ldrsbt, T.LdrsbtT1, IsaVersion.v80, InstFlags.Rt), + new(0xF9900000, 0xFFF00000, rnRtConstraints, InstName.LdrsbI, T.LdrsbIT1, IsaVersion.v80, InstFlags.Rt), + new(0xF9100800, 0xFFF00800, rnRtpuwPuwPwConstraints, InstName.LdrsbI, T.LdrsbIT2, IsaVersion.v80, InstFlags.RtWBack), + new(0xF91F0000, 0xFF7F0000, rtConstraints, InstName.LdrsbL, T.LdrsbLT1, IsaVersion.v80, InstFlags.Rt), + new(0xF9100000, 0xFFF00FC0, rnRtConstraints, InstName.LdrsbR, T.LdrsbRT2, IsaVersion.v80, InstFlags.Rt), + new(0xF9300E00, 0xFFF00F00, rnConstraints, InstName.Ldrsht, T.LdrshtT1, IsaVersion.v80, InstFlags.Rt), + new(0xF9B00000, 0xFFF00000, rnRtConstraints, InstName.LdrshI, T.LdrshIT1, IsaVersion.v80, InstFlags.Rt), + new(0xF9300800, 0xFFF00800, rnRtpuwPuwPwConstraints, InstName.LdrshI, T.LdrshIT2, IsaVersion.v80, InstFlags.RtWBack), + new(0xF93F0000, 0xFF7F0000, rtConstraints, InstName.LdrshL, T.LdrshLT1, IsaVersion.v80, InstFlags.Rt), + new(0xF9300000, 0xFFF00FC0, rnRtConstraints, InstName.LdrshR, T.LdrshRT2, IsaVersion.v80, InstFlags.Rt), + new(0xF8500E00, 0xFFF00F00, rnConstraints, InstName.Ldrt, T.LdrtT1, IsaVersion.v80, InstFlags.Rt), + new(0xF8D00000, 0xFFF00000, rnConstraints, InstName.LdrI, T.LdrIT3, IsaVersion.v80, InstFlags.Rt), + new(0xF8500800, 0xFFF00800, rnPuwPwConstraints, InstName.LdrI, T.LdrIT4, IsaVersion.v80, InstFlags.RtWBack), + new(0xF85F0000, 0xFF7F0000, InstName.LdrL, T.LdrLT2, IsaVersion.v80, InstFlags.Rt), + new(0xF8500000, 0xFFF00FC0, rnConstraints, InstName.LdrR, T.LdrRT2, IsaVersion.v80, InstFlags.Rt), + new(0xEE000E10, 0xFF100E10, InstName.Mcr, T.McrT1, IsaVersion.v80, InstFlags.Rt), + new(0xEC400E00, 0xFFF00E00, InstName.Mcrr, T.McrrT1, IsaVersion.v80, InstFlags.Rt), + new(0xFB000000, 0xFFF000F0, raConstraints, InstName.Mla, T.MlaT1, IsaVersion.v80, InstFlags.Rd), + new(0xFB000010, 0xFFF000F0, InstName.Mls, T.MlsT1, IsaVersion.v80, InstFlags.Rd), + new(0xF2C00000, 0xFBF08000, InstName.Movt, T.MovtT1, IsaVersion.v80, InstFlags.Rd), + new(0xF04F0000, 0xFBEF8000, InstName.MovI, T.MovIT2, IsaVersion.v80, InstFlags.Rd), + new(0xF2400000, 0xFBF08000, InstName.MovI, T.MovIT3, IsaVersion.v80, InstFlags.Rd), + new(0xEA4F0000, 0xFFEF8000, InstName.MovR, T.MovRT3, IsaVersion.v80, InstFlags.Rd), + new(0xFA00F000, 0xFF80F0F0, InstName.MovRr, T.MovRrT2, IsaVersion.v80, InstFlags.Rd), + new(0xEE100E10, 0xFF100E10, InstName.Mrc, T.MrcT1, IsaVersion.v80, InstFlags.Rt), + new(0xEC500E00, 0xFFF00E00, InstName.Mrrc, T.MrrcT1, IsaVersion.v80, InstFlags.Rt), + new(0xF3EF8000, 0xFFEFF0FF, InstName.Mrs, T.MrsT1, IsaVersion.v80, InstFlags.Rd), + new(0xF3E08020, 0xFFE0F0EF, InstName.MrsBr, T.MrsBrT1, IsaVersion.v80, InstFlags.Rd), + new(0xF3808020, 0xFFE0F0EF, InstName.MsrBr, T.MsrBrT1, IsaVersion.v80, InstFlags.None), + new(0xF3808000, 0xFFE0F0FF, InstName.MsrR, T.MsrRT1, IsaVersion.v80, InstFlags.None), + new(0xFB00F000, 0xFFF0F0F0, InstName.Mul, T.MulT2, IsaVersion.v80, InstFlags.Rd), + new(0xF06F0000, 0xFBEF8000, InstName.MvnI, T.MvnIT1, IsaVersion.v80, InstFlags.Rd), + new(0xEA6F0000, 0xFFEF8000, InstName.MvnR, T.MvnRT2, IsaVersion.v80, InstFlags.Rd), + new(0xF3AF8000, 0xFFFFFFFF, InstName.Nop, T.NopT2, IsaVersion.v80, InstFlags.None), + new(0xF0600000, 0xFBE08000, rnConstraints, InstName.OrnI, T.OrnIT1, IsaVersion.v80, InstFlags.Rd), + new(0xEA600000, 0xFFE08000, rnConstraints, InstName.OrnR, T.OrnRT1, IsaVersion.v80, InstFlags.Rd), + new(0xF0400000, 0xFBE08000, rnConstraints, InstName.OrrI, T.OrrIT1, IsaVersion.v80, InstFlags.Rd), + new(0xEA400000, 0xFFE08000, rnConstraints, InstName.OrrR, T.OrrRT2, IsaVersion.v80, InstFlags.Rd), + new(0xEAC00000, 0xFFF08010, sTConstraints, InstName.Pkh, T.PkhT1, IsaVersion.v80, InstFlags.Rd), + new(0xF890F000, 0xFFD0F000, rnConstraints, InstName.PldI, T.PldIT1, IsaVersion.v80, InstFlags.WBack), + new(0xF810FC00, 0xFFD0FF00, rnConstraints, InstName.PldI, T.PldIT2, IsaVersion.v80, InstFlags.WBack), + new(0xF81FF000, 0xFF7FF000, InstName.PldL, T.PldLT1, IsaVersion.v80, InstFlags.None), + new(0xF810F000, 0xFFD0FFC0, rnConstraints, InstName.PldR, T.PldRT1, IsaVersion.v80, InstFlags.WBack), + new(0xF990F000, 0xFFF0F000, rnConstraints, InstName.PliI, T.PliIT1, IsaVersion.v80, InstFlags.None), + new(0xF910FC00, 0xFFF0FF00, rnConstraints, InstName.PliI, T.PliIT2, IsaVersion.v80, InstFlags.None), + new(0xF91FF000, 0xFF7FF000, InstName.PliI, T.PliIT3, IsaVersion.v80, InstFlags.None), + new(0xF910F000, 0xFFF0FFC0, rnConstraints, InstName.PliR, T.PliRT1, IsaVersion.v80, InstFlags.None), + new(0xF3BF8F44, 0xFFFFFFFF, InstName.Pssbb, T.PssbbT1, IsaVersion.v80, InstFlags.None), + new(0xFA80F080, 0xFFF0F0F0, InstName.Qadd, T.QaddT1, IsaVersion.v80, InstFlags.Rd), + new(0xFA90F010, 0xFFF0F0F0, InstName.Qadd16, T.Qadd16T1, IsaVersion.v80, InstFlags.Rd), + new(0xFA80F010, 0xFFF0F0F0, InstName.Qadd8, T.Qadd8T1, IsaVersion.v80, InstFlags.Rd), + new(0xFAA0F010, 0xFFF0F0F0, InstName.Qasx, T.QasxT1, IsaVersion.v80, InstFlags.Rd), + new(0xFA80F090, 0xFFF0F0F0, InstName.Qdadd, T.QdaddT1, IsaVersion.v80, InstFlags.Rd), + new(0xFA80F0B0, 0xFFF0F0F0, InstName.Qdsub, T.QdsubT1, IsaVersion.v80, InstFlags.Rd), + new(0xFAE0F010, 0xFFF0F0F0, InstName.Qsax, T.QsaxT1, IsaVersion.v80, InstFlags.Rd), + new(0xFA80F0A0, 0xFFF0F0F0, InstName.Qsub, T.QsubT1, IsaVersion.v80, InstFlags.Rd), + new(0xFAD0F010, 0xFFF0F0F0, InstName.Qsub16, T.Qsub16T1, IsaVersion.v80, InstFlags.Rd), + new(0xFAC0F010, 0xFFF0F0F0, InstName.Qsub8, T.Qsub8T1, IsaVersion.v80, InstFlags.Rd), + new(0xFA90F0A0, 0xFFF0F0F0, InstName.Rbit, T.RbitT1, IsaVersion.v80, InstFlags.Rd), + new(0xFA90F080, 0xFFF0F0F0, InstName.Rev, T.RevT2, IsaVersion.v80, InstFlags.Rd), + new(0xFA90F090, 0xFFF0F0F0, InstName.Rev16, T.Rev16T2, IsaVersion.v80, InstFlags.Rd), + new(0xFA90F0B0, 0xFFF0F0F0, InstName.Revsh, T.RevshT2, IsaVersion.v80, InstFlags.Rd), + new(0xE810C000, 0xFFD0FFFF, InstName.Rfe, T.RfeT1, IsaVersion.v80, InstFlags.WBack), + new(0xE990C000, 0xFFD0FFFF, InstName.Rfe, T.RfeT2, IsaVersion.v80, InstFlags.WBack), + new(0xF1C00000, 0xFBE08000, InstName.RsbI, T.RsbIT2, IsaVersion.v80, InstFlags.Rd), + new(0xEBC00000, 0xFFE08000, InstName.RsbR, T.RsbRT1, IsaVersion.v80, InstFlags.Rd), + new(0xFA90F000, 0xFFF0F0F0, InstName.Sadd16, T.Sadd16T1, IsaVersion.v80, InstFlags.Rd), + new(0xFA80F000, 0xFFF0F0F0, InstName.Sadd8, T.Sadd8T1, IsaVersion.v80, InstFlags.Rd), + new(0xFAA0F000, 0xFFF0F0F0, InstName.Sasx, T.SasxT1, IsaVersion.v80, InstFlags.Rd), + new(0xF3BF8F70, 0xFFFFFFFF, InstName.Sb, T.SbT1, IsaVersion.v85, IsaFeature.FeatSb, InstFlags.None), + new(0xF1600000, 0xFBE08000, InstName.SbcI, T.SbcIT1, IsaVersion.v80, InstFlags.Rd), + new(0xEB600000, 0xFFE08000, InstName.SbcR, T.SbcRT2, IsaVersion.v80, InstFlags.Rd), + new(0xF3400000, 0xFFF08020, InstName.Sbfx, T.SbfxT1, IsaVersion.v80, InstFlags.Rd), + new(0xFB90F0F0, 0xFFF0F0F0, InstName.Sdiv, T.SdivT1, IsaVersion.v80, InstFlags.Rd), + new(0xFAA0F080, 0xFFF0F0F0, InstName.Sel, T.SelT1, IsaVersion.v80, InstFlags.Rd), + new(0xF3AF8004, 0xFFFFFFFF, InstName.Sev, T.SevT2, IsaVersion.v80, InstFlags.None), + new(0xF3AF8005, 0xFFFFFFFF, InstName.Sevl, T.SevlT2, IsaVersion.v80, InstFlags.None), + new(0xEF000C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha1c, T.Sha1cT1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None), + new(0xFFB902C0, 0xFFBF0FD0, vdVmConstraints, InstName.Sha1h, T.Sha1hT1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None), + new(0xEF200C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha1m, T.Sha1mT1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None), + new(0xEF100C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha1p, T.Sha1pT1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None), + new(0xEF300C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha1su0, T.Sha1su0T1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None), + new(0xFFBA0380, 0xFFBF0FD0, vdVmConstraints, InstName.Sha1su1, T.Sha1su1T1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None), + new(0xFF000C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha256h, T.Sha256hT1, IsaVersion.v80, IsaFeature.FeatSha256, InstFlags.None), + new(0xFF100C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha256h2, T.Sha256h2T1, IsaVersion.v80, IsaFeature.FeatSha256, InstFlags.None), + new(0xFFBA03C0, 0xFFBF0FD0, vdVmConstraints, InstName.Sha256su0, T.Sha256su0T1, IsaVersion.v80, IsaFeature.FeatSha256, InstFlags.None), + new(0xFF200C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha256su1, T.Sha256su1T1, IsaVersion.v80, IsaFeature.FeatSha256, InstFlags.None), + new(0xFA90F020, 0xFFF0F0F0, InstName.Shadd16, T.Shadd16T1, IsaVersion.v80, InstFlags.Rd), + new(0xFA80F020, 0xFFF0F0F0, InstName.Shadd8, T.Shadd8T1, IsaVersion.v80, InstFlags.Rd), + new(0xFAA0F020, 0xFFF0F0F0, InstName.Shasx, T.ShasxT1, IsaVersion.v80, InstFlags.Rd), + new(0xFAE0F020, 0xFFF0F0F0, InstName.Shsax, T.ShsaxT1, IsaVersion.v80, InstFlags.Rd), + new(0xFAD0F020, 0xFFF0F0F0, InstName.Shsub16, T.Shsub16T1, IsaVersion.v80, InstFlags.Rd), + new(0xFAC0F020, 0xFFF0F0F0, InstName.Shsub8, T.Shsub8T1, IsaVersion.v80, InstFlags.Rd), + new(0xF7F08000, 0xFFF0FFFF, InstName.Smc, T.SmcT1, IsaVersion.v80, InstFlags.None), + new(0xFB100000, 0xFFF000C0, raConstraints, InstName.Smlabb, T.SmlabbT1, IsaVersion.v80, InstFlags.Rd), + new(0xFB200000, 0xFFF000E0, raConstraints, InstName.Smlad, T.SmladT1, IsaVersion.v80, InstFlags.Rd), + new(0xFBC00000, 0xFFF000F0, InstName.Smlal, T.SmlalT1, IsaVersion.v80, InstFlags.RdLoRdHi), + new(0xFBC00080, 0xFFF000C0, InstName.Smlalbb, T.SmlalbbT1, IsaVersion.v80, InstFlags.RdLoRdHi), + new(0xFBC000C0, 0xFFF000E0, InstName.Smlald, T.SmlaldT1, IsaVersion.v80, InstFlags.RdLoRdHi), + new(0xFB300000, 0xFFF000E0, raConstraints, InstName.Smlawb, T.SmlawbT1, IsaVersion.v80, InstFlags.Rd), + new(0xFB400000, 0xFFF000E0, raConstraints, InstName.Smlsd, T.SmlsdT1, IsaVersion.v80, InstFlags.Rd), + new(0xFBD000C0, 0xFFF000E0, InstName.Smlsld, T.SmlsldT1, IsaVersion.v80, InstFlags.RdLoRdHi), + new(0xFB500000, 0xFFF000E0, raConstraints, InstName.Smmla, T.SmmlaT1, IsaVersion.v80, InstFlags.Rd), + new(0xFB600000, 0xFFF000E0, InstName.Smmls, T.SmmlsT1, IsaVersion.v80, InstFlags.Rd), + new(0xFB50F000, 0xFFF0F0E0, InstName.Smmul, T.SmmulT1, IsaVersion.v80, InstFlags.Rd), + new(0xFB20F000, 0xFFF0F0E0, InstName.Smuad, T.SmuadT1, IsaVersion.v80, InstFlags.Rd), + new(0xFB10F000, 0xFFF0F0C0, InstName.Smulbb, T.SmulbbT1, IsaVersion.v80, InstFlags.Rd), + new(0xFB800000, 0xFFF000F0, InstName.Smull, T.SmullT1, IsaVersion.v80, InstFlags.RdLoRdHi), + new(0xFB30F000, 0xFFF0F0E0, InstName.Smulwb, T.SmulwbT1, IsaVersion.v80, InstFlags.Rd), + new(0xFB40F000, 0xFFF0F0E0, InstName.Smusd, T.SmusdT1, IsaVersion.v80, InstFlags.Rd), + new(0xE80DC000, 0xFFDFFFE0, InstName.Srs, T.SrsT1, IsaVersion.v80, InstFlags.WBack), + new(0xE98DC000, 0xFFDFFFE0, InstName.Srs, T.SrsT2, IsaVersion.v80, InstFlags.WBack), + new(0xF3000000, 0xFFD08020, shimm2imm3Constraints, InstName.Ssat, T.SsatT1, IsaVersion.v80, InstFlags.Rd), + new(0xF3200000, 0xFFF0F0F0, InstName.Ssat16, T.Ssat16T1, IsaVersion.v80, InstFlags.Rd), + new(0xFAE0F000, 0xFFF0F0F0, InstName.Ssax, T.SsaxT1, IsaVersion.v80, InstFlags.Rd), + new(0xF3BF8F40, 0xFFFFFFFF, InstName.Ssbb, T.SsbbT1, IsaVersion.v80, InstFlags.None), + new(0xFAD0F000, 0xFFF0F0F0, InstName.Ssub16, T.Ssub16T1, IsaVersion.v80, InstFlags.Rd), + new(0xFAC0F000, 0xFFF0F0F0, InstName.Ssub8, T.Ssub8T1, IsaVersion.v80, InstFlags.Rd), + new(0xEC005E00, 0xFE50FF00, puwConstraints, InstName.Stc, T.StcT1, IsaVersion.v80, InstFlags.WBack), + new(0xE8C00FAF, 0xFFF00FFF, InstName.Stl, T.StlT1, IsaVersion.v80, InstFlags.RtRead), + new(0xE8C00F8F, 0xFFF00FFF, InstName.Stlb, T.StlbT1, IsaVersion.v80, InstFlags.RtRead), + new(0xE8C00FE0, 0xFFF00FF0, InstName.Stlex, T.StlexT1, IsaVersion.v80, InstFlags.RdRtReadRd16), + new(0xE8C00FC0, 0xFFF00FF0, InstName.Stlexb, T.StlexbT1, IsaVersion.v80, InstFlags.RdRtReadRd16), + new(0xE8C000F0, 0xFFF000F0, InstName.Stlexd, T.StlexdT1, IsaVersion.v80, InstFlags.RdRt2ReadRd16), + new(0xE8C00FD0, 0xFFF00FF0, InstName.Stlexh, T.StlexhT1, IsaVersion.v80, InstFlags.RdRtReadRd16), + new(0xE8C00F9F, 0xFFF00FFF, InstName.Stlh, T.StlhT1, IsaVersion.v80, InstFlags.RtRead), + new(0xE8800000, 0xFFD08000, InstName.Stm, T.StmT2, IsaVersion.v80, InstFlags.RlistReadWBack), + new(0xE9000000, 0xFFD08000, InstName.Stmdb, T.StmdbT1, IsaVersion.v80, InstFlags.RlistReadWBack), + new(0xF8000E00, 0xFFF00F00, rnConstraints, InstName.Strbt, T.StrbtT1, IsaVersion.v80, InstFlags.RtRead), + new(0xF8800000, 0xFFF00000, rnConstraints, InstName.StrbI, T.StrbIT2, IsaVersion.v80, InstFlags.RtRead), + new(0xF8000800, 0xFFF00800, rnPuwPwConstraints, InstName.StrbI, T.StrbIT3, IsaVersion.v80, InstFlags.RtReadWBack), + new(0xF8000000, 0xFFF00FC0, rnConstraints, InstName.StrbR, T.StrbRT2, IsaVersion.v80, InstFlags.RtRead), + new(0xE8400000, 0xFE500000, rnPwConstraints, InstName.StrdI, T.StrdIT1, IsaVersion.v80, InstFlags.Rt2ReadWBack), + new(0xE8400000, 0xFFF00000, InstName.Strex, T.StrexT1, IsaVersion.v80, InstFlags.RdRtRead), + new(0xE8C00F40, 0xFFF00FF0, InstName.Strexb, T.StrexbT1, IsaVersion.v80, InstFlags.RdRtReadRd16), + new(0xE8C00070, 0xFFF000F0, InstName.Strexd, T.StrexdT1, IsaVersion.v80, InstFlags.RdRt2ReadRd16), + new(0xE8C00F50, 0xFFF00FF0, InstName.Strexh, T.StrexhT1, IsaVersion.v80, InstFlags.RdRtReadRd16), + new(0xF8200E00, 0xFFF00F00, rnConstraints, InstName.Strht, T.StrhtT1, IsaVersion.v80, InstFlags.RtRead), + new(0xF8A00000, 0xFFF00000, rnConstraints, InstName.StrhI, T.StrhIT2, IsaVersion.v80, InstFlags.RtRead), + new(0xF8200800, 0xFFF00800, rnPuwPwConstraints, InstName.StrhI, T.StrhIT3, IsaVersion.v80, InstFlags.RtReadWBack), + new(0xF8200000, 0xFFF00FC0, rnConstraints, InstName.StrhR, T.StrhRT2, IsaVersion.v80, InstFlags.RtRead), + new(0xF8400E00, 0xFFF00F00, rnConstraints, InstName.Strt, T.StrtT1, IsaVersion.v80, InstFlags.RtRead), + new(0xF8C00000, 0xFFF00000, rnConstraints, InstName.StrI, T.StrIT3, IsaVersion.v80, InstFlags.RtRead), + new(0xF8400800, 0xFFF00800, rnPuwPwConstraints, InstName.StrI, T.StrIT4, IsaVersion.v80, InstFlags.RtReadWBack), + new(0xF8400000, 0xFFF00FC0, rnConstraints, InstName.StrR, T.StrRT2, IsaVersion.v80, InstFlags.RtRead), + new(0xF1A00000, 0xFBE08000, rnRdsConstraints, InstName.SubI, T.SubIT3, IsaVersion.v80, InstFlags.Rd), + new(0xF2A00000, 0xFBF08000, rnRnConstraints, InstName.SubI, T.SubIT4, IsaVersion.v80, InstFlags.Rd), + new(0xF3D08F00, 0xFFF0FF00, rnimm8Constraints, InstName.SubI, T.SubIT5, IsaVersion.v80, InstFlags.None), + new(0xEBA00000, 0xFFE08000, rnRdsConstraints, InstName.SubR, T.SubRT2, IsaVersion.v80, InstFlags.Rd), + new(0xF1AD0000, 0xFBEF8000, rdsConstraints, InstName.SubSpI, T.SubSpIT2, IsaVersion.v80, InstFlags.Rd), + new(0xF2AD0000, 0xFBFF8000, InstName.SubSpI, T.SubSpIT3, IsaVersion.v80, InstFlags.Rd), + new(0xEBAD0000, 0xFFEF8000, rdsConstraints, InstName.SubSpR, T.SubSpRT1, IsaVersion.v80, InstFlags.Rd), + new(0xFA40F080, 0xFFF0F0C0, rnConstraints, InstName.Sxtab, T.SxtabT1, IsaVersion.v80, InstFlags.Rd), + new(0xFA20F080, 0xFFF0F0C0, rnConstraints, InstName.Sxtab16, T.Sxtab16T1, IsaVersion.v80, InstFlags.Rd), + new(0xFA00F080, 0xFFF0F0C0, rnConstraints, InstName.Sxtah, T.SxtahT1, IsaVersion.v80, InstFlags.Rd), + new(0xFA4FF080, 0xFFFFF0C0, InstName.Sxtb, T.SxtbT2, IsaVersion.v80, InstFlags.Rd), + new(0xFA2FF080, 0xFFFFF0C0, InstName.Sxtb16, T.Sxtb16T1, IsaVersion.v80, InstFlags.Rd), + new(0xFA0FF080, 0xFFFFF0C0, InstName.Sxth, T.SxthT2, IsaVersion.v80, InstFlags.Rd), + new(0xE8D0F000, 0xFFF0FFE0, InstName.Tbb, T.TbbT1, IsaVersion.v80, InstFlags.None), + new(0xF0900F00, 0xFBF08F00, InstName.TeqI, T.TeqIT1, IsaVersion.v80, InstFlags.None), + new(0xEA900F00, 0xFFF08F00, InstName.TeqR, T.TeqRT1, IsaVersion.v80, InstFlags.None), + new(0xF3AF8012, 0xFFFFFFFF, InstName.Tsb, T.TsbT1, IsaVersion.v84, IsaFeature.FeatTrf, InstFlags.None), + new(0xF0100F00, 0xFBF08F00, InstName.TstI, T.TstIT1, IsaVersion.v80, InstFlags.None), + new(0xEA100F00, 0xFFF08F00, InstName.TstR, T.TstRT2, IsaVersion.v80, InstFlags.None), + new(0xFA90F040, 0xFFF0F0F0, InstName.Uadd16, T.Uadd16T1, IsaVersion.v80, InstFlags.Rd), + new(0xFA80F040, 0xFFF0F0F0, InstName.Uadd8, T.Uadd8T1, IsaVersion.v80, InstFlags.Rd), + new(0xFAA0F040, 0xFFF0F0F0, InstName.Uasx, T.UasxT1, IsaVersion.v80, InstFlags.Rd), + new(0xF3C00000, 0xFFF08020, InstName.Ubfx, T.UbfxT1, IsaVersion.v80, InstFlags.Rd), + new(0xF7F0A000, 0xFFF0F000, InstName.Udf, T.UdfT2, IsaVersion.v80, InstFlags.None), + new(0xFBB0F0F0, 0xFFF0F0F0, InstName.Udiv, T.UdivT1, IsaVersion.v80, InstFlags.Rd), + new(0xFA90F060, 0xFFF0F0F0, InstName.Uhadd16, T.Uhadd16T1, IsaVersion.v80, InstFlags.Rd), + new(0xFA80F060, 0xFFF0F0F0, InstName.Uhadd8, T.Uhadd8T1, IsaVersion.v80, InstFlags.Rd), + new(0xFAA0F060, 0xFFF0F0F0, InstName.Uhasx, T.UhasxT1, IsaVersion.v80, InstFlags.Rd), + new(0xFAE0F060, 0xFFF0F0F0, InstName.Uhsax, T.UhsaxT1, IsaVersion.v80, InstFlags.Rd), + new(0xFAD0F060, 0xFFF0F0F0, InstName.Uhsub16, T.Uhsub16T1, IsaVersion.v80, InstFlags.Rd), + new(0xFAC0F060, 0xFFF0F0F0, InstName.Uhsub8, T.Uhsub8T1, IsaVersion.v80, InstFlags.Rd), + new(0xFBE00060, 0xFFF000F0, InstName.Umaal, T.UmaalT1, IsaVersion.v80, InstFlags.RdLoRdHi), + new(0xFBE00000, 0xFFF000F0, InstName.Umlal, T.UmlalT1, IsaVersion.v80, InstFlags.RdLoRdHi), + new(0xFBA00000, 0xFFF000F0, InstName.Umull, T.UmullT1, IsaVersion.v80, InstFlags.RdLoRdHi), + new(0xFA90F050, 0xFFF0F0F0, InstName.Uqadd16, T.Uqadd16T1, IsaVersion.v80, InstFlags.Rd), + new(0xFA80F050, 0xFFF0F0F0, InstName.Uqadd8, T.Uqadd8T1, IsaVersion.v80, InstFlags.Rd), + new(0xFAA0F050, 0xFFF0F0F0, InstName.Uqasx, T.UqasxT1, IsaVersion.v80, InstFlags.Rd), + new(0xFAE0F050, 0xFFF0F0F0, InstName.Uqsax, T.UqsaxT1, IsaVersion.v80, InstFlags.Rd), + new(0xFAD0F050, 0xFFF0F0F0, InstName.Uqsub16, T.Uqsub16T1, IsaVersion.v80, InstFlags.Rd), + new(0xFAC0F050, 0xFFF0F0F0, InstName.Uqsub8, T.Uqsub8T1, IsaVersion.v80, InstFlags.Rd), + new(0xFB70F000, 0xFFF0F0F0, InstName.Usad8, T.Usad8T1, IsaVersion.v80, InstFlags.Rd), + new(0xFB700000, 0xFFF000F0, raConstraints, InstName.Usada8, T.Usada8T1, IsaVersion.v80, InstFlags.Rd), + new(0xF3800000, 0xFFD08020, shimm2imm3Constraints, InstName.Usat, T.UsatT1, IsaVersion.v80, InstFlags.Rd), + new(0xF3A00000, 0xFFF0F0F0, InstName.Usat16, T.Usat16T1, IsaVersion.v80, InstFlags.Rd), + new(0xFAE0F040, 0xFFF0F0F0, InstName.Usax, T.UsaxT1, IsaVersion.v80, InstFlags.Rd), + new(0xFAD0F040, 0xFFF0F0F0, InstName.Usub16, T.Usub16T1, IsaVersion.v80, InstFlags.Rd), + new(0xFAC0F040, 0xFFF0F0F0, InstName.Usub8, T.Usub8T1, IsaVersion.v80, InstFlags.Rd), + new(0xFA50F080, 0xFFF0F0C0, rnConstraints, InstName.Uxtab, T.UxtabT1, IsaVersion.v80, InstFlags.Rd), + new(0xFA30F080, 0xFFF0F0C0, rnConstraints, InstName.Uxtab16, T.Uxtab16T1, IsaVersion.v80, InstFlags.Rd), + new(0xFA10F080, 0xFFF0F0C0, rnConstraints, InstName.Uxtah, T.UxtahT1, IsaVersion.v80, InstFlags.Rd), + new(0xFA5FF080, 0xFFFFF0C0, InstName.Uxtb, T.UxtbT2, IsaVersion.v80, InstFlags.Rd), + new(0xFA3FF080, 0xFFFFF0C0, InstName.Uxtb16, T.Uxtb16T1, IsaVersion.v80, InstFlags.Rd), + new(0xFA1FF080, 0xFFFFF0C0, InstName.Uxth, T.UxthT2, IsaVersion.v80, InstFlags.Rd), + new(0xEF000710, 0xEF800F10, sizeQvdQvnQvmConstraints, InstName.Vaba, T.VabaT1, IsaVersion.v80, InstFlags.None), + new(0xEF800500, 0xEF800F50, sizeVdConstraints, InstName.Vabal, T.VabalT1, IsaVersion.v80, InstFlags.None), + new(0xEF800700, 0xEF800F50, sizeVdConstraints, InstName.VabdlI, T.VabdlIT1, IsaVersion.v80, InstFlags.None), + new(0xFF200D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VabdF, T.VabdFT1, IsaVersion.v80, InstFlags.None), + new(0xFF300D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VabdF, T.VabdFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF000700, 0xEF800F10, sizeQvdQvnQvmConstraints, InstName.VabdI, T.VabdIT1, IsaVersion.v80, InstFlags.None), + new(0xFFB10300, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vabs, T.VabsT1, IsaVersion.v80, InstFlags.None), + new(0xFFB90700, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.Vabs, T.VabsT1, IsaVersion.v80, InstFlags.None), + new(0xFFB50700, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.Vabs, T.VabsT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEEB00AC0, 0xFFBF0ED0, InstName.Vabs, T.VabsT2, IsaVersion.v80, InstFlags.None), + new(0xEEB009C0, 0xFFBF0FD0, InstName.Vabs, T.VabsT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFF000E10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vacge, T.VacgeT1, IsaVersion.v80, InstFlags.None), + new(0xFF100E10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vacge, T.VacgeT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFF200E10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vacgt, T.VacgtT1, IsaVersion.v80, InstFlags.None), + new(0xFF300E10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vacgt, T.VacgtT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF800400, 0xFF800F50, sizeVnVmConstraints, InstName.Vaddhn, T.VaddhnT1, IsaVersion.v80, InstFlags.None), + new(0xEF800000, 0xEF800F50, sizeVdOpvnConstraints, InstName.Vaddl, T.VaddlT1, IsaVersion.v80, InstFlags.None), + new(0xEF800100, 0xEF800F50, sizeVdOpvnConstraints, InstName.Vaddw, T.VaddwT1, IsaVersion.v80, InstFlags.None), + new(0xEF000D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VaddF, T.VaddFT1, IsaVersion.v80, InstFlags.None), + new(0xEF100D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VaddF, T.VaddFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEE300A00, 0xFFB00E50, InstName.VaddF, T.VaddFT2, IsaVersion.v80, InstFlags.None), + new(0xEE300900, 0xFFB00F50, InstName.VaddF, T.VaddFT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF000800, 0xFF800F10, qvdQvnQvmConstraints, InstName.VaddI, T.VaddIT1, IsaVersion.v80, InstFlags.None), + new(0xEF000110, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VandR, T.VandRT1, IsaVersion.v80, InstFlags.None), + new(0xEF800130, 0xEFB809B0, cmodeCmodeQvdConstraints, InstName.VbicI, T.VbicIT1, IsaVersion.v80, InstFlags.None), + new(0xEF800930, 0xEFB80DB0, cmodeCmodeQvdConstraints, InstName.VbicI, T.VbicIT2, IsaVersion.v80, InstFlags.None), + new(0xEF100110, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VbicR, T.VbicRT1, IsaVersion.v80, InstFlags.None), + new(0xFF300110, 0xFFB00F10, qvdQvnQvmOpConstraints, InstName.Vbif, T.VbifT1, IsaVersion.v80, InstFlags.None), + new(0xFF200110, 0xFFB00F10, qvdQvnQvmOpConstraints, InstName.Vbit, T.VbitT1, IsaVersion.v80, InstFlags.None), + new(0xFF100110, 0xFFB00F10, qvdQvnQvmOpConstraints, InstName.Vbsl, T.VbslT1, IsaVersion.v80, InstFlags.None), + new(0xFC900800, 0xFEB00F10, qvdQvnQvmConstraints, InstName.Vcadd, T.VcaddT1, IsaVersion.v83, IsaFeature.FeatFcma, InstFlags.None), + new(0xFC800800, 0xFEB00F10, qvdQvnQvmConstraints, InstName.Vcadd, T.VcaddT1, IsaVersion.v83, IsaFeature.FeatFcma | IsaFeature.FeatFp16, InstFlags.None), + new(0xFFB10100, 0xFFB30F90, sizeQvdQvmConstraints, InstName.VceqI, T.VceqIT1, IsaVersion.v80, InstFlags.None), + new(0xFFB90500, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.VceqI, T.VceqIT1, IsaVersion.v80, InstFlags.None), + new(0xFFB50500, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.VceqI, T.VceqIT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFF000810, 0xFF800F10, qvdQvnQvmSizeConstraints, InstName.VceqR, T.VceqRT1, IsaVersion.v80, InstFlags.None), + new(0xEF000E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VceqR, T.VceqRT2, IsaVersion.v80, InstFlags.None), + new(0xEF100E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VceqR, T.VceqRT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFFB10080, 0xFFB30F90, sizeQvdQvmConstraints, InstName.VcgeI, T.VcgeIT1, IsaVersion.v80, InstFlags.None), + new(0xFFB90480, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.VcgeI, T.VcgeIT1, IsaVersion.v80, InstFlags.None), + new(0xFFB50480, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.VcgeI, T.VcgeIT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF000310, 0xEF800F10, qvdQvnQvmSizeConstraints, InstName.VcgeR, T.VcgeRT1, IsaVersion.v80, InstFlags.None), + new(0xFF000E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VcgeR, T.VcgeRT2, IsaVersion.v80, InstFlags.None), + new(0xFF100E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VcgeR, T.VcgeRT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFFB10000, 0xFFB30F90, sizeQvdQvmConstraints, InstName.VcgtI, T.VcgtIT1, IsaVersion.v80, InstFlags.None), + new(0xFFB90400, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.VcgtI, T.VcgtIT1, IsaVersion.v80, InstFlags.None), + new(0xFFB50400, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.VcgtI, T.VcgtIT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF000300, 0xEF800F10, qvdQvnQvmSizeConstraints, InstName.VcgtR, T.VcgtRT1, IsaVersion.v80, InstFlags.None), + new(0xFF200E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VcgtR, T.VcgtRT2, IsaVersion.v80, InstFlags.None), + new(0xFF300E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VcgtR, T.VcgtRT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFFB10180, 0xFFB30F90, sizeQvdQvmConstraints, InstName.VcleI, T.VcleIT1, IsaVersion.v80, InstFlags.None), + new(0xFFB90580, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.VcleI, T.VcleIT1, IsaVersion.v80, InstFlags.None), + new(0xFFB50580, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.VcleI, T.VcleIT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFFB00400, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vcls, T.VclsT1, IsaVersion.v80, InstFlags.None), + new(0xFFB10200, 0xFFB30F90, sizeQvdQvmConstraints, InstName.VcltI, T.VcltIT1, IsaVersion.v80, InstFlags.None), + new(0xFFB90600, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.VcltI, T.VcltIT1, IsaVersion.v80, InstFlags.None), + new(0xFFB50600, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.VcltI, T.VcltIT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFFB00480, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vclz, T.VclzT1, IsaVersion.v80, InstFlags.None), + new(0xFC200800, 0xFE200F10, qvdQvnQvmConstraints, InstName.Vcmla, T.VcmlaT1, IsaVersion.v83, IsaFeature.FeatFcma, InstFlags.None), + new(0xFE000800, 0xFF000F10, qvdQvnConstraints, InstName.VcmlaS, T.VcmlaST1, IsaVersion.v83, IsaFeature.FeatFcma, InstFlags.None), + new(0xEEB40A40, 0xFFBF0ED0, InstName.Vcmp, T.VcmpT1, IsaVersion.v80, InstFlags.None), + new(0xEEB40940, 0xFFBF0FD0, InstName.Vcmp, T.VcmpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEEB50A40, 0xFFBF0EFF, InstName.Vcmp, T.VcmpT2, IsaVersion.v80, InstFlags.None), + new(0xEEB50940, 0xFFBF0FFF, InstName.Vcmp, T.VcmpT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEEB40AC0, 0xFFBF0ED0, InstName.Vcmpe, T.VcmpeT1, IsaVersion.v80, InstFlags.None), + new(0xEEB409C0, 0xFFBF0FD0, InstName.Vcmpe, T.VcmpeT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEEB50AC0, 0xFFBF0EFF, InstName.Vcmpe, T.VcmpeT2, IsaVersion.v80, InstFlags.None), + new(0xEEB509C0, 0xFFBF0FFF, InstName.Vcmpe, T.VcmpeT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFFB00500, 0xFFBF0F90, qvdQvmConstraints, InstName.Vcnt, T.VcntT1, IsaVersion.v80, InstFlags.None), + new(0xFFBB0000, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtaAsimd, T.VcvtaAsimdT1, IsaVersion.v80, InstFlags.None), + new(0xFFB70000, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtaAsimd, T.VcvtaAsimdT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFEBC0A40, 0xFFBF0E50, sizeConstraints, InstName.VcvtaVfp, T.VcvtaVfpT1, IsaVersion.v80, InstFlags.None), + new(0xFEBC0940, 0xFFBF0F50, sizeConstraints, InstName.VcvtaVfp, T.VcvtaVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEEB20A40, 0xFFBE0ED0, InstName.Vcvtb, T.VcvtbT1, IsaVersion.v80, InstFlags.None), + new(0xEEB30940, 0xFFBF0FD0, InstName.VcvtbBfs, T.VcvtbBfsT1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None), + new(0xFFBB0300, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtmAsimd, T.VcvtmAsimdT1, IsaVersion.v80, InstFlags.None), + new(0xFFB70300, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtmAsimd, T.VcvtmAsimdT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFEBF0A40, 0xFFBF0E50, sizeConstraints, InstName.VcvtmVfp, T.VcvtmVfpT1, IsaVersion.v80, InstFlags.None), + new(0xFEBF0940, 0xFFBF0F50, sizeConstraints, InstName.VcvtmVfp, T.VcvtmVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFFBB0100, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtnAsimd, T.VcvtnAsimdT1, IsaVersion.v80, InstFlags.None), + new(0xFFB70100, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtnAsimd, T.VcvtnAsimdT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFEBD0A40, 0xFFBF0E50, sizeConstraints, InstName.VcvtnVfp, T.VcvtnVfpT1, IsaVersion.v80, InstFlags.None), + new(0xFEBD0940, 0xFFBF0F50, sizeConstraints, InstName.VcvtnVfp, T.VcvtnVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFFBB0200, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtpAsimd, T.VcvtpAsimdT1, IsaVersion.v80, InstFlags.None), + new(0xFFB70200, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtpAsimd, T.VcvtpAsimdT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFEBE0A40, 0xFFBF0E50, sizeConstraints, InstName.VcvtpVfp, T.VcvtpVfpT1, IsaVersion.v80, InstFlags.None), + new(0xFEBE0940, 0xFFBF0F50, sizeConstraints, InstName.VcvtpVfp, T.VcvtpVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEEBC0A40, 0xFFBE0ED0, InstName.VcvtrIv, T.VcvtrIvT1, IsaVersion.v80, InstFlags.None), + new(0xEEBC0940, 0xFFBE0FD0, InstName.VcvtrIv, T.VcvtrIvT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEEB20AC0, 0xFFBE0ED0, InstName.Vcvtt, T.VcvttT1, IsaVersion.v80, InstFlags.None), + new(0xEEB309C0, 0xFFBF0FD0, InstName.VcvttBfs, T.VcvttBfsT1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None), + new(0xFFB60640, 0xFFBF0FD0, vmConstraints, InstName.VcvtBfs, T.VcvtBfsT1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None), + new(0xEEB70AC0, 0xFFBF0ED0, InstName.VcvtDs, T.VcvtDsT1, IsaVersion.v80, InstFlags.None), + new(0xFFB60600, 0xFFBF0ED0, opvdOpvmConstraints, InstName.VcvtHs, T.VcvtHsT1, IsaVersion.v80, InstFlags.None), + new(0xFFBB0600, 0xFFBF0E10, qvdQvmConstraints, InstName.VcvtIs, T.VcvtIsT1, IsaVersion.v80, InstFlags.None), + new(0xFFB70600, 0xFFBF0E10, qvdQvmConstraints, InstName.VcvtIs, T.VcvtIsT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEEBC0AC0, 0xFFBE0ED0, InstName.VcvtIv, T.VcvtIvT1, IsaVersion.v80, InstFlags.None), + new(0xEEBC09C0, 0xFFBE0FD0, InstName.VcvtIv, T.VcvtIvT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEEB80A40, 0xFFBF0E50, InstName.VcvtVi, T.VcvtViT1, IsaVersion.v80, InstFlags.None), + new(0xEEB80940, 0xFFBF0F50, InstName.VcvtVi, T.VcvtViT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF800E10, 0xEF800E90, imm6Opimm6Imm6QvdQvmConstraints, InstName.VcvtXs, T.VcvtXsT1, IsaVersion.v80, InstFlags.None), + new(0xEF800C10, 0xEF800E90, imm6Opimm6Imm6QvdQvmConstraints, InstName.VcvtXs, T.VcvtXsT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEEBA0A40, 0xFFBA0E50, InstName.VcvtXv, T.VcvtXvT1, IsaVersion.v80, InstFlags.None), + new(0xEEBA0940, 0xFFBA0F50, InstName.VcvtXv, T.VcvtXvT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEE800A00, 0xFFB00E50, InstName.Vdiv, T.VdivT1, IsaVersion.v80, InstFlags.None), + new(0xEE800900, 0xFFB00F50, InstName.Vdiv, T.VdivT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFC000D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vdot, T.VdotT1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None), + new(0xFE000D00, 0xFFB00F10, qvdQvnConstraints, InstName.VdotS, T.VdotST1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None), + new(0xEE800B10, 0xFF900F5F, qvdEbConstraints, InstName.VdupR, T.VdupRT1, IsaVersion.v80, InstFlags.RtRead), + new(0xFFB00C00, 0xFFB00F90, imm4QvdConstraints, InstName.VdupS, T.VdupST1, IsaVersion.v80, InstFlags.None), + new(0xFF000110, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Veor, T.VeorT1, IsaVersion.v80, InstFlags.None), + new(0xEFB00000, 0xFFB00010, qvdQvnQvmQimm4Constraints, InstName.Vext, T.VextT1, IsaVersion.v80, InstFlags.None), + new(0xEF000C10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vfma, T.VfmaT1, IsaVersion.v80, InstFlags.None), + new(0xEF100C10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vfma, T.VfmaT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEEA00A00, 0xFFB00E50, InstName.Vfma, T.VfmaT2, IsaVersion.v80, InstFlags.None), + new(0xEEA00900, 0xFFB00F50, InstName.Vfma, T.VfmaT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFC200810, 0xFFB00F10, qvdConstraints, InstName.Vfmal, T.VfmalT1, IsaVersion.v82, IsaFeature.FeatFhm, InstFlags.None), + new(0xFE000810, 0xFFB00F10, qvdConstraints, InstName.VfmalS, T.VfmalST1, IsaVersion.v82, IsaFeature.FeatFhm, InstFlags.None), + new(0xFC300810, 0xFFB00F10, vdVnVmConstraints, InstName.VfmaBf, T.VfmaBfT1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None), + new(0xFE300810, 0xFFB00F10, vdVnConstraints, InstName.VfmaBfs, T.VfmaBfsT1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None), + new(0xEF200C10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vfms, T.VfmsT1, IsaVersion.v80, InstFlags.None), + new(0xEF300C10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vfms, T.VfmsT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEEA00A40, 0xFFB00E50, InstName.Vfms, T.VfmsT2, IsaVersion.v80, InstFlags.None), + new(0xEEA00940, 0xFFB00F50, InstName.Vfms, T.VfmsT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFCA00810, 0xFFB00F10, qvdConstraints, InstName.Vfmsl, T.VfmslT1, IsaVersion.v82, IsaFeature.FeatFhm, InstFlags.None), + new(0xFE100810, 0xFFB00F10, qvdConstraints, InstName.VfmslS, T.VfmslST1, IsaVersion.v82, IsaFeature.FeatFhm, InstFlags.None), + new(0xEE900A40, 0xFFB00E50, InstName.Vfnma, T.VfnmaT1, IsaVersion.v80, InstFlags.None), + new(0xEE900940, 0xFFB00F50, InstName.Vfnma, T.VfnmaT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEE900A00, 0xFFB00E50, InstName.Vfnms, T.VfnmsT1, IsaVersion.v80, InstFlags.None), + new(0xEE900900, 0xFFB00F50, InstName.Vfnms, T.VfnmsT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF000000, 0xEF800F10, qvdQvnQvmSizeConstraints, InstName.Vhadd, T.VhaddT1, IsaVersion.v80, InstFlags.None), + new(0xEF000200, 0xEF800F10, qvdQvnQvmSizeConstraints, InstName.Vhsub, T.VhsubT1, IsaVersion.v80, InstFlags.None), + new(0xFEB00AC0, 0xFFBF0FD0, InstName.Vins, T.VinsT1, IsaVersion.v82, IsaFeature.FeatFp16, InstFlags.None), + new(0xEEB90BC0, 0xFFBF0FD0, InstName.Vjcvt, T.VjcvtT1, IsaVersion.v83, IsaFeature.FeatJscvt, InstFlags.None), + new(0xF9A00000, 0xFFB00F10, sizeConstraints2, InstName.Vld11, T.Vld11T1, IsaVersion.v80, InstFlags.None), + new(0xF9A00400, 0xFFB00F20, sizeConstraints2, InstName.Vld11, T.Vld11T2, IsaVersion.v80, InstFlags.None), + new(0xF9A00800, 0xFFB00F40, sizeIndexAlignIndexAlignConstraints, InstName.Vld11, T.Vld11T3, IsaVersion.v80, InstFlags.None), + new(0xF9A00C00, 0xFFB00F00, sizeSizeaConstraints, InstName.Vld1A, T.Vld1AT1, IsaVersion.v80, InstFlags.None), + new(0xF9200700, 0xFFB00F00, alignConstraints, InstName.Vld1M, T.Vld1MT1, IsaVersion.v80, InstFlags.None), + new(0xF9200A00, 0xFFB00F00, alignConstraints2, InstName.Vld1M, T.Vld1MT2, IsaVersion.v80, InstFlags.None), + new(0xF9200600, 0xFFB00F00, alignConstraints, InstName.Vld1M, T.Vld1MT3, IsaVersion.v80, InstFlags.None), + new(0xF9200200, 0xFFB00F00, InstName.Vld1M, T.Vld1MT4, IsaVersion.v80, InstFlags.None), + new(0xF9A00100, 0xFFB00F00, sizeConstraints2, InstName.Vld21, T.Vld21T1, IsaVersion.v80, InstFlags.None), + new(0xF9A00500, 0xFFB00F00, sizeConstraints2, InstName.Vld21, T.Vld21T2, IsaVersion.v80, InstFlags.None), + new(0xF9A00900, 0xFFB00F20, sizeConstraints2, InstName.Vld21, T.Vld21T3, IsaVersion.v80, InstFlags.None), + new(0xF9A00D00, 0xFFB00F00, sizeConstraints3, InstName.Vld2A, T.Vld2AT1, IsaVersion.v80, InstFlags.None), + new(0xF9200800, 0xFFB00E00, alignSizeConstraints, InstName.Vld2M, T.Vld2MT1, IsaVersion.v80, InstFlags.None), + new(0xF9200300, 0xFFB00F00, sizeConstraints3, InstName.Vld2M, T.Vld2MT2, IsaVersion.v80, InstFlags.None), + new(0xF9A00200, 0xFFB00F10, sizeConstraints2, InstName.Vld31, T.Vld31T1, IsaVersion.v80, InstFlags.None), + new(0xF9A00600, 0xFFB00F10, sizeConstraints2, InstName.Vld31, T.Vld31T2, IsaVersion.v80, InstFlags.None), + new(0xF9A00A00, 0xFFB00F30, sizeConstraints2, InstName.Vld31, T.Vld31T3, IsaVersion.v80, InstFlags.None), + new(0xF9A00E00, 0xFFB00F10, sizeAConstraints, InstName.Vld3A, T.Vld3AT1, IsaVersion.v80, InstFlags.None), + new(0xF9200400, 0xFFB00E00, sizeAlignConstraints, InstName.Vld3M, T.Vld3MT1, IsaVersion.v80, InstFlags.None), + new(0xF9A00300, 0xFFB00F00, sizeConstraints2, InstName.Vld41, T.Vld41T1, IsaVersion.v80, InstFlags.None), + new(0xF9A00700, 0xFFB00F00, sizeConstraints2, InstName.Vld41, T.Vld41T2, IsaVersion.v80, InstFlags.None), + new(0xF9A00B00, 0xFFB00F00, sizeIndexAlignConstraints, InstName.Vld41, T.Vld41T3, IsaVersion.v80, InstFlags.None), + new(0xF9A00F00, 0xFFB00F00, sizeaConstraints, InstName.Vld4A, T.Vld4AT1, IsaVersion.v80, InstFlags.None), + new(0xF9200000, 0xFFB00E00, sizeConstraints3, InstName.Vld4M, T.Vld4MT1, IsaVersion.v80, InstFlags.None), + new(0xEC100B00, 0xFE100F01, puwPwPuwPuwConstraints, InstName.Vldm, T.VldmT1, IsaVersion.v80, InstFlags.WBack), + new(0xEC100A00, 0xFE100F00, puwPwPuwPuwConstraints, InstName.Vldm, T.VldmT2, IsaVersion.v80, InstFlags.WBack), + new(0xED100A00, 0xFF300E00, rnConstraints, InstName.VldrI, T.VldrIT1, IsaVersion.v80, InstFlags.None), + new(0xED100900, 0xFF300F00, rnConstraints, InstName.VldrI, T.VldrIT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xED1F0A00, 0xFF3F0E00, InstName.VldrL, T.VldrLT1, IsaVersion.v80, InstFlags.None), + new(0xED1F0900, 0xFF3F0F00, InstName.VldrL, T.VldrLT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFF000F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vmaxnm, T.VmaxnmT1, IsaVersion.v80, InstFlags.None), + new(0xFF100F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vmaxnm, T.VmaxnmT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFE800A00, 0xFFB00E50, sizeConstraints, InstName.Vmaxnm, T.VmaxnmT2, IsaVersion.v80, InstFlags.None), + new(0xFE800900, 0xFFB00F50, sizeConstraints, InstName.Vmaxnm, T.VmaxnmT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF000F00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmaxF, T.VmaxFT1, IsaVersion.v80, InstFlags.None), + new(0xEF100F00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmaxF, T.VmaxFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF000600, 0xEF800F10, qvdQvnQvmSizeConstraints, InstName.VmaxI, T.VmaxIT1, IsaVersion.v80, InstFlags.None), + new(0xFF200F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vminnm, T.VminnmT1, IsaVersion.v80, InstFlags.None), + new(0xFF300F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vminnm, T.VminnmT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFE800A40, 0xFFB00E50, sizeConstraints, InstName.Vminnm, T.VminnmT2, IsaVersion.v80, InstFlags.None), + new(0xFE800940, 0xFFB00F50, sizeConstraints, InstName.Vminnm, T.VminnmT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF200F00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VminF, T.VminFT1, IsaVersion.v80, InstFlags.None), + new(0xEF300F00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VminF, T.VminFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF000610, 0xEF800F10, qvdQvnQvmSizeConstraints, InstName.VminI, T.VminIT1, IsaVersion.v80, InstFlags.None), + new(0xEF800800, 0xEF800F50, sizeVdConstraints, InstName.VmlalI, T.VmlalIT1, IsaVersion.v80, InstFlags.None), + new(0xEF800240, 0xEF800F50, sizeSizeVdConstraints, InstName.VmlalS, T.VmlalST1, IsaVersion.v80, InstFlags.None), + new(0xEF000D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmlaF, T.VmlaFT1, IsaVersion.v80, InstFlags.None), + new(0xEF100D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmlaF, T.VmlaFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEE000A00, 0xFFB00E50, InstName.VmlaF, T.VmlaFT2, IsaVersion.v80, InstFlags.None), + new(0xEE000900, 0xFFB00F50, InstName.VmlaF, T.VmlaFT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF000900, 0xFF800F10, sizeQvdQvnQvmConstraints, InstName.VmlaI, T.VmlaIT1, IsaVersion.v80, InstFlags.None), + new(0xEFA00040, 0xEFA00E50, sizeQvdQvnConstraints, InstName.VmlaS, T.VmlaST1, IsaVersion.v80, InstFlags.None), + new(0xEF900040, 0xEFB00F50, sizeQvdQvnConstraints, InstName.VmlaS, T.VmlaST1, IsaVersion.v80, InstFlags.None), + new(0xEF900140, 0xEFB00F50, sizeQvdQvnConstraints, InstName.VmlaS, T.VmlaST1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF800A00, 0xEF800F50, sizeVdConstraints, InstName.VmlslI, T.VmlslIT1, IsaVersion.v80, InstFlags.None), + new(0xEF800640, 0xEF800F50, sizeSizeVdConstraints, InstName.VmlslS, T.VmlslST1, IsaVersion.v80, InstFlags.None), + new(0xEF200D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmlsF, T.VmlsFT1, IsaVersion.v80, InstFlags.None), + new(0xEF300D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmlsF, T.VmlsFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEE000A40, 0xFFB00E50, InstName.VmlsF, T.VmlsFT2, IsaVersion.v80, InstFlags.None), + new(0xEE000940, 0xFFB00F50, InstName.VmlsF, T.VmlsFT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFF000900, 0xFF800F10, sizeQvdQvnQvmConstraints, InstName.VmlsI, T.VmlsIT1, IsaVersion.v80, InstFlags.None), + new(0xEFA00440, 0xEFA00E50, sizeQvdQvnConstraints, InstName.VmlsS, T.VmlsST1, IsaVersion.v80, InstFlags.None), + new(0xEF900440, 0xEFB00F50, sizeQvdQvnConstraints, InstName.VmlsS, T.VmlsST1, IsaVersion.v80, InstFlags.None), + new(0xEF900540, 0xEFB00F50, sizeQvdQvnConstraints, InstName.VmlsS, T.VmlsST1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFC000C40, 0xFFB00F50, vdVnVmConstraints, InstName.Vmmla, T.VmmlaT1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None), + new(0xEF800A10, 0xEF870FD0, imm3hImm3hImm3hImm3hImm3hVdConstraints, InstName.Vmovl, T.VmovlT1, IsaVersion.v80, InstFlags.None), + new(0xFFB20200, 0xFFB30FD0, sizeVmConstraints, InstName.Vmovn, T.VmovnT1, IsaVersion.v80, InstFlags.None), + new(0xFEB00A40, 0xFFBF0FD0, InstName.Vmovx, T.VmovxT1, IsaVersion.v82, IsaFeature.FeatFp16, InstFlags.None), + new(0xEC400B10, 0xFFE00FD0, InstName.VmovD, T.VmovDT1, IsaVersion.v80, InstFlags.Rt2Read), + new(0xEE000910, 0xFFE00F7F, InstName.VmovH, T.VmovHT1, IsaVersion.v82, IsaFeature.FeatFp16, InstFlags.Rt), + new(0xEF800010, 0xEFB809B0, qvdConstraints, InstName.VmovI, T.VmovIT1, IsaVersion.v80, InstFlags.None), + new(0xEEB00A00, 0xFFB00EF0, InstName.VmovI, T.VmovIT2, IsaVersion.v80, InstFlags.None), + new(0xEEB00900, 0xFFB00FF0, InstName.VmovI, T.VmovIT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF800810, 0xEFB80DB0, qvdConstraints, InstName.VmovI, T.VmovIT3, IsaVersion.v80, InstFlags.None), + new(0xEF800C10, 0xEFB80CB0, qvdConstraints, InstName.VmovI, T.VmovIT4, IsaVersion.v80, InstFlags.None), + new(0xEF800E30, 0xEFB80FB0, qvdConstraints, InstName.VmovI, T.VmovIT5, IsaVersion.v80, InstFlags.None), + new(0xEEB00A40, 0xFFBF0ED0, InstName.VmovR, T.VmovRT2, IsaVersion.v80, InstFlags.None), + new(0xEE000B10, 0xFF900F1F, opc1opc2Constraints, InstName.VmovRs, T.VmovRsT1, IsaVersion.v80, InstFlags.RtRead), + new(0xEE000A10, 0xFFE00F7F, InstName.VmovS, T.VmovST1, IsaVersion.v80, InstFlags.RtRead), + new(0xEE100B10, 0xFF100F1F, uopc1opc2Uopc1opc2Constraints, InstName.VmovSr, T.VmovSrT1, IsaVersion.v80, InstFlags.Rt), + new(0xEC400A10, 0xFFE00FD0, InstName.VmovSs, T.VmovSsT1, IsaVersion.v80, InstFlags.Rt2Read), + new(0xEEF00A10, 0xFFF00FFF, InstName.Vmrs, T.VmrsT1, IsaVersion.v80, InstFlags.Rt), + new(0xEEE00A10, 0xFFF00FFF, InstName.Vmsr, T.VmsrT1, IsaVersion.v80, InstFlags.RtRead), + new(0xEF800C00, 0xEF800D50, sizeOpuOpsizeVdConstraints, InstName.VmullI, T.VmullIT1, IsaVersion.v80, InstFlags.None), + new(0xEF800A40, 0xEF800F50, sizeSizeVdConstraints, InstName.VmullS, T.VmullST1, IsaVersion.v80, InstFlags.None), + new(0xFF000D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmulF, T.VmulFT1, IsaVersion.v80, InstFlags.None), + new(0xFF100D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmulF, T.VmulFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEE200A00, 0xFFB00E50, InstName.VmulF, T.VmulFT2, IsaVersion.v80, InstFlags.None), + new(0xEE200900, 0xFFB00F50, InstName.VmulF, T.VmulFT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF000910, 0xEF800F10, sizeOpsizeOpsizeQvdQvnQvmConstraints, InstName.VmulI, T.VmulIT1, IsaVersion.v80, InstFlags.None), + new(0xEFA00840, 0xEFA00E50, sizeQvdQvnConstraints, InstName.VmulS, T.VmulST1, IsaVersion.v80, InstFlags.None), + new(0xEF900840, 0xEFB00F50, sizeQvdQvnConstraints, InstName.VmulS, T.VmulST1, IsaVersion.v80, InstFlags.None), + new(0xEF900940, 0xEFB00F50, sizeQvdQvnConstraints, InstName.VmulS, T.VmulST1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF800030, 0xEFB809B0, cmodeQvdConstraints, InstName.VmvnI, T.VmvnIT1, IsaVersion.v80, InstFlags.None), + new(0xEF800830, 0xEFB80DB0, cmodeQvdConstraints, InstName.VmvnI, T.VmvnIT2, IsaVersion.v80, InstFlags.None), + new(0xEF800C30, 0xEFB80EB0, cmodeQvdConstraints, InstName.VmvnI, T.VmvnIT3, IsaVersion.v80, InstFlags.None), + new(0xFFB00580, 0xFFBF0F90, qvdQvmConstraints, InstName.VmvnR, T.VmvnRT1, IsaVersion.v80, InstFlags.None), + new(0xFFB10380, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vneg, T.VnegT1, IsaVersion.v80, InstFlags.None), + new(0xFFB90780, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.Vneg, T.VnegT1, IsaVersion.v80, InstFlags.None), + new(0xFFB50780, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.Vneg, T.VnegT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEEB10A40, 0xFFBF0ED0, InstName.Vneg, T.VnegT2, IsaVersion.v80, InstFlags.None), + new(0xEEB10940, 0xFFBF0FD0, InstName.Vneg, T.VnegT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEE100A40, 0xFFB00E50, InstName.Vnmla, T.VnmlaT1, IsaVersion.v80, InstFlags.None), + new(0xEE100940, 0xFFB00F50, InstName.Vnmla, T.VnmlaT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEE100A00, 0xFFB00E50, InstName.Vnmls, T.VnmlsT1, IsaVersion.v80, InstFlags.None), + new(0xEE100900, 0xFFB00F50, InstName.Vnmls, T.VnmlsT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEE200A40, 0xFFB00E50, InstName.Vnmul, T.VnmulT1, IsaVersion.v80, InstFlags.None), + new(0xEE200940, 0xFFB00F50, InstName.Vnmul, T.VnmulT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF300110, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VornR, T.VornRT1, IsaVersion.v80, InstFlags.None), + new(0xEF800110, 0xEFB809B0, cmodeCmodeQvdConstraints, InstName.VorrI, T.VorrIT1, IsaVersion.v80, InstFlags.None), + new(0xEF800910, 0xEFB80DB0, cmodeCmodeQvdConstraints, InstName.VorrI, T.VorrIT2, IsaVersion.v80, InstFlags.None), + new(0xEF200110, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VorrR, T.VorrRT1, IsaVersion.v80, InstFlags.None), + new(0xFFB00600, 0xFFB30F10, sizeQvdQvmConstraints, InstName.Vpadal, T.VpadalT1, IsaVersion.v80, InstFlags.None), + new(0xFFB00200, 0xFFB30F10, sizeQvdQvmConstraints, InstName.Vpaddl, T.VpaddlT1, IsaVersion.v80, InstFlags.None), + new(0xFF000D00, 0xFFB00F10, qConstraints, InstName.VpaddF, T.VpaddFT1, IsaVersion.v80, InstFlags.None), + new(0xFF100D00, 0xFFB00F10, qConstraints, InstName.VpaddF, T.VpaddFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF000B10, 0xFF800F10, sizeQConstraints, InstName.VpaddI, T.VpaddIT1, IsaVersion.v80, InstFlags.None), + new(0xFF000F00, 0xFFB00F50, InstName.VpmaxF, T.VpmaxFT1, IsaVersion.v80, InstFlags.None), + new(0xFF100F00, 0xFFB00F50, InstName.VpmaxF, T.VpmaxFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF000A00, 0xEF800F50, sizeConstraints4, InstName.VpmaxI, T.VpmaxIT1, IsaVersion.v80, InstFlags.None), + new(0xFF200F00, 0xFFB00F50, InstName.VpminF, T.VpminFT1, IsaVersion.v80, InstFlags.None), + new(0xFF300F00, 0xFFB00F50, InstName.VpminF, T.VpminFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF000A10, 0xEF800F50, sizeConstraints4, InstName.VpminI, T.VpminIT1, IsaVersion.v80, InstFlags.None), + new(0xFFB00700, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vqabs, T.VqabsT1, IsaVersion.v80, InstFlags.None), + new(0xEF000010, 0xEF800F10, qvdQvnQvmConstraints, InstName.Vqadd, T.VqaddT1, IsaVersion.v80, InstFlags.None), + new(0xEF800900, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmlal, T.VqdmlalT1, IsaVersion.v80, InstFlags.None), + new(0xEF800340, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmlal, T.VqdmlalT2, IsaVersion.v80, InstFlags.None), + new(0xEF800B00, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmlsl, T.VqdmlslT1, IsaVersion.v80, InstFlags.None), + new(0xEF800740, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmlsl, T.VqdmlslT2, IsaVersion.v80, InstFlags.None), + new(0xEF000B00, 0xFF800F10, qvdQvnQvmSizeSizeConstraints, InstName.Vqdmulh, T.VqdmulhT1, IsaVersion.v80, InstFlags.None), + new(0xEF800C40, 0xEF800F50, sizeSizeQvdQvnConstraints, InstName.Vqdmulh, T.VqdmulhT2, IsaVersion.v80, InstFlags.None), + new(0xEF800D00, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmull, T.VqdmullT1, IsaVersion.v80, InstFlags.None), + new(0xEF800B40, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmull, T.VqdmullT2, IsaVersion.v80, InstFlags.None), + new(0xFFB20200, 0xFFB30F10, opSizeVmConstraints, InstName.Vqmovn, T.VqmovnT1, IsaVersion.v80, InstFlags.None), + new(0xFFB00780, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vqneg, T.VqnegT1, IsaVersion.v80, InstFlags.None), + new(0xFF000B10, 0xFF800F10, qvdQvnQvmSizeSizeConstraints, InstName.Vqrdmlah, T.VqrdmlahT1, IsaVersion.v81, IsaFeature.FeatRdm, InstFlags.None), + new(0xEF800E40, 0xEF800F50, sizeSizeQvdQvnConstraints, InstName.Vqrdmlah, T.VqrdmlahT2, IsaVersion.v81, IsaFeature.FeatRdm, InstFlags.None), + new(0xFF000C10, 0xFF800F10, qvdQvnQvmSizeSizeConstraints, InstName.Vqrdmlsh, T.VqrdmlshT1, IsaVersion.v81, IsaFeature.FeatRdm, InstFlags.None), + new(0xEF800F40, 0xEF800F50, sizeSizeQvdQvnConstraints, InstName.Vqrdmlsh, T.VqrdmlshT2, IsaVersion.v81, IsaFeature.FeatRdm, InstFlags.None), + new(0xFF000B00, 0xFF800F10, qvdQvnQvmSizeSizeConstraints, InstName.Vqrdmulh, T.VqrdmulhT1, IsaVersion.v80, InstFlags.None), + new(0xEF800D40, 0xEF800F50, sizeSizeQvdQvnConstraints, InstName.Vqrdmulh, T.VqrdmulhT2, IsaVersion.v80, InstFlags.None), + new(0xEF000510, 0xEF800F10, qvdQvmQvnConstraints, InstName.Vqrshl, T.VqrshlT1, IsaVersion.v80, InstFlags.None), + new(0xEF800850, 0xEF800ED0, imm6UopVmConstraints, InstName.Vqrshrn, T.VqrshrnT1, IsaVersion.v80, InstFlags.None), + new(0xEF800610, 0xEF800E10, imm6lUopQvdQvmConstraints, InstName.VqshlI, T.VqshlIT1, IsaVersion.v80, InstFlags.None), + new(0xEF000410, 0xEF800F10, qvdQvmQvnConstraints, InstName.VqshlR, T.VqshlRT1, IsaVersion.v80, InstFlags.None), + new(0xEF800810, 0xEF800ED0, imm6UopVmConstraints, InstName.Vqshrn, T.VqshrnT1, IsaVersion.v80, InstFlags.None), + new(0xEF000210, 0xEF800F10, qvdQvnQvmConstraints, InstName.Vqsub, T.VqsubT1, IsaVersion.v80, InstFlags.None), + new(0xFF800400, 0xFF800F50, sizeVnVmConstraints, InstName.Vraddhn, T.VraddhnT1, IsaVersion.v80, InstFlags.None), + new(0xFFB30400, 0xFFB30E90, qvdQvmSizeSizeConstraints, InstName.Vrecpe, T.VrecpeT1, IsaVersion.v80, InstFlags.None), + new(0xEF000F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vrecps, T.VrecpsT1, IsaVersion.v80, InstFlags.None), + new(0xEF100F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vrecps, T.VrecpsT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFFB00100, 0xFFB30F90, sizeSizeSizeQvdQvmConstraints, InstName.Vrev16, T.Vrev16T1, IsaVersion.v80, InstFlags.None), + new(0xFFB00080, 0xFFB30F90, sizeSizeQvdQvmConstraints, InstName.Vrev32, T.Vrev32T1, IsaVersion.v80, InstFlags.None), + new(0xFFB00000, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vrev64, T.Vrev64T1, IsaVersion.v80, InstFlags.None), + new(0xEF000100, 0xEF800F10, qvdQvnQvmSizeConstraints, InstName.Vrhadd, T.VrhaddT1, IsaVersion.v80, InstFlags.None), + new(0xFFBA0500, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintaAsimd, T.VrintaAsimdT1, IsaVersion.v80, InstFlags.None), + new(0xFFB60500, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintaAsimd, T.VrintaAsimdT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFEB80A40, 0xFFBF0ED0, sizeConstraints, InstName.VrintaVfp, T.VrintaVfpT1, IsaVersion.v80, InstFlags.None), + new(0xFEB80940, 0xFFBF0FD0, sizeConstraints, InstName.VrintaVfp, T.VrintaVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFFBA0680, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintmAsimd, T.VrintmAsimdT1, IsaVersion.v80, InstFlags.None), + new(0xFFB60680, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintmAsimd, T.VrintmAsimdT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFEBB0A40, 0xFFBF0ED0, sizeConstraints, InstName.VrintmVfp, T.VrintmVfpT1, IsaVersion.v80, InstFlags.None), + new(0xFEBB0940, 0xFFBF0FD0, sizeConstraints, InstName.VrintmVfp, T.VrintmVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFFBA0400, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintnAsimd, T.VrintnAsimdT1, IsaVersion.v80, InstFlags.None), + new(0xFFB60400, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintnAsimd, T.VrintnAsimdT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFEB90A40, 0xFFBF0ED0, sizeConstraints, InstName.VrintnVfp, T.VrintnVfpT1, IsaVersion.v80, InstFlags.None), + new(0xFEB90940, 0xFFBF0FD0, sizeConstraints, InstName.VrintnVfp, T.VrintnVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFFBA0780, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintpAsimd, T.VrintpAsimdT1, IsaVersion.v80, InstFlags.None), + new(0xFFB60780, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintpAsimd, T.VrintpAsimdT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFEBA0A40, 0xFFBF0ED0, sizeConstraints, InstName.VrintpVfp, T.VrintpVfpT1, IsaVersion.v80, InstFlags.None), + new(0xFEBA0940, 0xFFBF0FD0, sizeConstraints, InstName.VrintpVfp, T.VrintpVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEEB60A40, 0xFFBF0ED0, InstName.VrintrVfp, T.VrintrVfpT1, IsaVersion.v80, InstFlags.None), + new(0xEEB60940, 0xFFBF0FD0, InstName.VrintrVfp, T.VrintrVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFFBA0480, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintxAsimd, T.VrintxAsimdT1, IsaVersion.v80, InstFlags.None), + new(0xFFB60480, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintxAsimd, T.VrintxAsimdT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEEB70A40, 0xFFBF0ED0, InstName.VrintxVfp, T.VrintxVfpT1, IsaVersion.v80, InstFlags.None), + new(0xEEB70940, 0xFFBF0FD0, InstName.VrintxVfp, T.VrintxVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFFBA0580, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintzAsimd, T.VrintzAsimdT1, IsaVersion.v80, InstFlags.None), + new(0xFFB60580, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintzAsimd, T.VrintzAsimdT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEEB60AC0, 0xFFBF0ED0, InstName.VrintzVfp, T.VrintzVfpT1, IsaVersion.v80, InstFlags.None), + new(0xEEB609C0, 0xFFBF0FD0, InstName.VrintzVfp, T.VrintzVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF000500, 0xEF800F10, qvdQvmQvnConstraints, InstName.Vrshl, T.VrshlT1, IsaVersion.v80, InstFlags.None), + new(0xEF800210, 0xEF800F10, imm6lQvdQvmConstraints, InstName.Vrshr, T.VrshrT1, IsaVersion.v80, InstFlags.None), + new(0xEF800850, 0xFF800FD0, imm6VmConstraints, InstName.Vrshrn, T.VrshrnT1, IsaVersion.v80, InstFlags.None), + new(0xFFB30480, 0xFFB30E90, qvdQvmSizeSizeConstraints, InstName.Vrsqrte, T.VrsqrteT1, IsaVersion.v80, InstFlags.None), + new(0xEF200F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vrsqrts, T.VrsqrtsT1, IsaVersion.v80, InstFlags.None), + new(0xEF300F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vrsqrts, T.VrsqrtsT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF800310, 0xEF800F10, imm6lQvdQvmConstraints, InstName.Vrsra, T.VrsraT1, IsaVersion.v80, InstFlags.None), + new(0xFF800600, 0xFF800F50, sizeVnVmConstraints, InstName.Vrsubhn, T.VrsubhnT1, IsaVersion.v80, InstFlags.None), + new(0xFC200D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vsdot, T.VsdotT1, IsaVersion.v82, IsaFeature.FeatDotprod, InstFlags.None), + new(0xFE200D00, 0xFFB00F10, qvdQvnConstraints, InstName.VsdotS, T.VsdotST1, IsaVersion.v82, IsaFeature.FeatDotprod, InstFlags.None), + new(0xFE000A00, 0xFF800E50, sizeConstraints, InstName.Vsel, T.VselT1, IsaVersion.v80, InstFlags.None), + new(0xFE000900, 0xFF800F50, sizeConstraints, InstName.Vsel, T.VselT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF800A10, 0xEF800FD0, imm6VdImm6Imm6Imm6Constraints, InstName.Vshll, T.VshllT1, IsaVersion.v80, InstFlags.None), + new(0xFFB20300, 0xFFB30FD0, sizeVdConstraints2, InstName.Vshll, T.VshllT2, IsaVersion.v80, InstFlags.None), + new(0xEF800510, 0xFF800F10, imm6lQvdQvmConstraints, InstName.VshlI, T.VshlIT1, IsaVersion.v80, InstFlags.None), + new(0xEF000400, 0xEF800F10, qvdQvmQvnConstraints, InstName.VshlR, T.VshlRT1, IsaVersion.v80, InstFlags.None), + new(0xEF800010, 0xEF800F10, imm6lQvdQvmConstraints, InstName.Vshr, T.VshrT1, IsaVersion.v80, InstFlags.None), + new(0xEF800810, 0xFF800FD0, imm6VmConstraints, InstName.Vshrn, T.VshrnT1, IsaVersion.v80, InstFlags.None), + new(0xFF800510, 0xFF800F10, imm6lQvdQvmConstraints, InstName.Vsli, T.VsliT1, IsaVersion.v80, InstFlags.None), + new(0xFC200C40, 0xFFB00F50, vdVnVmConstraints, InstName.Vsmmla, T.VsmmlaT1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None), + new(0xEEB10AC0, 0xFFBF0ED0, InstName.Vsqrt, T.VsqrtT1, IsaVersion.v80, InstFlags.None), + new(0xEEB109C0, 0xFFBF0FD0, InstName.Vsqrt, T.VsqrtT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF800110, 0xEF800F10, imm6lQvdQvmConstraints, InstName.Vsra, T.VsraT1, IsaVersion.v80, InstFlags.None), + new(0xFF800410, 0xFF800F10, imm6lQvdQvmConstraints, InstName.Vsri, T.VsriT1, IsaVersion.v80, InstFlags.None), + new(0xF9800000, 0xFFB00F10, sizeConstraints2, InstName.Vst11, T.Vst11T1, IsaVersion.v80, InstFlags.None), + new(0xF9800400, 0xFFB00F20, sizeConstraints2, InstName.Vst11, T.Vst11T2, IsaVersion.v80, InstFlags.None), + new(0xF9800800, 0xFFB00F40, sizeIndexAlignIndexAlignConstraints, InstName.Vst11, T.Vst11T3, IsaVersion.v80, InstFlags.None), + new(0xF9000700, 0xFFB00F00, alignConstraints, InstName.Vst1M, T.Vst1MT1, IsaVersion.v80, InstFlags.None), + new(0xF9000A00, 0xFFB00F00, alignConstraints2, InstName.Vst1M, T.Vst1MT2, IsaVersion.v80, InstFlags.None), + new(0xF9000600, 0xFFB00F00, alignConstraints, InstName.Vst1M, T.Vst1MT3, IsaVersion.v80, InstFlags.None), + new(0xF9000200, 0xFFB00F00, InstName.Vst1M, T.Vst1MT4, IsaVersion.v80, InstFlags.None), + new(0xF9800100, 0xFFB00F00, sizeConstraints2, InstName.Vst21, T.Vst21T1, IsaVersion.v80, InstFlags.None), + new(0xF9800500, 0xFFB00F00, sizeConstraints2, InstName.Vst21, T.Vst21T2, IsaVersion.v80, InstFlags.None), + new(0xF9800900, 0xFFB00F20, sizeConstraints2, InstName.Vst21, T.Vst21T3, IsaVersion.v80, InstFlags.None), + new(0xF9000800, 0xFFB00E00, alignSizeConstraints, InstName.Vst2M, T.Vst2MT1, IsaVersion.v80, InstFlags.None), + new(0xF9000300, 0xFFB00F00, sizeConstraints3, InstName.Vst2M, T.Vst2MT2, IsaVersion.v80, InstFlags.None), + new(0xF9800200, 0xFFB00F10, sizeConstraints2, InstName.Vst31, T.Vst31T1, IsaVersion.v80, InstFlags.None), + new(0xF9800600, 0xFFB00F10, sizeConstraints2, InstName.Vst31, T.Vst31T2, IsaVersion.v80, InstFlags.None), + new(0xF9800A00, 0xFFB00F30, sizeConstraints2, InstName.Vst31, T.Vst31T3, IsaVersion.v80, InstFlags.None), + new(0xF9000400, 0xFFB00E00, sizeAlignConstraints, InstName.Vst3M, T.Vst3MT1, IsaVersion.v80, InstFlags.None), + new(0xF9800300, 0xFFB00F00, sizeConstraints2, InstName.Vst41, T.Vst41T1, IsaVersion.v80, InstFlags.None), + new(0xF9800700, 0xFFB00F00, sizeConstraints2, InstName.Vst41, T.Vst41T2, IsaVersion.v80, InstFlags.None), + new(0xF9800B00, 0xFFB00F00, sizeIndexAlignConstraints, InstName.Vst41, T.Vst41T3, IsaVersion.v80, InstFlags.None), + new(0xF9000000, 0xFFB00E00, sizeConstraints3, InstName.Vst4M, T.Vst4MT1, IsaVersion.v80, InstFlags.None), + new(0xEC000B00, 0xFE100F01, puwPwPuwPuwConstraints, InstName.Vstm, T.VstmT1, IsaVersion.v80, InstFlags.WBack), + new(0xEC000A00, 0xFE100F00, puwPwPuwPuwConstraints, InstName.Vstm, T.VstmT2, IsaVersion.v80, InstFlags.WBack), + new(0xED000A00, 0xFF300E00, InstName.Vstr, T.VstrT1, IsaVersion.v80, InstFlags.None), + new(0xED000900, 0xFF300F00, InstName.Vstr, T.VstrT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEF800600, 0xFF800F50, sizeVnVmConstraints, InstName.Vsubhn, T.VsubhnT1, IsaVersion.v80, InstFlags.None), + new(0xEF800200, 0xEF800F50, sizeVdOpvnConstraints, InstName.Vsubl, T.VsublT1, IsaVersion.v80, InstFlags.None), + new(0xEF800300, 0xEF800F50, sizeVdOpvnConstraints, InstName.Vsubw, T.VsubwT1, IsaVersion.v80, InstFlags.None), + new(0xEF200D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VsubF, T.VsubFT1, IsaVersion.v80, InstFlags.None), + new(0xEF300D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VsubF, T.VsubFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xEE300A40, 0xFFB00E50, InstName.VsubF, T.VsubFT2, IsaVersion.v80, InstFlags.None), + new(0xEE300940, 0xFFB00F50, InstName.VsubF, T.VsubFT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None), + new(0xFF000800, 0xFF800F10, qvdQvnQvmConstraints, InstName.VsubI, T.VsubIT1, IsaVersion.v80, InstFlags.None), + new(0xFE800D10, 0xFFB00F10, qvdQvnConstraints, InstName.VsudotS, T.VsudotST1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None), + new(0xFFB20000, 0xFFBF0F90, qvdQvmConstraints, InstName.Vswp, T.VswpT1, IsaVersion.v80, InstFlags.None), + new(0xFFB00800, 0xFFB00C10, InstName.Vtbl, T.VtblT1, IsaVersion.v80, InstFlags.None), + new(0xFFB20080, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vtrn, T.VtrnT1, IsaVersion.v80, InstFlags.None), + new(0xEF000810, 0xFF800F10, qvdQvnQvmSizeConstraints, InstName.Vtst, T.VtstT1, IsaVersion.v80, InstFlags.None), + new(0xFC200D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vudot, T.VudotT1, IsaVersion.v82, IsaFeature.FeatDotprod, InstFlags.None), + new(0xFE200D10, 0xFFB00F10, qvdQvnConstraints, InstName.VudotS, T.VudotST1, IsaVersion.v82, IsaFeature.FeatDotprod, InstFlags.None), + new(0xFC200C50, 0xFFB00F50, vdVnVmConstraints, InstName.Vummla, T.VummlaT1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None), + new(0xFCA00D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vusdot, T.VusdotT1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None), + new(0xFE800D00, 0xFFB00F10, qvdQvnConstraints, InstName.VusdotS, T.VusdotST1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None), + new(0xFCA00C40, 0xFFB00F50, vdVnVmConstraints, InstName.Vusmmla, T.VusmmlaT1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None), + new(0xFFB20100, 0xFFB30F90, sizeQsizeQvdQvmConstraints, InstName.Vuzp, T.VuzpT1, IsaVersion.v80, InstFlags.None), + new(0xFFB20180, 0xFFB30F90, sizeQsizeQvdQvmConstraints, InstName.Vzip, T.VzipT1, IsaVersion.v80, InstFlags.None), + new(0xF3AF8002, 0xFFFFFFFF, InstName.Wfe, T.WfeT2, IsaVersion.v80, InstFlags.None), + new(0xF3AF8003, 0xFFFFFFFF, InstName.Wfi, T.WfiT2, IsaVersion.v80, InstFlags.None), + new(0xF3AF8001, 0xFFFFFFFF, InstName.Yield, T.YieldT2, IsaVersion.v80, InstFlags.None), + }; + + _table = new(insts); + } + + public static bool TryGetMeta(uint encoding, IsaVersion version, IsaFeature features, out InstMeta meta) + { + if (_table.TryFind(encoding, version, features, out InstInfoForTable info)) + { + meta = info.Meta; + + return true; + } + + meta = new(InstName.Udf, T.UdfA1, IsaVersion.v80, IsaFeature.None, InstFlags.None); + + return false; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/MultiBlock.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/MultiBlock.cs new file mode 100644 index 000000000..a213c222c --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/MultiBlock.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; + +namespace Ryujinx.Cpu.LightningJit.Arm32 +{ + class MultiBlock + { + public readonly List Blocks; + public readonly bool HasHostCall; + public readonly bool IsTruncated; + + public MultiBlock(List blocks) + { + Blocks = blocks; + + Block block = blocks[0]; + + HasHostCall = block.HasHostCall; + + for (int index = 1; index < blocks.Count; index++) + { + block = blocks[index]; + + HasHostCall |= block.HasHostCall; + } + + block = blocks[^1]; + + IsTruncated = block.IsTruncated; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/PendingBranch.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/PendingBranch.cs new file mode 100644 index 000000000..8f48cd076 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/PendingBranch.cs @@ -0,0 +1,20 @@ +namespace Ryujinx.Cpu.LightningJit.Arm32 +{ + readonly struct PendingBranch + { + public readonly BranchType BranchType; + public readonly uint TargetAddress; + public readonly uint NextAddress; + public readonly InstName Name; + public readonly int WriterPointer; + + public PendingBranch(BranchType branchType, uint targetAddress, uint nextAddress, InstName name, int writerPointer) + { + BranchType = branchType; + TargetAddress = targetAddress; + NextAddress = nextAddress; + Name = name; + WriterPointer = writerPointer; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/RegisterAllocator.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/RegisterAllocator.cs new file mode 100644 index 000000000..6c7057229 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/RegisterAllocator.cs @@ -0,0 +1,169 @@ +using Ryujinx.Cpu.LightningJit.CodeGen; +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; +using System; +using System.Numerics; + +namespace Ryujinx.Cpu.LightningJit.Arm32 +{ + class RegisterAllocator + { + public const int MaxTemps = 1; + + private uint _gprMask; + private uint _fpSimdMask; + + public int FixedContextRegister { get; } + public int FixedPageTableRegister { get; } + + public uint UsedGprsMask { get; private set; } + public uint UsedFpSimdMask { get; private set; } + + public RegisterAllocator() + { + _gprMask = ushort.MaxValue; + _fpSimdMask = ushort.MaxValue; + + FixedContextRegister = AllocateTempRegisterWithPreferencing(); + FixedPageTableRegister = AllocateTempRegisterWithPreferencing(); + } + + public void MarkGprAsUsed(int index) + { + UsedGprsMask |= 1u << index; + } + + public void MarkFpSimdAsUsed(int index) + { + UsedFpSimdMask |= 1u << index; + } + + public void MarkFpSimdRangeAsUsed(int index, int count) + { + UsedFpSimdMask |= (uint.MaxValue >> (32 - count)) << index; + } + + public Operand RemapGprRegister(int index) + { + MarkGprAsUsed(index); + + return new Operand(OperandKind.Register, OperandType.I32, (ulong)index); + } + + public Operand RemapFpRegister(int index, bool isFP32) + { + MarkFpSimdAsUsed(index); + + return new Operand(OperandKind.Register, isFP32 ? OperandType.FP32 : OperandType.FP64, (ulong)index); + } + + public Operand RemapSimdRegister(int index) + { + MarkFpSimdAsUsed(index); + + return new Operand(OperandKind.Register, OperandType.V128, (ulong)index); + } + + public Operand RemapSimdRegister(int index, int count) + { + MarkFpSimdRangeAsUsed(index, count); + + return new Operand(OperandKind.Register, OperandType.V128, (ulong)index); + } + + public void EnsureTempGprRegisters(int count) + { + if (count != 0) + { + Span registers = stackalloc int[count]; + + for (int index = 0; index < count; index++) + { + registers[index] = AllocateTempGprRegister(); + } + + for (int index = 0; index < count; index++) + { + FreeTempGprRegister(registers[index]); + } + } + } + + public int AllocateTempGprRegister() + { + int index = AllocateTempRegister(ref _gprMask, AbiConstants.ReservedRegsMask); + + MarkGprAsUsed(index); + + return index; + } + + private int AllocateTempRegisterWithPreferencing() + { + int firstCalleeSaved = BitOperations.TrailingZeroCount(~_gprMask & AbiConstants.GprCalleeSavedRegsMask); + if (firstCalleeSaved < 32) + { + uint regMask = 1u << firstCalleeSaved; + if ((regMask & AbiConstants.ReservedRegsMask) == 0) + { + _gprMask |= regMask; + + return firstCalleeSaved; + } + } + + return AllocateTempRegister(ref _gprMask, AbiConstants.ReservedRegsMask); + } + + public int AllocateTempFpSimdRegister() + { + int index = AllocateTempRegister(ref _fpSimdMask, 0); + + MarkFpSimdAsUsed(index); + + return index; + } + + public ScopedRegister AllocateTempGprRegisterScoped() + { + return new(this, new(OperandKind.Register, OperandType.I32, (ulong)AllocateTempGprRegister())); + } + + public ScopedRegister AllocateTempFpRegisterScoped(bool isFP32) + { + return new(this, new(OperandKind.Register, isFP32 ? OperandType.FP32 : OperandType.FP64, (ulong)AllocateTempFpSimdRegister())); + } + + public ScopedRegister AllocateTempSimdRegisterScoped() + { + return new(this, new(OperandKind.Register, OperandType.V128, (ulong)AllocateTempFpSimdRegister())); + } + + public void FreeTempGprRegister(int index) + { + FreeTempRegister(ref _gprMask, index); + } + + public void FreeTempFpSimdRegister(int index) + { + FreeTempRegister(ref _fpSimdMask, index); + } + + private static int AllocateTempRegister(ref uint mask, uint reservedMask) + { + int index = BitOperations.TrailingZeroCount(~(mask | reservedMask)); + if (index == sizeof(uint) * 8) + { + throw new InvalidOperationException("No free registers."); + } + + mask |= 1u << index; + + return index; + } + + private static void FreeTempRegister(ref uint mask, int index) + { + mask &= ~(1u << index); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/RegisterUtils.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/RegisterUtils.cs new file mode 100644 index 000000000..8fbdeb731 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/RegisterUtils.cs @@ -0,0 +1,109 @@ +using System; + +namespace Ryujinx.Cpu.LightningJit.Arm32 +{ + static class RegisterUtils + { + public const int SpRegister = 13; + public const int LrRegister = 14; + public const int PcRegister = 15; + + private const int RmBit = 0; + private const int RdRtBit = 12; + private const int RdHiRnBit = 16; + + private const int RdRtT16Bit = 16; + private const int RdRtT16AltBit = 24; + + private const int RdRt2RdHiT32Bit = 8; + private const int RdT32AltBit = 0; + private const int RtRdLoT32Bit = 12; + + public static int ExtractRt(uint encoding) + { + return (int)(encoding >> RdRtBit) & 0xf; + } + + public static int ExtractRt2(uint encoding) + { + return (int)GetRt2((uint)ExtractRt(encoding)); + } + + public static int ExtractRd(InstFlags flags, uint encoding) + { + return flags.HasFlag(InstFlags.Rd16) ? ExtractRn(encoding) : ExtractRd(encoding); + } + + public static int ExtractRd(uint encoding) + { + return (int)(encoding >> RdRtBit) & 0xf; + } + + public static int ExtractRdHi(uint encoding) + { + return (int)(encoding >> RdHiRnBit) & 0xf; + } + + public static int ExtractRn(uint encoding) + { + return (int)(encoding >> RdHiRnBit) & 0xf; + } + + public static int ExtractRm(uint encoding) + { + return (int)(encoding >> RmBit) & 0xf; + } + + public static uint GetRt2(uint rt) + { + return Math.Min(rt + 1, PcRegister); + } + + public static int ExtractRdn(InstFlags flags, uint encoding) + { + if (flags.HasFlag(InstFlags.Dn)) + { + return ((int)(encoding >> RdRtT16Bit) & 7) | (int)((encoding >> 4) & 8); + } + else + { + return ExtractRdT16(flags, encoding); + } + } + + public static int ExtractRdT16(InstFlags flags, uint encoding) + { + return flags.HasFlag(InstFlags.Rd16) ? (int)(encoding >> RdRtT16AltBit) & 7 : (int)(encoding >> RdRtT16Bit) & 7; + } + + public static int ExtractRtT16(InstFlags flags, uint encoding) + { + return flags.HasFlag(InstFlags.Rd16) ? (int)(encoding >> RdRtT16AltBit) & 7 : (int)(encoding >> RdRtT16Bit) & 7; + } + + public static int ExtractRdT32(InstFlags flags, uint encoding) + { + return flags.HasFlag(InstFlags.Rd16) ? (int)(encoding >> RdT32AltBit) & 0xf : (int)(encoding >> RdRt2RdHiT32Bit) & 0xf; + } + + public static int ExtractRdLoT32(uint encoding) + { + return (int)(encoding >> RtRdLoT32Bit) & 0xf; + } + + public static int ExtractRdHiT32(uint encoding) + { + return (int)(encoding >> RdRt2RdHiT32Bit) & 0xf; + } + + public static int ExtractRtT32(uint encoding) + { + return (int)(encoding >> RtRdLoT32Bit) & 0xf; + } + + public static int ExtractRt2T32(uint encoding) + { + return (int)(encoding >> RdRt2RdHiT32Bit) & 0xf; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/ScopedRegister.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/ScopedRegister.cs new file mode 100644 index 000000000..18b1416ea --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/ScopedRegister.cs @@ -0,0 +1,39 @@ +using Ryujinx.Cpu.LightningJit.CodeGen; +using System; + +namespace Ryujinx.Cpu.LightningJit.Arm32 +{ + readonly struct ScopedRegister : IDisposable + { + private readonly RegisterAllocator _registerAllocator; + private readonly Operand _operand; + private readonly bool _isAllocated; + + public readonly Operand Operand => _operand; + public readonly bool IsAllocated => _isAllocated; + + public ScopedRegister(RegisterAllocator registerAllocator, Operand operand, bool isAllocated = true) + { + _registerAllocator = registerAllocator; + _operand = operand; + _isAllocated = isAllocated; + } + + public readonly void Dispose() + { + if (!_isAllocated) + { + return; + } + + if (_operand.Type.IsInteger()) + { + _registerAllocator.FreeTempGprRegister(_operand.AsInt32()); + } + else + { + _registerAllocator.FreeTempFpSimdRegister(_operand.AsInt32()); + } + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/Compiler.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/Compiler.cs new file mode 100644 index 000000000..1e8a89157 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/Compiler.cs @@ -0,0 +1,789 @@ +using ARMeilleure.Common; +using ARMeilleure.Memory; +using Ryujinx.Cpu.LightningJit.CodeGen; +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Numerics; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class Compiler + { + public const uint UsableGprsMask = 0x7fff; + public const uint UsableFpSimdMask = 0xffff; + public const uint UsablePStateMask = 0xf0000000; + + private const int Encodable26BitsOffsetLimit = 0x2000000; + + private readonly struct Context + { + public readonly CodeWriter Writer; + public readonly RegisterAllocator RegisterAllocator; + public readonly MemoryManagerType MemoryManagerType; + public readonly TailMerger TailMerger; + public readonly AddressTable FuncTable; + public readonly IntPtr DispatchStubPointer; + + private readonly RegisterSaveRestore _registerSaveRestore; + private readonly IntPtr _pageTablePointer; + + public Context( + CodeWriter writer, + RegisterAllocator registerAllocator, + MemoryManagerType mmType, + TailMerger tailMerger, + AddressTable funcTable, + RegisterSaveRestore registerSaveRestore, + IntPtr dispatchStubPointer, + IntPtr pageTablePointer) + { + Writer = writer; + RegisterAllocator = registerAllocator; + MemoryManagerType = mmType; + TailMerger = tailMerger; + FuncTable = funcTable; + _registerSaveRestore = registerSaveRestore; + DispatchStubPointer = dispatchStubPointer; + _pageTablePointer = pageTablePointer; + } + + public readonly int GetReservedStackOffset() + { + return _registerSaveRestore.GetReservedStackOffset(); + } + + public readonly void WritePrologueAt(int instructionPointer) + { + CodeWriter writer = new(); + Assembler asm = new(writer); + + _registerSaveRestore.WritePrologue(ref asm); + + // If needed, set up the fixed registers with the pointers we will use. + // First one is the context pointer (passed as first argument), + // second one is the page table or address space base, it is at a fixed memory location and considered constant. + + if (RegisterAllocator.FixedContextRegister != 0) + { + asm.Mov(Register(RegisterAllocator.FixedContextRegister), Register(0)); + } + + asm.Mov(Register(RegisterAllocator.FixedPageTableRegister), (ulong)_pageTablePointer); + + LoadFromContext(ref asm); + + // Write the prologue at the specified position in our writer. + Writer.WriteInstructionsAt(instructionPointer, writer); + } + + public readonly void WriteEpilogueWithoutContext() + { + Assembler asm = new(Writer); + + _registerSaveRestore.WriteEpilogue(ref asm); + } + + public void LoadFromContext() + { + Assembler asm = new(Writer); + + LoadFromContext(ref asm); + } + + private void LoadFromContext(ref Assembler asm) + { + LoadGprFromContext(ref asm, RegisterAllocator.UsedGprsMask & UsableGprsMask, NativeContextOffsets.GprBaseOffset); + LoadFpSimdFromContext(ref asm, RegisterAllocator.UsedFpSimdMask & UsableFpSimdMask, NativeContextOffsets.FpSimdBaseOffset); + LoadPStateFromContext(ref asm, UsablePStateMask, NativeContextOffsets.FlagsBaseOffset); + } + + public void StoreToContext() + { + Assembler asm = new(Writer); + + StoreToContext(ref asm); + } + + private void StoreToContext(ref Assembler asm) + { + StoreGprToContext(ref asm, RegisterAllocator.UsedGprsMask & UsableGprsMask, NativeContextOffsets.GprBaseOffset); + StoreFpSimdToContext(ref asm, RegisterAllocator.UsedFpSimdMask & UsableFpSimdMask, NativeContextOffsets.FpSimdBaseOffset); + StorePStateToContext(ref asm, UsablePStateMask, NativeContextOffsets.FlagsBaseOffset); + } + + private void LoadGprFromContext(ref Assembler asm, uint mask, int baseOffset) + { + Operand contextPtr = Register(RegisterAllocator.FixedContextRegister); + + while (mask != 0) + { + int reg = BitOperations.TrailingZeroCount(mask); + int offset = baseOffset + reg * 8; + + if (reg < 31 && (mask & (2u << reg)) != 0 && offset < RegisterSaveRestore.Encodable9BitsOffsetLimit) + { + mask &= ~(3u << reg); + + asm.LdpRiUn(Register(reg), Register(reg + 1), contextPtr, offset); + } + else + { + mask &= ~(1u << reg); + + asm.LdrRiUn(Register(reg), contextPtr, offset); + } + } + } + + private void LoadFpSimdFromContext(ref Assembler asm, uint mask, int baseOffset) + { + Operand contextPtr = Register(RegisterAllocator.FixedContextRegister); + + while (mask != 0) + { + int reg = BitOperations.TrailingZeroCount(mask); + int offset = baseOffset + reg * 16; + + mask &= ~(1u << reg); + + asm.LdrRiUn(Register(reg, OperandType.V128), contextPtr, offset); + } + } + + private void LoadPStateFromContext(ref Assembler asm, uint mask, int baseOffset) + { + if (mask == 0) + { + return; + } + + Operand contextPtr = Register(RegisterAllocator.FixedContextRegister); + + using ScopedRegister tempRegister = RegisterAllocator.AllocateTempGprRegisterScoped(); + + asm.LdrRiUn(tempRegister.Operand, contextPtr, baseOffset); + asm.MsrNzcv(tempRegister.Operand); + } + + private void StoreGprToContext(ref Assembler asm, uint mask, int baseOffset) + { + Operand contextPtr = Register(RegisterAllocator.FixedContextRegister); + + while (mask != 0) + { + int reg = BitOperations.TrailingZeroCount(mask); + int offset = baseOffset + reg * 8; + + if (reg < 31 && (mask & (2u << reg)) != 0 && offset < RegisterSaveRestore.Encodable9BitsOffsetLimit) + { + mask &= ~(3u << reg); + + asm.StpRiUn(Register(reg), Register(reg + 1), contextPtr, offset); + } + else + { + mask &= ~(1u << reg); + + asm.StrRiUn(Register(reg), contextPtr, offset); + } + } + } + + private void StoreFpSimdToContext(ref Assembler asm, uint mask, int baseOffset) + { + Operand contextPtr = Register(RegisterAllocator.FixedContextRegister); + + while (mask != 0) + { + int reg = BitOperations.TrailingZeroCount(mask); + int offset = baseOffset + reg * 16; + + mask &= ~(1u << reg); + + asm.StrRiUn(Register(reg, OperandType.V128), contextPtr, offset); + } + } + + private void StorePStateToContext(ref Assembler asm, uint mask, int baseOffset) + { + if (mask == 0) + { + return; + } + + Operand contextPtr = Register(RegisterAllocator.FixedContextRegister); + + using ScopedRegister tempRegister = RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempRegister2 = RegisterAllocator.AllocateTempGprRegisterScoped(); + + asm.LdrRiUn(tempRegister.Operand, contextPtr, baseOffset); + asm.MrsNzcv(tempRegister2.Operand); + asm.And(tempRegister.Operand, tempRegister.Operand, InstEmitCommon.Const(0xfffffff)); + asm.Orr(tempRegister.Operand, tempRegister.Operand, tempRegister2.Operand); + asm.StrRiUn(tempRegister.Operand, contextPtr, baseOffset); + } + } + + public static CompiledFunction Compile(CpuPreset cpuPreset, IMemoryManager memoryManager, ulong address, AddressTable funcTable, IntPtr dispatchStubPtr, bool isThumb) + { + MultiBlock multiBlock = Decoder.DecodeMulti(cpuPreset, memoryManager, address, isThumb); + + Dictionary targets = new(); + + CodeWriter writer = new(); + RegisterAllocator regAlloc = new(); + Assembler asm = new(writer); + CodeGenContext cgContext = new(writer, asm, regAlloc, memoryManager.Type, isThumb); + ArmCondition lastCondition = ArmCondition.Al; + int lastConditionIp = 0; + + // Required for load/store to context. + regAlloc.EnsureTempGprRegisters(2); + + ulong pc = address; + + for (int blockIndex = 0; blockIndex < multiBlock.Blocks.Count; blockIndex++) + { + Block block = multiBlock.Blocks[blockIndex]; + + Debug.Assert(block.Address == pc); + + targets.Add(pc, writer.InstructionPointer); + + for (int index = 0; index < block.Instructions.Count; index++) + { + InstInfo instInfo = block.Instructions[index]; + + if (index < block.Instructions.Count - 1) + { + cgContext.SetNextInstruction(block.Instructions[index + 1]); + } + else + { + cgContext.SetNextInstruction(default); + } + + SetConditionalStart(cgContext, ref lastCondition, ref lastConditionIp, instInfo.Name, instInfo.Flags, instInfo.Encoding); + + if (block.IsLoopEnd && index == block.Instructions.Count - 1) + { + // If this is a loop, the code might run for a long time uninterrupted. + // We insert a "sync point" here to ensure the loop can be interrupted if needed. + + cgContext.AddPendingSyncPoint(); + + asm.B(0); + } + + cgContext.SetPc((uint)pc); + + instInfo.EmitFunc(cgContext, instInfo.Encoding); + + if (cgContext.ConsumeNzcvModified()) + { + ForceConditionalEnd(cgContext, ref lastCondition, lastConditionIp); + } + + cgContext.UpdateItState(); + + pc += instInfo.Flags.HasFlag(InstFlags.Thumb16) ? 2UL : 4UL; + } + + if (Decoder.WritesToPC(block.Instructions[^1].Encoding, block.Instructions[^1].Name, block.Instructions[^1].Flags, block.IsThumb)) + { + // If the block ends with a PC register write, then we have a branch from register. + + InstEmitCommon.SetThumbFlag(cgContext, regAlloc.RemapGprRegister(RegisterUtils.PcRegister)); + + cgContext.AddPendingIndirectBranch(block.Instructions[^1].Name, RegisterUtils.PcRegister); + + asm.B(0); + } + + ForceConditionalEnd(cgContext, ref lastCondition, lastConditionIp); + } + + RegisterSaveRestore rsr = new( + regAlloc.UsedGprsMask & AbiConstants.GprCalleeSavedRegsMask, + regAlloc.UsedFpSimdMask & AbiConstants.FpSimdCalleeSavedRegsMask, + OperandType.FP64, + multiBlock.HasHostCall, + multiBlock.HasHostCall ? CalculateStackSizeForCallSpill(regAlloc.UsedGprsMask, regAlloc.UsedFpSimdMask, UsablePStateMask) : 0); + + TailMerger tailMerger = new(); + + Context context = new(writer, regAlloc, memoryManager.Type, tailMerger, funcTable, rsr, dispatchStubPtr, memoryManager.PageTablePointer); + + InstInfo lastInstruction = multiBlock.Blocks[^1].Instructions[^1]; + bool lastInstIsConditional = GetCondition(lastInstruction, isThumb) != ArmCondition.Al; + + if (multiBlock.IsTruncated || lastInstIsConditional || lastInstruction.Name.IsCall() || IsConditionalBranch(lastInstruction)) + { + WriteTailCallConstant(context, ref asm, (uint)pc); + } + + IEnumerable pendingBranches = cgContext.GetPendingBranches(); + + foreach (PendingBranch pendingBranch in pendingBranches) + { + RewriteBranchInstructionWithTarget(context, pendingBranch, targets); + } + + tailMerger.WriteReturn(writer, context.WriteEpilogueWithoutContext); + + context.WritePrologueAt(0); + + return new(writer.AsByteSpan(), (int)(pc - address)); + } + + private static int CalculateStackSizeForCallSpill(uint gprUseMask, uint fpSimdUseMask, uint pStateUseMask) + { + // Note that we don't discard callee saved FP/SIMD register because only the lower 64 bits is callee saved, + // so if the function is using the full register, that won't be enough. + // We could do better, but it's likely not worth it since this case happens very rarely in practice. + + return BitOperations.PopCount(gprUseMask & ~AbiConstants.GprCalleeSavedRegsMask) * 8 + + BitOperations.PopCount(fpSimdUseMask) * 16 + + (pStateUseMask != 0 ? 8 : 0); + } + + private static void SetConditionalStart( + CodeGenContext context, + ref ArmCondition condition, + ref int instructionPointer, + InstName name, + InstFlags flags, + uint encoding) + { + if (!context.ConsumeItCondition(out ArmCondition currentCond)) + { + currentCond = GetCondition(name, flags, encoding, context.IsThumb); + } + + if (currentCond != condition) + { + WriteConditionalEnd(context, condition, instructionPointer); + + condition = currentCond; + + if (currentCond != ArmCondition.Al) + { + instructionPointer = context.CodeWriter.InstructionPointer; + context.Arm64Assembler.B(currentCond.Invert(), 0); + } + } + } + + private static bool IsConditionalBranch(in InstInfo instInfo) + { + return instInfo.Name == InstName.B && (ArmCondition)(instInfo.Encoding >> 28) != ArmCondition.Al; + } + + private static ArmCondition GetCondition(in InstInfo instInfo, bool isThumb) + { + return GetCondition(instInfo.Name, instInfo.Flags, instInfo.Encoding, isThumb); + } + + private static ArmCondition GetCondition(InstName name, InstFlags flags, uint encoding, bool isThumb) + { + // For branch, we handle conditional execution on the instruction itself. + bool hasCond = flags.HasFlag(InstFlags.Cond) && !CanHandleConditionalInstruction(name, encoding, isThumb); + + return hasCond ? (ArmCondition)(encoding >> 28) : ArmCondition.Al; + } + + private static bool CanHandleConditionalInstruction(InstName name, uint encoding, bool isThumb) + { + if (name == InstName.B) + { + return true; + } + + // We can use CSEL for conditional MOV from registers, as long the instruction is not setting flags. + // We don't handle thumb right now because the condition comes from the IT block which would be more complicated to handle. + if (name == InstName.MovR && !isThumb && (encoding & (1u << 20)) == 0) + { + return true; + } + + return false; + } + + private static void ForceConditionalEnd(CodeGenContext context, ref ArmCondition condition, int instructionPointer) + { + WriteConditionalEnd(context, condition, instructionPointer); + + condition = ArmCondition.Al; + } + + private static void WriteConditionalEnd(CodeGenContext context, ArmCondition condition, int instructionPointer) + { + if (condition != ArmCondition.Al) + { + int delta = context.CodeWriter.InstructionPointer - instructionPointer; + uint branchInst = context.CodeWriter.ReadInstructionAt(instructionPointer) | (((uint)delta & 0x7ffff) << 5); + Debug.Assert((int)((branchInst & ~0x1fu) << 8) >> 11 == delta * 4); + + context.CodeWriter.WriteInstructionAt(instructionPointer, branchInst); + } + } + + private static void RewriteBranchInstructionWithTarget(in Context context, in PendingBranch pendingBranch, Dictionary targets) + { + switch (pendingBranch.BranchType) + { + case BranchType.Branch: + RewriteBranchInstructionWithTarget(context, pendingBranch.Name, pendingBranch.TargetAddress, pendingBranch.WriterPointer, targets); + break; + case BranchType.Call: + RewriteCallInstructionWithTarget(context, pendingBranch.TargetAddress, pendingBranch.NextAddress, pendingBranch.WriterPointer); + break; + case BranchType.IndirectBranch: + RewriteIndirectBranchInstructionWithTarget(context, pendingBranch.Name, pendingBranch.TargetAddress, pendingBranch.WriterPointer); + break; + case BranchType.TableBranchByte: + case BranchType.TableBranchHalfword: + RewriteTableBranchInstructionWithTarget( + context, + pendingBranch.BranchType == BranchType.TableBranchHalfword, + pendingBranch.TargetAddress, + pendingBranch.NextAddress, + pendingBranch.WriterPointer); + break; + case BranchType.IndirectCall: + RewriteIndirectCallInstructionWithTarget(context, pendingBranch.TargetAddress, pendingBranch.NextAddress, pendingBranch.WriterPointer); + break; + case BranchType.SyncPoint: + case BranchType.SoftwareInterrupt: + case BranchType.ReadCntpct: + RewriteHostCall(context, pendingBranch.Name, pendingBranch.BranchType, pendingBranch.TargetAddress, pendingBranch.NextAddress, pendingBranch.WriterPointer); + break; + default: + Debug.Fail($"Invalid branch type '{pendingBranch.BranchType}'"); + break; + } + } + + private static void RewriteBranchInstructionWithTarget(in Context context, InstName name, uint targetAddress, int branchIndex, Dictionary targets) + { + CodeWriter writer = context.Writer; + Assembler asm = new(writer); + + int delta; + int targetIndex; + uint encoding = writer.ReadInstructionAt(branchIndex); + + if (encoding == 0x14000000) + { + // Unconditional branch. + + if (targets.TryGetValue(targetAddress, out targetIndex)) + { + delta = targetIndex - branchIndex; + + if (delta >= -Encodable26BitsOffsetLimit && delta < Encodable26BitsOffsetLimit) + { + writer.WriteInstructionAt(branchIndex, encoding | (uint)(delta & 0x3ffffff)); + + return; + } + } + + targetIndex = writer.InstructionPointer; + delta = targetIndex - branchIndex; + + writer.WriteInstructionAt(branchIndex, encoding | (uint)(delta & 0x3ffffff)); + WriteTailCallConstant(context, ref asm, targetAddress); + } + else + { + // Conditional branch. + + uint branchMask = 0x7ffff; + int branchMax = (int)(branchMask + 1) / 2; + + if (targets.TryGetValue(targetAddress, out targetIndex)) + { + delta = targetIndex - branchIndex; + + if (delta >= -branchMax && delta < branchMax) + { + writer.WriteInstructionAt(branchIndex, encoding | (uint)((delta & branchMask) << 5)); + + return; + } + } + + targetIndex = writer.InstructionPointer; + delta = targetIndex - branchIndex; + + if (delta >= -branchMax && delta < branchMax) + { + writer.WriteInstructionAt(branchIndex, encoding | (uint)((delta & branchMask) << 5)); + WriteTailCallConstant(context, ref asm, targetAddress); + } + else + { + // If the branch target is too far away, we use a regular unconditional branch + // instruction instead which has a much higher range. + // We branch directly to the end of the function, where we put the conditional branch, + // and then branch back to the next instruction or return the branch target depending + // on the branch being taken or not. + + uint branchInst = 0x14000000u | ((uint)delta & 0x3ffffff); + Debug.Assert((int)(branchInst << 6) >> 4 == delta * 4); + + writer.WriteInstructionAt(branchIndex, branchInst); + + int movedBranchIndex = writer.InstructionPointer; + + writer.WriteInstruction(0u); // Placeholder + asm.B((branchIndex + 1 - writer.InstructionPointer) * 4); + + delta = writer.InstructionPointer - movedBranchIndex; + + writer.WriteInstructionAt(movedBranchIndex, encoding | (uint)((delta & branchMask) << 5)); + WriteTailCallConstant(context, ref asm, targetAddress); + } + } + + Debug.Assert(name == InstName.B || name == InstName.Cbnz, $"Unknown branch instruction \"{name}\"."); + } + + private static void RewriteCallInstructionWithTarget(in Context context, uint targetAddress, uint nextAddress, int branchIndex) + { + CodeWriter writer = context.Writer; + Assembler asm = new(writer); + + WriteBranchToCurrentPosition(context, branchIndex); + + asm.Mov(context.RegisterAllocator.RemapGprRegister(RegisterUtils.LrRegister), nextAddress); + + context.StoreToContext(); + InstEmitFlow.WriteCallWithGuestAddress( + writer, + ref asm, + context.RegisterAllocator, + context.TailMerger, + context.WriteEpilogueWithoutContext, + context.FuncTable, + context.DispatchStubPointer, + context.GetReservedStackOffset(), + nextAddress, + InstEmitCommon.Const((int)targetAddress)); + context.LoadFromContext(); + + // Branch back to the next instruction (after the call). + asm.B((branchIndex + 1 - writer.InstructionPointer) * 4); + } + + private static void RewriteIndirectBranchInstructionWithTarget(in Context context, InstName name, uint targetRegister, int branchIndex) + { + CodeWriter writer = context.Writer; + Assembler asm = new(writer); + + WriteBranchToCurrentPosition(context, branchIndex); + + using ScopedRegister target = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + asm.And(target.Operand, context.RegisterAllocator.RemapGprRegister((int)targetRegister), InstEmitCommon.Const(~1)); + + context.StoreToContext(); + + if ((name == InstName.Bx && targetRegister == RegisterUtils.LrRegister) || + name == InstName.Ldm || + name == InstName.Ldmda || + name == InstName.Ldmdb || + name == InstName.Ldmib) + { + // Arm32 does not have a return instruction, instead returns are implemented + // either using BX LR (for leaf functions), or POP { ... PC }. + + asm.Mov(Register(0), target.Operand); + + context.TailMerger.AddUnconditionalReturn(writer, asm); + } + else + { + InstEmitFlow.WriteCallWithGuestAddress( + writer, + ref asm, + context.RegisterAllocator, + context.TailMerger, + context.WriteEpilogueWithoutContext, + context.FuncTable, + context.DispatchStubPointer, + context.GetReservedStackOffset(), + 0u, + target.Operand, + isTail: true); + } + } + + private static void RewriteTableBranchInstructionWithTarget(in Context context, bool halfword, uint rn, uint rm, int branchIndex) + { + CodeWriter writer = context.Writer; + Assembler asm = new(writer); + + WriteBranchToCurrentPosition(context, branchIndex); + + using ScopedRegister target = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + asm.Add( + target.Operand, + context.RegisterAllocator.RemapGprRegister((int)rn), + context.RegisterAllocator.RemapGprRegister((int)rm), + ArmShiftType.Lsl, + halfword ? 1 : 0); + + InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, asm, target.Operand, target.Operand); + + if (halfword) + { + asm.LdrhRiUn(target.Operand, target.Operand, 0); + } + else + { + asm.LdrbRiUn(target.Operand, target.Operand, 0); + } + + asm.Add(target.Operand, context.RegisterAllocator.RemapGprRegister(RegisterUtils.PcRegister), target.Operand, ArmShiftType.Lsl, 1); + + context.StoreToContext(); + + InstEmitFlow.WriteCallWithGuestAddress( + writer, + ref asm, + context.RegisterAllocator, + context.TailMerger, + context.WriteEpilogueWithoutContext, + context.FuncTable, + context.DispatchStubPointer, + context.GetReservedStackOffset(), + 0u, + target.Operand, + isTail: true); + } + + private static void RewriteIndirectCallInstructionWithTarget(in Context context, uint targetRegister, uint nextAddress, int branchIndex) + { + CodeWriter writer = context.Writer; + Assembler asm = new(writer); + + WriteBranchToCurrentPosition(context, branchIndex); + + using ScopedRegister target = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + asm.And(target.Operand, context.RegisterAllocator.RemapGprRegister((int)targetRegister), InstEmitCommon.Const(~1)); + asm.Mov(context.RegisterAllocator.RemapGprRegister(RegisterUtils.LrRegister), nextAddress); + + context.StoreToContext(); + InstEmitFlow.WriteCallWithGuestAddress( + writer, + ref asm, + context.RegisterAllocator, + context.TailMerger, + context.WriteEpilogueWithoutContext, + context.FuncTable, + context.DispatchStubPointer, + context.GetReservedStackOffset(), + nextAddress & ~1u, + target.Operand); + context.LoadFromContext(); + + // Branch back to the next instruction (after the call). + asm.B((branchIndex + 1 - writer.InstructionPointer) * 4); + } + + private static void RewriteHostCall(in Context context, InstName name, BranchType type, uint imm, uint pc, int branchIndex) + { + CodeWriter writer = context.Writer; + Assembler asm = new(writer); + + uint encoding = writer.ReadInstructionAt(branchIndex); + int targetIndex = writer.InstructionPointer; + int delta = targetIndex - branchIndex; + + writer.WriteInstructionAt(branchIndex, encoding | (uint)(delta & 0x3ffffff)); + + switch (type) + { + case BranchType.SyncPoint: + InstEmitSystem.WriteSyncPoint(context.Writer, context.RegisterAllocator, context.TailMerger, context.GetReservedStackOffset()); + break; + case BranchType.SoftwareInterrupt: + context.StoreToContext(); + switch (name) + { + case InstName.Bkpt: + InstEmitSystem.WriteBkpt(context.Writer, context.RegisterAllocator, context.TailMerger, context.GetReservedStackOffset(), pc, imm); + break; + case InstName.Svc: + InstEmitSystem.WriteSvc(context.Writer, context.RegisterAllocator, context.TailMerger, context.GetReservedStackOffset(), pc, imm); + break; + case InstName.Udf: + InstEmitSystem.WriteUdf(context.Writer, context.RegisterAllocator, context.TailMerger, context.GetReservedStackOffset(), pc, imm); + break; + } + context.LoadFromContext(); + break; + case BranchType.ReadCntpct: + InstEmitSystem.WriteReadCntpct(context.Writer, context.RegisterAllocator, context.GetReservedStackOffset(), (int)imm, (int)pc); + break; + default: + Debug.Fail($"Invalid branch type '{type}'"); + break; + } + + // Branch back to the next instruction. + asm.B((branchIndex + 1 - writer.InstructionPointer) * 4); + } + + private static void WriteBranchToCurrentPosition(in Context context, int branchIndex) + { + CodeWriter writer = context.Writer; + + int targetIndex = writer.InstructionPointer; + + if (branchIndex + 1 == targetIndex) + { + writer.RemoveLastInstruction(); + } + else + { + uint encoding = writer.ReadInstructionAt(branchIndex); + int delta = targetIndex - branchIndex; + + writer.WriteInstructionAt(branchIndex, encoding | (uint)(delta & 0x3ffffff)); + } + } + + private static void WriteTailCallConstant(in Context context, ref Assembler asm, uint address) + { + context.StoreToContext(); + InstEmitFlow.WriteCallWithGuestAddress( + context.Writer, + ref asm, + context.RegisterAllocator, + context.TailMerger, + context.WriteEpilogueWithoutContext, + context.FuncTable, + context.DispatchStubPointer, + context.GetReservedStackOffset(), + 0u, + InstEmitCommon.Const((int)address), + isTail: true); + } + + private static Operand Register(int register, OperandType type = OperandType.I64) + { + return new Operand(register, RegisterType.Integer, type); + } + + public static void PrintStats() + { + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmit.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmit.cs new file mode 100644 index 000000000..488919325 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmit.cs @@ -0,0 +1,8502 @@ +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; +using System; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + class InstEmit : IInstEmit + { + public static void AdcIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12 inst = new(encoding); + + InstEmitAlu.AdcI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), inst.S != 0); + } + + public static void AdcIT1(CodeGenContext context, uint encoding) + { + InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitAlu.AdcI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), inst.S != 0); + } + + public static void AdcRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.AdcR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0); + } + + public static void AdcRT1(CodeGenContext context, uint encoding) + { + InstRmb19w3Rdnb16w3 inst = new(encoding); + + InstEmitAlu.AdcR(context, inst.Rdn, inst.Rdn, inst.Rm, 0, 0, !context.InITBlock); + } + + public static void AdcRT2(CodeGenContext context, uint encoding) + { + InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.AdcR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0); + } + + public static void AdcRrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.AdcRr(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Rs, inst.S != 0); + } + + public static void AddIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12 inst = new(encoding); + + InstEmitAlu.AddI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), inst.S != 0); + } + + public static void AddIT1(CodeGenContext context, uint encoding) + { + InstImm3b22w3Rnb19w3Rdb16w3 inst = new(encoding); + + InstEmitAlu.AddI(context, inst.Rd, inst.Rn, inst.Imm3, !context.InITBlock); + } + + public static void AddIT2(CodeGenContext context, uint encoding) + { + InstRdnb24w3Imm8b16w8 inst = new(encoding); + + InstEmitAlu.AddI(context, inst.Rdn, inst.Rdn, inst.Imm8, !context.InITBlock); + } + + public static void AddIT3(CodeGenContext context, uint encoding) + { + InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitAlu.AddI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), inst.S != 0); + } + + public static void AddIT4(CodeGenContext context, uint encoding) + { + InstIb26w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitAlu.AddI(context, inst.Rd, inst.Rn, ImmUtils.CombineImmU12(inst.Imm8, inst.Imm3, inst.I), false); + } + + public static void AddRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.AddR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0); + } + + public static void AddRT1(CodeGenContext context, uint encoding) + { + InstRmb22w3Rnb19w3Rdb16w3 inst = new(encoding); + + InstEmitAlu.AddR(context, inst.Rd, inst.Rn, inst.Rm, 0, 0, !context.InITBlock); + } + + public static void AddRT2(CodeGenContext context, uint encoding) + { + InstDnb23w1Rmb19w4Rdnb16w3 inst = new(encoding); + + uint rdn = (inst.Dn << 3) | inst.Rdn; + + InstEmitAlu.AddR(context, rdn, rdn, inst.Rm, 0, 0, false); + } + + public static void AddRT3(CodeGenContext context, uint encoding) + { + InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.AddR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0); + } + + public static void AddRrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.AddRr(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Rs, inst.S != 0); + } + + public static void AddSpIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rdb12w4Imm12b0w12 inst = new(encoding); + + InstEmitAlu.AddI(context, inst.Rd, RegisterUtils.SpRegister, ImmUtils.ExpandImm(inst.Imm12), inst.S != 0); + } + + public static void AddSpIT1(CodeGenContext context, uint encoding) + { + InstRdb24w3Imm8b16w8 inst = new(encoding); + + InstEmitAlu.AddI(context, inst.Rd, RegisterUtils.SpRegister, inst.Imm8 << 2, false); + } + + public static void AddSpIT2(CodeGenContext context, uint encoding) + { + InstImm7b16w7 inst = new(encoding); + + InstEmitAlu.AddI(context, RegisterUtils.SpRegister, RegisterUtils.SpRegister, inst.Imm7 << 2, false); + } + + public static void AddSpIT3(CodeGenContext context, uint encoding) + { + InstIb26w1Sb20w1Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitAlu.AddI(context, inst.Rd, RegisterUtils.SpRegister, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), inst.S != 0); + } + + public static void AddSpIT4(CodeGenContext context, uint encoding) + { + InstIb26w1Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitAlu.AddI(context, inst.Rd, RegisterUtils.SpRegister, ImmUtils.CombineImmU12(inst.Imm8, inst.Imm3, inst.I), false); + } + + public static void AddSpRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.AddR(context, inst.Rd, RegisterUtils.SpRegister, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0); + } + + public static void AddSpRT1(CodeGenContext context, uint encoding) + { + InstDmb23w1Rdmb16w3 inst = new(encoding); + + uint rdm = inst.Rdm | (inst.Dm << 3); + + InstEmitAlu.AddR(context, rdm, RegisterUtils.SpRegister, rdm, 0, 0, false); + } + + public static void AddSpRT2(CodeGenContext context, uint encoding) + { + InstRmb19w4 inst = new(encoding); + + InstEmitAlu.AddR(context, RegisterUtils.SpRegister, RegisterUtils.SpRegister, inst.Rm, 0, 0, false); + } + + public static void AddSpRT3(CodeGenContext context, uint encoding) + { + InstSb20w1Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.AddR(context, inst.Rd, RegisterUtils.SpRegister, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0); + } + + public static void AdrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb12w4Imm12b0w12 inst = new(encoding); + + InstEmitAlu.Adr(context, inst.Rd, ImmUtils.ExpandImm(inst.Imm12), true); + } + + public static void AdrA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb12w4Imm12b0w12 inst = new(encoding); + + InstEmitAlu.Adr(context, inst.Rd, ImmUtils.ExpandImm(inst.Imm12), false); + } + + public static void AdrT1(CodeGenContext context, uint encoding) + { + InstRdb24w3Imm8b16w8 inst = new(encoding); + + InstEmitAlu.Adr(context, inst.Rd, inst.Imm8 << 2, true); + } + + public static void AdrT2(CodeGenContext context, uint encoding) + { + InstIb26w1Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitAlu.Adr(context, inst.Rd, ImmUtils.CombineImmU12(inst.Imm8, inst.Imm3, inst.I), false); + } + + public static void AdrT3(CodeGenContext context, uint encoding) + { + InstIb26w1Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitAlu.Adr(context, inst.Rd, ImmUtils.CombineImmU12(inst.Imm8, inst.Imm3, inst.I), true); + } + + public static void AesdA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCrypto.Aesd(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void AesdT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCrypto.Aesd(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void AeseA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCrypto.Aese(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void AeseT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCrypto.Aese(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void AesimcA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCrypto.Aesimc(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void AesimcT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCrypto.Aesimc(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void AesmcA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCrypto.Aesmc(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void AesmcT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCrypto.Aesmc(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void AndIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12 inst = new(encoding); + + InstEmitAlu.AndI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), ImmUtils.ExpandedImmRotated(inst.Imm12), inst.S != 0); + } + + public static void AndIT1(CodeGenContext context, uint encoding) + { + InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitAlu.AndI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), ImmUtils.ExpandedImmRotated(inst.Imm8, inst.Imm3, inst.I), inst.S != 0); + } + + public static void AndRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.AndR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0); + } + + public static void AndRT1(CodeGenContext context, uint encoding) + { + InstRmb19w3Rdnb16w3 inst = new(encoding); + + InstEmitAlu.AndR(context, inst.Rdn, inst.Rdn, inst.Rm, 0, 0, !context.InITBlock); + } + + public static void AndRT2(CodeGenContext context, uint encoding) + { + InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.AndR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0); + } + + public static void AndRrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.AndRr(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Rs, inst.S != 0); + } + + public static void BA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Imm24b0w24 inst = new(encoding); + + InstEmitFlow.B(context, ImmUtils.ExtractSImm24Times4(inst.Imm24), (ArmCondition)inst.Cond); + } + + public static void BT1(CodeGenContext context, uint encoding) + { + InstCondb24w4Imm8b16w8 inst = new(encoding); + + InstEmitFlow.B(context, ImmUtils.ExtractT16SImm8Times2(inst.Imm8), (ArmCondition)inst.Cond); + } + + public static void BT2(CodeGenContext context, uint encoding) + { + InstImm11b16w11 inst = new(encoding); + + InstEmitFlow.B(context, ImmUtils.ExtractT16SImm11Times2(inst.Imm11), ArmCondition.Al); + } + + public static void BT3(CodeGenContext context, uint encoding) + { + InstSb26w1Condb22w4Imm6b16w6J1b13w1J2b11w1Imm11b0w11 inst = new(encoding); + + InstEmitFlow.B(context, ImmUtils.CombineSImm20Times2(inst.Imm11, inst.Imm6, inst.J1, inst.J2, inst.S), (ArmCondition)inst.Cond); + } + + public static void BT4(CodeGenContext context, uint encoding) + { + InstSb26w1Imm10b16w10J1b13w1J2b11w1Imm11b0w11 inst = new(encoding); + + InstEmitFlow.B(context, ImmUtils.CombineSImm24Times2(inst.Imm11, inst.Imm10, inst.J1, inst.J2, inst.S), ArmCondition.Al); + } + + public static void BfcA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Msbb16w5Rdb12w4Lsbb7w5 inst = new(encoding); + + InstEmitBit.Bfc(context, inst.Rd, inst.Lsb, inst.Msb); + } + + public static void BfcT1(CodeGenContext context, uint encoding) + { + InstImm3b12w3Rdb8w4Imm2b6w2Msbb0w5 inst = new(encoding); + + InstEmitBit.Bfc(context, inst.Rd, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.Msb); + } + + public static void BfiA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Msbb16w5Rdb12w4Lsbb7w5Rnb0w4 inst = new(encoding); + + InstEmitBit.Bfi(context, inst.Rd, inst.Rn, inst.Lsb, inst.Msb); + } + + public static void BfiT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Imm3b12w3Rdb8w4Imm2b6w2Msbb0w5 inst = new(encoding); + + InstEmitBit.Bfi(context, inst.Rd, inst.Rn, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.Msb); + } + + public static void BicIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12 inst = new(encoding); + + InstEmitAlu.BicI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), ImmUtils.ExpandedImmRotated(inst.Imm12), inst.S != 0); + } + + public static void BicIT1(CodeGenContext context, uint encoding) + { + InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitAlu.BicI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), ImmUtils.ExpandedImmRotated(inst.Imm8, inst.Imm3, inst.I), inst.S != 0); + } + + public static void BicRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.BicR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0); + } + + public static void BicRT1(CodeGenContext context, uint encoding) + { + InstRmb19w3Rdnb16w3 inst = new(encoding); + + InstEmitAlu.BicR(context, inst.Rdn, inst.Rdn, inst.Rm, 0, 0, !context.InITBlock); + } + + public static void BicRT2(CodeGenContext context, uint encoding) + { + InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.BicR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0); + } + + public static void BicRrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.BicRr(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Rs, inst.S != 0); + } + + public static void BkptA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Imm12b8w12Imm4b0w4 inst = new(encoding); + + InstEmitSystem.Bkpt(context, ImmUtils.CombineImmU16(inst.Imm12, inst.Imm4)); + } + + public static void BkptT1(CodeGenContext context, uint encoding) + { + InstImm8b16w8 inst = new(encoding); + + InstEmitSystem.Bkpt(context, inst.Imm8); + } + + public static void BlxRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rmb0w4 inst = new(encoding); + + InstEmitFlow.Blx(context, inst.Rm, false); + } + + public static void BlxRT1(CodeGenContext context, uint encoding) + { + InstRmb19w4 inst = new(encoding); + + InstEmitFlow.Blx(context, inst.Rm, true); + } + + public static void BlIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Imm24b0w24 inst = new(encoding); + + InstEmitFlow.Bl(context, ImmUtils.ExtractSImm24Times4(inst.Imm24), false, false); + } + + public static void BlIA2(CodeGenContext context, uint encoding) + { + InstHb24w1Imm24b0w24 inst = new(encoding); + + InstEmitFlow.Bl(context, ImmUtils.ExtractSImm24Times4(inst.Imm24) | ((int)inst.H << 1), false, true); + } + + public static void BlIT1(CodeGenContext context, uint encoding) + { + InstSb26w1Imm10b16w10J1b13w1J2b11w1Imm11b0w11 inst = new(encoding); + + InstEmitFlow.Bl(context, ImmUtils.CombineSImm24Times2(inst.Imm11, inst.Imm10, inst.J1, inst.J2, inst.S), true, true); + } + + public static void BlIT2(CodeGenContext context, uint encoding) + { + InstSb26w1Imm10hb16w10J1b13w1J2b11w1Imm10lb1w10Hb0w1 inst = new(encoding); + + InstEmitFlow.Bl(context, ImmUtils.CombineSImm24Times4(inst.Imm10l, inst.Imm10h, inst.J1, inst.J2, inst.S), true, false); + } + + public static void BxA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rmb0w4 inst = new(encoding); + + InstEmitFlow.Bx(context, inst.Rm); + } + + public static void BxT1(CodeGenContext context, uint encoding) + { + InstRmb19w4 inst = new(encoding); + + InstEmitFlow.Bx(context, inst.Rm); + } + + public static void BxjA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rmb0w4 inst = new(encoding); + + InstEmitFlow.Bx(context, inst.Rm); + } + + public static void BxjT1(CodeGenContext context, uint encoding) + { + InstRmb16w4 inst = new(encoding); + + InstEmitFlow.Bx(context, inst.Rm); + } + + public static void CbnzT1(CodeGenContext context, uint encoding) + { + InstOpb27w1Ib25w1Imm5b19w5Rnb16w3 inst = new(encoding); + + InstEmitFlow.Cbnz(context, inst.Rn, (int)((inst.Imm5 << 1) | (inst.I << 6)), inst.Op != 0); + } + + public static void ClrbhbA1(CodeGenContext context, uint encoding) + { + _ = new InstCondb28w4(encoding); + + throw new NotImplementedException(); + } + + public static void ClrbhbT1(CodeGenContext context, uint encoding) + { + throw new NotImplementedException(); + } + + public static void ClrexA1(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Clrex(); + } + + public static void ClrexT1(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Clrex(); + } + + public static void ClzA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitBit.Clz(context, inst.Rd, inst.Rm); + } + + public static void ClzT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitBit.Clz(context, inst.Rd, inst.Rm); + } + + public static void CmnIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Imm12b0w12 inst = new(encoding); + + InstEmitAlu.CmnI(context, inst.Rn, ImmUtils.ExpandImm(inst.Imm12)); + } + + public static void CmnIT1(CodeGenContext context, uint encoding) + { + InstIb26w1Rnb16w4Imm3b12w3Imm8b0w8 inst = new(encoding); + + InstEmitAlu.CmnI(context, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I)); + } + + public static void CmnRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.CmnR(context, inst.Rn, inst.Rm, inst.Stype, inst.Imm5); + } + + public static void CmnRT1(CodeGenContext context, uint encoding) + { + InstRmb19w3Rnb16w3 inst = new(encoding); + + InstEmitAlu.CmnR(context, inst.Rn, inst.Rm, 0, 0); + } + + public static void CmnRT2(CodeGenContext context, uint encoding) + { + InstRnb16w4Imm3b12w3Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.CmnR(context, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3)); + } + + public static void CmnRrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.CmnRr(context, inst.Rn, inst.Rm, inst.Stype, inst.Rs); + } + + public static void CmpIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Imm12b0w12 inst = new(encoding); + + InstEmitAlu.CmpI(context, inst.Rn, ImmUtils.ExpandImm(inst.Imm12)); + } + + public static void CmpIT1(CodeGenContext context, uint encoding) + { + InstRnb24w3Imm8b16w8 inst = new(encoding); + + InstEmitAlu.CmpI(context, inst.Rn, inst.Imm8); + } + + public static void CmpIT2(CodeGenContext context, uint encoding) + { + InstIb26w1Rnb16w4Imm3b12w3Imm8b0w8 inst = new(encoding); + + InstEmitAlu.CmpI(context, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I)); + } + + public static void CmpRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.CmpR(context, inst.Rn, inst.Rm, inst.Stype, inst.Imm5); + } + + public static void CmpRT1(CodeGenContext context, uint encoding) + { + InstRmb19w3Rnb16w3 inst = new(encoding); + + InstEmitAlu.CmpR(context, inst.Rn, inst.Rm, 0, 0); + } + + public static void CmpRT2(CodeGenContext context, uint encoding) + { + InstNb23w1Rmb19w4Rnb16w3 inst = new(encoding); + + InstEmitAlu.CmpR(context, inst.Rn | (inst.N << 3), inst.Rm, 0, 0); + } + + public static void CmpRT3(CodeGenContext context, uint encoding) + { + InstRnb16w4Imm3b12w3Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.CmpR(context, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3)); + } + + public static void CmpRrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.CmpRr(context, inst.Rn, inst.Rm, inst.Stype, inst.Rs); + } + + public static void CpsA1(CodeGenContext context, uint encoding) + { + InstImodb18w2Mb17w1Ab8w1Ib7w1Fb6w1Modeb0w5 inst = new(encoding); + + InstEmitSystem.Cps(context, inst.Imod, inst.M, inst.A, inst.I, inst.F, inst.Mode); + } + + public static void CpsT1(CodeGenContext context, uint encoding) + { + InstImb20w1Ab18w1Ib17w1Fb16w1 inst = new(encoding); + + InstEmitSystem.Cps(context, inst.Im, 0, inst.A, inst.I, inst.F, 0); + } + + public static void CpsT2(CodeGenContext context, uint encoding) + { + InstImodb9w2Mb8w1Ab7w1Ib6w1Fb5w1Modeb0w5 inst = new(encoding); + + InstEmitSystem.Cps(context, inst.Imod, inst.M, inst.A, inst.I, inst.F, inst.Mode); + } + + public static void Crc32A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Szb21w2Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitCrc32.Crc32(context, inst.Rd, inst.Rn, inst.Rm, inst.Sz); + } + + public static void Crc32T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Szb4w2Rmb0w4 inst = new(encoding); + + InstEmitCrc32.Crc32(context, inst.Rd, inst.Rn, inst.Rm, inst.Sz); + } + + public static void Crc32cA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Szb21w2Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitCrc32.Crc32c(context, inst.Rd, inst.Rn, inst.Rm, inst.Sz); + } + + public static void Crc32cT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Szb4w2Rmb0w4 inst = new(encoding); + + InstEmitCrc32.Crc32c(context, inst.Rd, inst.Rn, inst.Rm, inst.Sz); + } + + public static void CsdbA1(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Csdb(); + } + + public static void CsdbT1(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Csdb(); + } + + public static void DbgA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Optionb0w4 inst = new(encoding); + + InstEmitSystem.Dbg(context, inst.Option); + } + + public static void DbgT1(CodeGenContext context, uint encoding) + { + InstOptionb0w4 inst = new(encoding); + + InstEmitSystem.Dbg(context, inst.Option); + } + + public static void Dcps1T1(CodeGenContext context, uint encoding) + { + InstEmitSystem.PrivilegedInstruction(context, encoding); + } + + public static void Dcps2T1(CodeGenContext context, uint encoding) + { + InstEmitSystem.PrivilegedInstruction(context, encoding); + } + + public static void Dcps3T1(CodeGenContext context, uint encoding) + { + InstEmitSystem.PrivilegedInstruction(context, encoding); + } + + public static void DmbA1(CodeGenContext context, uint encoding) + { + InstOptionb0w4 inst = new(encoding); + + context.Arm64Assembler.Dmb(inst.Option); + } + + public static void DmbT1(CodeGenContext context, uint encoding) + { + InstOptionb0w4 inst = new(encoding); + + context.Arm64Assembler.Dmb(inst.Option); + } + + public static void DsbA1(CodeGenContext context, uint encoding) + { + InstOptionb0w4 inst = new(encoding); + + context.Arm64Assembler.Dsb(inst.Option); + } + + public static void DsbT1(CodeGenContext context, uint encoding) + { + InstOptionb0w4 inst = new(encoding); + + context.Arm64Assembler.Dsb(inst.Option); + } + + public static void EorIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12 inst = new(encoding); + + InstEmitAlu.EorI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), ImmUtils.ExpandedImmRotated(inst.Imm12), inst.S != 0); + } + + public static void EorIT1(CodeGenContext context, uint encoding) + { + InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitAlu.EorI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), ImmUtils.ExpandedImmRotated(inst.Imm8, inst.Imm3, inst.I), inst.S != 0); + } + + public static void EorRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.EorR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0); + } + + public static void EorRT1(CodeGenContext context, uint encoding) + { + InstRmb19w3Rdnb16w3 inst = new(encoding); + + InstEmitAlu.EorR(context, inst.Rdn, inst.Rdn, inst.Rm, 0, 0, !context.InITBlock); + } + + public static void EorRT2(CodeGenContext context, uint encoding) + { + InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.EorR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0); + } + + public static void EorRrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.EorRr(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Rs, inst.S != 0); + } + + public static void EretA1(CodeGenContext context, uint encoding) + { + InstEmitSystem.PrivilegedInstruction(context, encoding); + } + + public static void EretT1(CodeGenContext context, uint encoding) + { + InstEmitSystem.PrivilegedInstruction(context, encoding); + } + + public static void EsbA1(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Esb(); + } + + public static void EsbT1(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Esb(); + } + + public static void FldmxA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7 inst = new(encoding); + + InstEmitNeonMemory.Vldm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Imm871, inst.U != 0, inst.W != 0, singleRegs: false); + } + + public static void FldmxT1(CodeGenContext context, uint encoding) + { + InstPb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7 inst = new(encoding); + + InstEmitNeonMemory.Vldm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Imm871, inst.U != 0, inst.W != 0, singleRegs: false); + } + + public static void FstmxA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7 inst = new(encoding); + + InstEmitNeonMemory.Vstm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Imm871, inst.U != 0, inst.W != 0, singleRegs: false); + } + + public static void FstmxT1(CodeGenContext context, uint encoding) + { + InstPb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7 inst = new(encoding); + + InstEmitNeonMemory.Vstm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Imm871, inst.U != 0, inst.W != 0, singleRegs: false); + } + + public static void HltA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Imm12b8w12Imm4b0w4 inst = new(encoding); + + InstEmitSystem.Hlt(context, ImmUtils.CombineImmU16(inst.Imm12, inst.Imm4)); + } + + public static void HltT1(CodeGenContext context, uint encoding) + { + InstImm6b16w6 inst = new(encoding); + + InstEmitSystem.Hlt(context, inst.Imm6); + } + + public static void HvcA1(CodeGenContext context, uint encoding) + { + InstEmitSystem.PrivilegedInstruction(context, encoding); + } + + public static void HvcT1(CodeGenContext context, uint encoding) + { + InstEmitSystem.PrivilegedInstruction(context, encoding); + } + + public static void IsbA1(CodeGenContext context, uint encoding) + { + InstOptionb0w4 inst = new(encoding); + + context.Arm64Assembler.Isb(inst.Option); + } + + public static void IsbT1(CodeGenContext context, uint encoding) + { + InstOptionb0w4 inst = new(encoding); + + context.Arm64Assembler.Isb(inst.Option); + } + + public static void ItT1(CodeGenContext context, uint encoding) + { + InstFirstcondb20w4Maskb16w4 inst = new(encoding); + + InstEmitFlow.It(context, inst.Firstcond, inst.Mask); + } + + public static void LdaA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Lda(context, inst.Rt, inst.Rn); + } + + public static void LdaT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Lda(context, inst.Rt, inst.Rn); + } + + public static void LdabA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Ldab(context, inst.Rt, inst.Rn); + } + + public static void LdabT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Ldab(context, inst.Rt, inst.Rn); + } + + public static void LdaexA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Ldaex(context, inst.Rt, inst.Rn); + } + + public static void LdaexT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Ldaex(context, inst.Rt, inst.Rn); + } + + public static void LdaexbA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Ldaexb(context, inst.Rt, inst.Rn); + } + + public static void LdaexbT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Ldaexb(context, inst.Rt, inst.Rn); + } + + public static void LdaexdA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Ldaexd(context, inst.Rt, RegisterUtils.GetRt2(inst.Rt), inst.Rn); + } + + public static void LdaexdT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Rt2b8w4 inst = new(encoding); + + InstEmitMemory.Ldaexd(context, inst.Rt, inst.Rt2, inst.Rn); + } + + public static void LdaexhA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Ldaexh(context, inst.Rt, inst.Rn); + } + + public static void LdaexhT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Ldaexh(context, inst.Rt, inst.Rn); + } + + public static void LdahA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Ldah(context, inst.Rt, inst.Rn); + } + + public static void LdahT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Ldah(context, inst.Rt, inst.Rn); + } + + public static void LdcIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Imm8b0w8 inst = new(encoding); + + InstEmitMemory.LdcI(context, inst.Rn, (int)inst.Imm8 << 2, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdcIT1(CodeGenContext context, uint encoding) + { + InstPb24w1Ub23w1Wb21w1Rnb16w4Imm8b0w8 inst = new(encoding); + + InstEmitMemory.LdcI(context, inst.Rn, (int)inst.Imm8 << 2, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdcLA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Imm8b0w8 inst = new(encoding); + + InstEmitMemory.LdcL(context, inst.Imm8 << 2, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdcLT1(CodeGenContext context, uint encoding) + { + InstPb24w1Ub23w1Wb21w1Imm8b0w8 inst = new(encoding); + + InstEmitMemory.LdcL(context, inst.Imm8 << 2, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdmA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Wb21w1Rnb16w4RegisterListb0w16 inst = new(encoding); + + InstEmitMemory.Ldm(context, inst.Rn, inst.RegisterList, inst.W != 0); + } + + public static void LdmT1(CodeGenContext context, uint encoding) + { + InstRnb24w3RegisterListb16w8 inst = new(encoding); + + InstEmitMemory.Ldm(context, inst.Rn, inst.RegisterList, false); + } + + public static void LdmT2(CodeGenContext context, uint encoding) + { + InstWb21w1Rnb16w4Pb15w1Mb14w1RegisterListb0w14 inst = new(encoding); + + InstEmitMemory.Ldm(context, inst.Rn, ImmUtils.CombineRegisterList(inst.RegisterList, inst.M, inst.P), inst.W != 0); + } + + public static void LdmdaA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Wb21w1Rnb16w4RegisterListb0w16 inst = new(encoding); + + InstEmitMemory.Ldmda(context, inst.Rn, inst.RegisterList, inst.W != 0); + } + + public static void LdmdbA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Wb21w1Rnb16w4RegisterListb0w16 inst = new(encoding); + + InstEmitMemory.Ldmdb(context, inst.Rn, inst.RegisterList, inst.W != 0); + } + + public static void LdmdbT1(CodeGenContext context, uint encoding) + { + InstWb21w1Rnb16w4Pb15w1Mb14w1RegisterListb0w14 inst = new(encoding); + + InstEmitMemory.Ldmdb(context, inst.Rn, ImmUtils.CombineRegisterList(inst.RegisterList, inst.M, inst.P), inst.W != 0); + } + + public static void LdmibA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Wb21w1Rnb16w4RegisterListb0w16 inst = new(encoding); + + InstEmitMemory.Ldmib(context, inst.Rn, inst.RegisterList, inst.W != 0); + } + + public static void LdmEA1(CodeGenContext context, uint encoding) + { + InstEmitSystem.PrivilegedInstruction(context, encoding); + } + + public static void LdmUA1(CodeGenContext context, uint encoding) + { + InstEmitSystem.PrivilegedInstruction(context, encoding); + } + + public static void LdrbtA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.LdrbtI(context, inst.Rt, inst.Rn, (int)inst.Imm12, postIndex: true, inst.U != 0); + } + + public static void LdrbtA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitMemory.LdrbtR(context, inst.Rt, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, postIndex: true, inst.U != 0); + } + + public static void LdrbtT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm8b0w8 inst = new(encoding); + + InstEmitMemory.LdrbtI(context, inst.Rt, inst.Rn, (int)inst.Imm8, postIndex: false, true); + } + + public static void LdrbIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.LdrbI(context, inst.Rt, inst.Rn, (int)inst.Imm12, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrbIT1(CodeGenContext context, uint encoding) + { + InstImm5b22w5Rnb19w3Rtb16w3 inst = new(encoding); + + InstEmitMemory.LdrbI(context, inst.Rt, inst.Rn, (int)inst.Imm5, true, true, false); + } + + public static void LdrbIT2(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.LdrbI(context, inst.Rt, inst.Rn, (int)inst.Imm12, true, true, false); + } + + public static void LdrbIT3(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Pb10w1Ub9w1Wb8w1Imm8b0w8 inst = new(encoding); + + InstEmitMemory.LdrbI(context, inst.Rt, inst.Rn, (int)inst.Imm8, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrbLA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.LdrbL(context, inst.Rt, inst.Imm12, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrbLT1(CodeGenContext context, uint encoding) + { + InstUb23w1Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.LdrbL(context, inst.Rt, inst.Imm12, true, inst.U != 0, false); + } + + public static void LdrbRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitMemory.LdrbR(context, inst.Rt, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrbRT1(CodeGenContext context, uint encoding) + { + InstRmb22w3Rnb19w3Rtb16w3 inst = new(encoding); + + InstEmitMemory.LdrbR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, true, true, false); + } + + public static void LdrbRT2(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm2b4w2Rmb0w4 inst = new(encoding); + + InstEmitMemory.LdrbR(context, inst.Rt, inst.Rn, inst.Rm, 0, inst.Imm2, true, true, false); + } + + public static void LdrdIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding); + + InstEmitMemory.LdrdI(context, inst.Rt, RegisterUtils.GetRt2(inst.Rt), inst.Rn, ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrdIT1(CodeGenContext context, uint encoding) + { + InstPb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rt2b8w4Imm8b0w8 inst = new(encoding); + + InstEmitMemory.LdrdI(context, inst.Rt, inst.Rt2, inst.Rn, inst.Imm8 << 2, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrdLA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Ub23w1Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding); + + InstEmitMemory.LdrdL(context, inst.Rt, RegisterUtils.GetRt2(inst.Rt), ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), true, inst.U != 0, false); + } + + public static void LdrdLT1(CodeGenContext context, uint encoding) + { + InstPb24w1Ub23w1Wb21w1Rtb12w4Rt2b8w4Imm8b0w8 inst = new(encoding); + + InstEmitMemory.LdrdL(context, inst.Rt, inst.Rt2, inst.Imm8, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrdRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rmb0w4 inst = new(encoding); + + InstEmitMemory.LdrdR(context, inst.Rt, RegisterUtils.GetRt2(inst.Rt), inst.Rn, inst.Rm, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrexA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Ldrex(context, inst.Rt, inst.Rn); + } + + public static void LdrexT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm8b0w8 inst = new(encoding); + + InstEmitMemory.Ldrex(context, inst.Rt, inst.Rn); + } + + public static void LdrexbA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Ldrexb(context, inst.Rt, inst.Rn); + } + + public static void LdrexbT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Ldrexb(context, inst.Rt, inst.Rn); + } + + public static void LdrexdA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Ldrexd(context, inst.Rt, RegisterUtils.GetRt2(inst.Rt), inst.Rn); + } + + public static void LdrexdT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Rt2b8w4 inst = new(encoding); + + InstEmitMemory.Ldrexd(context, inst.Rt, inst.Rt2, inst.Rn); + } + + public static void LdrexhA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Ldrexh(context, inst.Rt, inst.Rn); + } + + public static void LdrexhT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Ldrexh(context, inst.Rt, inst.Rn); + } + + public static void LdrhtA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding); + + InstEmitMemory.LdrhtI(context, inst.Rt, inst.Rn, (int)ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), postIndex: true, inst.U != 0); + } + + public static void LdrhtA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Ub23w1Rnb16w4Rtb12w4Rmb0w4 inst = new(encoding); + + InstEmitMemory.LdrhtR(context, inst.Rt, inst.Rn, inst.Rm, postIndex: true, inst.U != 0); + } + + public static void LdrhtT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm8b0w8 inst = new(encoding); + + InstEmitMemory.LdrhtI(context, inst.Rt, inst.Rn, (int)inst.Imm8, postIndex: false, true); + } + + public static void LdrhIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding); + + InstEmitMemory.LdrhI(context, inst.Rt, inst.Rn, (int)ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrhIT1(CodeGenContext context, uint encoding) + { + InstImm5b22w5Rnb19w3Rtb16w3 inst = new(encoding); + + InstEmitMemory.LdrhI(context, inst.Rt, inst.Rn, (int)inst.Imm5 << 1, true, true, false); + } + + public static void LdrhIT2(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.LdrhI(context, inst.Rt, inst.Rn, (int)inst.Imm12, true, true, false); + } + + public static void LdrhIT3(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Pb10w1Ub9w1Wb8w1Imm8b0w8 inst = new(encoding); + + InstEmitMemory.LdrhI(context, inst.Rt, inst.Rn, (int)inst.Imm8, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrhLA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding); + + InstEmitMemory.LdrhL(context, inst.Rt, ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrhLT1(CodeGenContext context, uint encoding) + { + InstUb23w1Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.LdrhL(context, inst.Rt, inst.Imm12, true, inst.U != 0, false); + } + + public static void LdrhRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rmb0w4 inst = new(encoding); + + InstEmitMemory.LdrhR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrhRT1(CodeGenContext context, uint encoding) + { + InstRmb22w3Rnb19w3Rtb16w3 inst = new(encoding); + + InstEmitMemory.LdrhR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, true, true, false); + } + + public static void LdrhRT2(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm2b4w2Rmb0w4 inst = new(encoding); + + InstEmitMemory.LdrhR(context, inst.Rt, inst.Rn, inst.Rm, 0, inst.Imm2, true, true, false); + } + + public static void LdrsbtA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding); + + InstEmitMemory.LdrsbtI(context, inst.Rt, inst.Rn, (int)ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), postIndex: true, inst.U != 0); + } + + public static void LdrsbtA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Ub23w1Rnb16w4Rtb12w4Rmb0w4 inst = new(encoding); + + InstEmitMemory.LdrsbtR(context, inst.Rt, inst.Rn, inst.Rm, postIndex: true, inst.U != 0); + } + + public static void LdrsbtT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm8b0w8 inst = new(encoding); + + InstEmitMemory.LdrsbtI(context, inst.Rt, inst.Rn, (int)inst.Imm8, postIndex: false, true); + } + + public static void LdrsbIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding); + + InstEmitMemory.LdrsbI(context, inst.Rt, inst.Rn, (int)ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrsbIT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.LdrsbI(context, inst.Rt, inst.Rn, (int)inst.Imm12, true, true, false); + } + + public static void LdrsbIT2(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Pb10w1Ub9w1Wb8w1Imm8b0w8 inst = new(encoding); + + InstEmitMemory.LdrsbI(context, inst.Rt, inst.Rn, (int)inst.Imm8, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrsbLA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding); + + InstEmitMemory.LdrsbL(context, inst.Rt, ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrsbLT1(CodeGenContext context, uint encoding) + { + InstUb23w1Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.LdrsbL(context, inst.Rt, inst.Imm12, true, inst.U != 0, false); + } + + public static void LdrsbRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rmb0w4 inst = new(encoding); + + InstEmitMemory.LdrsbR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrsbRT1(CodeGenContext context, uint encoding) + { + InstRmb22w3Rnb19w3Rtb16w3 inst = new(encoding); + + InstEmitMemory.LdrsbR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, true, true, false); + } + + public static void LdrsbRT2(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm2b4w2Rmb0w4 inst = new(encoding); + + InstEmitMemory.LdrsbR(context, inst.Rt, inst.Rn, inst.Rm, 0, inst.Imm2, true, true, false); + } + + public static void LdrshtA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding); + + InstEmitMemory.LdrshtI(context, inst.Rt, inst.Rn, (int)ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), postIndex: true, inst.U != 0); + } + + public static void LdrshtA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Ub23w1Rnb16w4Rtb12w4Rmb0w4 inst = new(encoding); + + InstEmitMemory.LdrshtR(context, inst.Rt, inst.Rn, inst.Rm, postIndex: true, inst.U != 0); + } + + public static void LdrshtT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm8b0w8 inst = new(encoding); + + InstEmitMemory.LdrshtI(context, inst.Rt, inst.Rn, (int)inst.Imm8, postIndex: false, true); + } + + public static void LdrshIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding); + + InstEmitMemory.LdrshI(context, inst.Rt, inst.Rn, (int)ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrshIT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.LdrshI(context, inst.Rt, inst.Rn, (int)inst.Imm12, true, true, false); + } + + public static void LdrshIT2(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Pb10w1Ub9w1Wb8w1Imm8b0w8 inst = new(encoding); + + InstEmitMemory.LdrshI(context, inst.Rt, inst.Rn, (int)inst.Imm8, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrshLA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding); + + InstEmitMemory.LdrshL(context, inst.Rt, ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrshLT1(CodeGenContext context, uint encoding) + { + InstUb23w1Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.LdrshL(context, inst.Rt, inst.Imm12, true, inst.U != 0, false); + } + + public static void LdrshRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rmb0w4 inst = new(encoding); + + InstEmitMemory.LdrshR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrshRT1(CodeGenContext context, uint encoding) + { + InstRmb22w3Rnb19w3Rtb16w3 inst = new(encoding); + + InstEmitMemory.LdrshR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, true, true, false); + } + + public static void LdrshRT2(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm2b4w2Rmb0w4 inst = new(encoding); + + InstEmitMemory.LdrshR(context, inst.Rt, inst.Rn, inst.Rm, 0, inst.Imm2, true, true, false); + } + + public static void LdrtA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.LdrtI(context, inst.Rt, inst.Rn, (int)inst.Imm12, postIndex: true, inst.U != 0); + } + + public static void LdrtA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitMemory.LdrtR(context, inst.Rt, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, postIndex: true, inst.U != 0); + } + + public static void LdrtT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm8b0w8 inst = new(encoding); + + InstEmitMemory.LdrtI(context, inst.Rt, inst.Rn, (int)inst.Imm8, postIndex: false, true); + } + + public static void LdrIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.LdrI(context, inst.Rt, inst.Rn, (int)inst.Imm12, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrIT1(CodeGenContext context, uint encoding) + { + InstImm5b22w5Rnb19w3Rtb16w3 inst = new(encoding); + + InstEmitMemory.LdrI(context, inst.Rt, inst.Rn, (int)inst.Imm5 << 2, true, true, false); + } + + public static void LdrIT2(CodeGenContext context, uint encoding) + { + InstRtb24w3Imm8b16w8 inst = new(encoding); + + InstEmitMemory.LdrI(context, inst.Rt, RegisterUtils.SpRegister, (int)inst.Imm8 << 2, true, true, false); + } + + public static void LdrIT3(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.LdrI(context, inst.Rt, inst.Rn, (int)inst.Imm12, true, true, false); + } + + public static void LdrIT4(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Pb10w1Ub9w1Wb8w1Imm8b0w8 inst = new(encoding); + + InstEmitMemory.LdrI(context, inst.Rt, inst.Rn, (int)inst.Imm8, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrLA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.LdrL(context, inst.Rt, inst.Imm12, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrLT1(CodeGenContext context, uint encoding) + { + InstRtb24w3Imm8b16w8 inst = new(encoding); + + InstEmitMemory.LdrL(context, inst.Rt, inst.Imm8 << 2, true, true, false); + } + + public static void LdrLT2(CodeGenContext context, uint encoding) + { + InstUb23w1Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.LdrL(context, inst.Rt, inst.Imm12, true, inst.U != 0, false); + } + + public static void LdrRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitMemory.LdrR(context, inst.Rt, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void LdrRT1(CodeGenContext context, uint encoding) + { + InstRmb22w3Rnb19w3Rtb16w3 inst = new(encoding); + + InstEmitMemory.LdrR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, true, true, false); + } + + public static void LdrRT2(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm2b4w2Rmb0w4 inst = new(encoding); + + InstEmitMemory.LdrR(context, inst.Rt, inst.Rn, inst.Rm, 0, inst.Imm2, true, true, false); + } + + public static void McrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Opc1b21w3Crnb16w4Rtb12w4Coproc0b8w1Opc2b5w3Crmb0w4 inst = new(encoding); + + InstEmitSystem.Mcr(context, encoding, inst.Coproc0 | 0xe, inst.Opc1, inst.Rt, inst.Crn, inst.Crm, inst.Opc2); + } + + public static void McrT1(CodeGenContext context, uint encoding) + { + InstOpc1b21w3Crnb16w4Rtb12w4Coproc0b8w1Opc2b5w3Crmb0w4 inst = new(encoding); + + InstEmitSystem.Mcr(context, encoding, inst.Coproc0 | 0xe, inst.Opc1, inst.Rt, inst.Crn, inst.Crm, inst.Opc2); + } + + public static void McrrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rt2b16w4Rtb12w4Coproc0b8w1Opc1b4w4Crmb0w4 inst = new(encoding); + + InstEmitSystem.Mcrr(context, encoding, inst.Coproc0 | 0xe, inst.Opc1, inst.Rt, inst.Crm); + } + + public static void McrrT1(CodeGenContext context, uint encoding) + { + InstRt2b16w4Rtb12w4Coproc0b8w1Opc1b4w4Crmb0w4 inst = new(encoding); + + InstEmitSystem.Mcrr(context, encoding, inst.Coproc0 | 0xe, inst.Opc1, inst.Rt, inst.Crm); + } + + public static void MlaA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rdb16w4Rab12w4Rmb8w4Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Mla(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra); + } + + public static void MlaT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rab12w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Mla(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra); + } + + public static void MlsA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb16w4Rab12w4Rmb8w4Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Mls(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra); + } + + public static void MlsT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rab12w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Mls(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra); + } + + public static void MovtA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Imm4b16w4Rdb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMove.Movt(context, inst.Rd, ImmUtils.CombineImmU16(inst.Imm12, inst.Imm4)); + } + + public static void MovtT1(CodeGenContext context, uint encoding) + { + InstIb26w1Imm4b16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitMove.Movt(context, inst.Rd, ImmUtils.CombineImmU16(inst.Imm8, inst.Imm3, inst.I, inst.Imm4)); + } + + public static void MovIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rdb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMove.MovI(context, inst.Rd, ImmUtils.ExpandImm(inst.Imm12), ImmUtils.ExpandedImmRotated(inst.Imm12), inst.S != 0); + } + + public static void MovIA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Imm4b16w4Rdb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMove.MovI(context, inst.Rd, ImmUtils.CombineImmU16(inst.Imm12, inst.Imm4), false, false); + } + + public static void MovIT1(CodeGenContext context, uint encoding) + { + InstRdb24w3Imm8b16w8 inst = new(encoding); + + InstEmitMove.MovI(context, inst.Rd, inst.Imm8, false, !context.InITBlock); + } + + public static void MovIT2(CodeGenContext context, uint encoding) + { + InstIb26w1Sb20w1Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitMove.MovI(context, inst.Rd, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), ImmUtils.ExpandedImmRotated(inst.Imm8, inst.Imm3, inst.I), inst.S != 0); + } + + public static void MovIT3(CodeGenContext context, uint encoding) + { + InstIb26w1Imm4b16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitMove.MovI(context, inst.Rd, ImmUtils.CombineImmU16(inst.Imm8, inst.Imm3, inst.I, inst.Imm4), false, false); + } + + public static void MovRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitMove.MovR(context, inst.Cond, inst.Rd, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0); + } + + public static void MovRT1(CodeGenContext context, uint encoding) + { + InstDb23w1Rmb19w4Rdb16w3 inst = new(encoding); + + InstEmitMove.MovR(context, inst.Rd | (inst.D << 3), inst.Rm, 0, 0, false); + } + + public static void MovRT2(CodeGenContext context, uint encoding) + { + InstOpb27w2Imm5b22w5Rmb19w3Rdb16w3 inst = new(encoding); + + InstEmitMove.MovR(context, inst.Rd, inst.Rm, inst.Op, inst.Imm5, !context.InITBlock); + } + + public static void MovRT3(CodeGenContext context, uint encoding) + { + InstSb20w1Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding); + + InstEmitMove.MovR(context, inst.Rd, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0); + } + + public static void MovRrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitMove.MovRr(context, inst.Rd, inst.Rm, inst.Stype, inst.Rs, inst.S != 0); + } + + public static void MovRrT1(CodeGenContext context, uint encoding) + { + InstRsb19w3Rdmb16w3 inst = new(encoding); + + InstEmitMove.MovRr(context, inst.Rdm, inst.Rdm, ((encoding >> 7) & 2) | ((encoding >> 6) & 1), inst.Rs, !context.InITBlock); + } + + public static void MovRrT2(CodeGenContext context, uint encoding) + { + InstStypeb21w2Sb20w1Rmb16w4Rdb8w4Rsb0w4 inst = new(encoding); + + InstEmitMove.MovRr(context, inst.Rd, inst.Rm, inst.Stype, inst.Rs, inst.S != 0); + } + + public static void MrcA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Opc1b21w3Crnb16w4Rtb12w4Coproc0b8w1Opc2b5w3Crmb0w4 inst = new(encoding); + + InstEmitSystem.Mrc(context, encoding, inst.Coproc0 | 0xe, inst.Opc1, inst.Rt, inst.Crn, inst.Crm, inst.Opc2); + } + + public static void MrcT1(CodeGenContext context, uint encoding) + { + InstOpc1b21w3Crnb16w4Rtb12w4Coproc0b8w1Opc2b5w3Crmb0w4 inst = new(encoding); + + InstEmitSystem.Mrc(context, encoding, inst.Coproc0 | 0xe, inst.Opc1, inst.Rt, inst.Crn, inst.Crm, inst.Opc2); + } + + public static void MrrcA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rt2b16w4Rtb12w4Coproc0b8w1Opc1b4w4Crmb0w4 inst = new(encoding); + + InstEmitSystem.Mrrc(context, encoding, inst.Coproc0 | 0xe, inst.Opc1, inst.Rt, inst.Rt2, inst.Crm); + } + + public static void MrrcT1(CodeGenContext context, uint encoding) + { + InstRt2b16w4Rtb12w4Coproc0b8w1Opc1b4w4Crmb0w4 inst = new(encoding); + + InstEmitSystem.Mrrc(context, encoding, inst.Coproc0 | 0xe, inst.Opc1, inst.Rt, inst.Rt2, inst.Crm); + } + + public static void MrsA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rb22w1Rdb12w4 inst = new(encoding); + + InstEmitSystem.Mrs(context, inst.Rd, inst.R != 0); + } + + public static void MrsT1(CodeGenContext context, uint encoding) + { + InstRb20w1Rdb8w4 inst = new(encoding); + + InstEmitSystem.Mrs(context, inst.Rd, inst.R != 0); + } + + public static void MrsBrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rb22w1M1b16w4Rdb12w4Mb8w1 inst = new(encoding); + + InstEmitSystem.MrsBr(context, inst.Rd, inst.M1 | (inst.M << 4), inst.R != 0); + } + + public static void MrsBrT1(CodeGenContext context, uint encoding) + { + InstRb20w1M1b16w4Rdb8w4Mb4w1 inst = new(encoding); + + InstEmitSystem.MrsBr(context, inst.Rd, inst.M1 | (inst.M << 4), inst.R != 0); + } + + public static void MsrBrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rb22w1M1b16w4Mb8w1Rnb0w4 inst = new(encoding); + + InstEmitSystem.MsrBr(context, inst.Rn, inst.M1 | (inst.M << 4), inst.R != 0); + } + + public static void MsrBrT1(CodeGenContext context, uint encoding) + { + InstRb20w1Rnb16w4M1b8w4Mb4w1 inst = new(encoding); + + InstEmitSystem.MsrBr(context, inst.Rn, inst.M1 | (inst.M << 4), inst.R != 0); + } + + public static void MsrIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rb22w1Maskb16w4Imm12b0w12 inst = new(encoding); + + InstEmitSystem.MsrI(context, inst.Imm12, inst.Mask, inst.R != 0); + } + + public static void MsrRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rb22w1Maskb16w4Rnb0w4 inst = new(encoding); + + InstEmitSystem.MsrR(context, inst.Rn, inst.Mask, inst.R != 0); + } + + public static void MsrRT1(CodeGenContext context, uint encoding) + { + InstRb20w1Rnb16w4Maskb8w4 inst = new(encoding); + + InstEmitSystem.MsrR(context, inst.Rn, inst.Mask, inst.R != 0); + } + + public static void MulA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rdb16w4Rmb8w4Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Mul(context, inst.Rd, inst.Rn, inst.Rm, inst.S != 0); + } + + public static void MulT1(CodeGenContext context, uint encoding) + { + InstRnb19w3Rdmb16w3 inst = new(encoding); + + InstEmitMultiply.Mul(context, inst.Rdm, inst.Rn, inst.Rdm, !context.InITBlock); + } + + public static void MulT2(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Mul(context, inst.Rd, inst.Rn, inst.Rm, false); + } + + public static void MvnIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rdb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMove.MvnI(context, inst.Rd, ImmUtils.ExpandImm(inst.Imm12), ImmUtils.ExpandedImmRotated(inst.Imm12), inst.S != 0); + } + + public static void MvnIT1(CodeGenContext context, uint encoding) + { + InstIb26w1Sb20w1Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitMove.MvnI(context, inst.Rd, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), ImmUtils.ExpandedImmRotated(inst.Imm8, inst.Imm3, inst.I), inst.S != 0); + } + + public static void MvnRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitMove.MvnR(context, inst.Rd, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0); + } + + public static void MvnRT1(CodeGenContext context, uint encoding) + { + InstRmb19w3Rdb16w3 inst = new(encoding); + + InstEmitMove.MvnR(context, inst.Rd, inst.Rm, 0, 0, !context.InITBlock); + } + + public static void MvnRT2(CodeGenContext context, uint encoding) + { + InstSb20w1Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding); + + InstEmitMove.MvnR(context, inst.Rd, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0); + } + + public static void MvnRrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitMove.MvnRr(context, inst.Rd, inst.Rm, inst.Stype, inst.Rs, inst.S != 0); + } + + public static void NopA1(CodeGenContext context, uint encoding) + { + } + + public static void NopT1(CodeGenContext context, uint encoding) + { + } + + public static void NopT2(CodeGenContext context, uint encoding) + { + } + + public static void OrnIT1(CodeGenContext context, uint encoding) + { + InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitAlu.OrnI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), ImmUtils.ExpandedImmRotated(inst.Imm8, inst.Imm3, inst.I), inst.S != 0); + } + + public static void OrnRT1(CodeGenContext context, uint encoding) + { + InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.OrnR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0); + } + + public static void OrrIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12 inst = new(encoding); + + InstEmitAlu.OrrI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), ImmUtils.ExpandedImmRotated(inst.Imm12), inst.S != 0); + } + + public static void OrrIT1(CodeGenContext context, uint encoding) + { + InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitAlu.OrrI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), ImmUtils.ExpandedImmRotated(inst.Imm8, inst.Imm3, inst.I), inst.S != 0); + } + + public static void OrrRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.OrrR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0); + } + + public static void OrrRT1(CodeGenContext context, uint encoding) + { + InstRmb19w3Rdnb16w3 inst = new(encoding); + + InstEmitAlu.OrrR(context, inst.Rdn, inst.Rdn, inst.Rm, 0, 0, !context.InITBlock); + } + + public static void OrrRT2(CodeGenContext context, uint encoding) + { + InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.OrrR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0); + } + + public static void OrrRrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.OrrRr(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Rs, inst.S != 0); + } + + public static void PkhA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Imm5b7w5Tbb6w1Rmb0w4 inst = new(encoding); + + InstEmitMove.Pkh(context, inst.Rd, inst.Rn, inst.Rm, inst.Tb != 0, inst.Imm5); + } + + public static void PkhT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Imm3b12w3Rdb8w4Imm2b6w2Tbb5w1Rmb0w4 inst = new(encoding); + + InstEmitMove.Pkh(context, inst.Rd, inst.Rn, inst.Rm, inst.Tb != 0, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3)); + } + + public static void PldIA1(CodeGenContext context, uint encoding) + { + InstUb23w1Rb22w1Rnb16w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.PldI(context, inst.Rn, inst.Imm12, inst.U != 0, inst.R != 0); + } + + public static void PldIT1(CodeGenContext context, uint encoding) + { + InstWb21w1Rnb16w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.PldI(context, inst.Rn, inst.Imm12, true, inst.W == 0); + } + + public static void PldIT2(CodeGenContext context, uint encoding) + { + InstWb21w1Rnb16w4Imm8b0w8 inst = new(encoding); + + InstEmitMemory.PldI(context, inst.Rn, inst.Imm8, false, inst.W == 0); + } + + public static void PldLA1(CodeGenContext context, uint encoding) + { + InstUb23w1Imm12b0w12 inst = new(encoding); + + InstEmitMemory.PldL(context, inst.Imm12, inst.U != 0); + } + + public static void PldLT1(CodeGenContext context, uint encoding) + { + InstUb23w1Imm12b0w12 inst = new(encoding); + + InstEmitMemory.PldL(context, inst.Imm12, inst.U != 0); + } + + public static void PldRA1(CodeGenContext context, uint encoding) + { + InstUb23w1Rb22w1Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitMemory.PldR(context, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.U != 0, inst.R != 0); + } + + public static void PldRT1(CodeGenContext context, uint encoding) + { + InstWb21w1Rnb16w4Imm2b4w2Rmb0w4 inst = new(encoding); + + InstEmitMemory.PldR(context, inst.Rn, inst.Rm, 0, inst.Imm2, true, inst.W == 0); + } + + public static void PliIA1(CodeGenContext context, uint encoding) + { + InstUb23w1Rnb16w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.PliI(context, inst.Rn, inst.Imm12, inst.U != 0); + } + + public static void PliIT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.PliI(context, inst.Rn, inst.Imm12, true); + } + + public static void PliIT2(CodeGenContext context, uint encoding) + { + InstRnb16w4Imm8b0w8 inst = new(encoding); + + InstEmitMemory.PliI(context, inst.Rn, inst.Imm8, false); + } + + public static void PliIT3(CodeGenContext context, uint encoding) + { + InstUb23w1Imm12b0w12 inst = new(encoding); + + InstEmitMemory.PliL(context, inst.Imm12, inst.U != 0); + } + + public static void PliRA1(CodeGenContext context, uint encoding) + { + InstUb23w1Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitMemory.PliR(context, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.U != 0); + } + + public static void PliRT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Imm2b4w2Rmb0w4 inst = new(encoding); + + InstEmitMemory.PliR(context, inst.Rn, inst.Rm, 0, inst.Imm2, true); + } + + public static void PopT1(CodeGenContext context, uint encoding) + { + InstPb24w1RegisterListb16w8 inst = new(encoding); + + InstEmitMemory.Ldm(context, RegisterUtils.SpRegister, inst.RegisterList | (inst.P << RegisterUtils.PcRegister), true); + } + + public static void PssbbA1(CodeGenContext context, uint encoding) + { + throw new NotImplementedException(); + } + + public static void PssbbT1(CodeGenContext context, uint encoding) + { + throw new NotImplementedException(); + } + + public static void PushT1(CodeGenContext context, uint encoding) + { + InstMb24w1RegisterListb16w8 inst = new(encoding); + + InstEmitMemory.Stmdb(context, RegisterUtils.SpRegister, inst.RegisterList | (inst.M << RegisterUtils.LrRegister), true); + } + + public static void QaddA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Qadd(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void QaddT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Qadd(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Qadd16A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Qadd16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Qadd16T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Qadd16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Qadd8A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Qadd8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Qadd8T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Qadd8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void QasxA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Qasx(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void QasxT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Qasx(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void QdaddA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Qdadd(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void QdaddT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Qdadd(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void QdsubA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Qdsub(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void QdsubT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Qdsub(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void QsaxA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Qsax(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void QsaxT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Qsax(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void QsubA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Qsub(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void QsubT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Qsub(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Qsub16A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Qsub16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Qsub16T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Qsub16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Qsub8A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Qsub8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Qsub8T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Qsub8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void RbitA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitBit.Rbit(context, inst.Rd, inst.Rm); + } + + public static void RbitT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitBit.Rbit(context, inst.Rd, inst.Rm); + } + + public static void RevA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitBit.Rev(context, inst.Rd, inst.Rm); + } + + public static void RevT1(CodeGenContext context, uint encoding) + { + InstRmb19w3Rdb16w3 inst = new(encoding); + + InstEmitBit.Rev(context, inst.Rd, inst.Rm); + } + + public static void RevT2(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitBit.Rev(context, inst.Rd, inst.Rm); + } + + public static void Rev16A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitBit.Rev16(context, inst.Rd, inst.Rm); + } + + public static void Rev16T1(CodeGenContext context, uint encoding) + { + InstRmb19w3Rdb16w3 inst = new(encoding); + + InstEmitBit.Rev16(context, inst.Rd, inst.Rm); + } + + public static void Rev16T2(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitBit.Rev16(context, inst.Rd, inst.Rm); + } + + public static void RevshA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitBit.Revsh(context, inst.Rd, inst.Rm); + } + + public static void RevshT1(CodeGenContext context, uint encoding) + { + InstRmb19w3Rdb16w3 inst = new(encoding); + + InstEmitBit.Revsh(context, inst.Rd, inst.Rm); + } + + public static void RevshT2(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitBit.Revsh(context, inst.Rd, inst.Rm); + } + + public static void RfeA1(CodeGenContext context, uint encoding) + { + InstEmitSystem.PrivilegedInstruction(context, encoding); + } + + public static void RfeT1(CodeGenContext context, uint encoding) + { + InstEmitSystem.PrivilegedInstruction(context, encoding); + } + + public static void RfeT2(CodeGenContext context, uint encoding) + { + InstEmitSystem.PrivilegedInstruction(context, encoding); + } + + public static void RsbIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12 inst = new(encoding); + + InstEmitAlu.RsbI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), inst.S != 0); + } + + public static void RsbIT1(CodeGenContext context, uint encoding) + { + InstRnb19w3Rdb16w3 inst = new(encoding); + + InstEmitAlu.RsbI(context, inst.Rd, inst.Rn, 0, !context.InITBlock); + } + + public static void RsbIT2(CodeGenContext context, uint encoding) + { + InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitAlu.RsbI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), inst.S != 0); + } + + public static void RsbRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.RsbR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0); + } + + public static void RsbRT1(CodeGenContext context, uint encoding) + { + InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.RsbR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0); + } + + public static void RsbRrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.RsbRr(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Rs, inst.S != 0); + } + + public static void RscIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12 inst = new(encoding); + + InstEmitAlu.RscI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), inst.S != 0); + } + + public static void RscRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.RscR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0); + } + + public static void RscRrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.RscRr(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Rs, inst.S != 0); + } + + public static void Sadd16A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Sadd16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Sadd16T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Sadd16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Sadd8A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Sadd8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Sadd8T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Sadd8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void SasxA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Sasx(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void SasxT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Sasx(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void SbA1(CodeGenContext context, uint encoding) + { + throw new NotImplementedException(); + } + + public static void SbT1(CodeGenContext context, uint encoding) + { + throw new NotImplementedException(); + } + + public static void SbcIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12 inst = new(encoding); + + InstEmitAlu.SbcI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), inst.S != 0); + } + + public static void SbcIT1(CodeGenContext context, uint encoding) + { + InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitAlu.SbcI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), inst.S != 0); + } + + public static void SbcRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.SbcR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0); + } + + public static void SbcRT1(CodeGenContext context, uint encoding) + { + InstRmb19w3Rdnb16w3 inst = new(encoding); + + InstEmitAlu.SbcR(context, inst.Rdn, inst.Rdn, inst.Rm, 0, 0, !context.InITBlock); + } + + public static void SbcRT2(CodeGenContext context, uint encoding) + { + InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.SbcR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0); + } + + public static void SbcRrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.SbcRr(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Rs, inst.S != 0); + } + + public static void SbfxA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Widthm1b16w5Rdb12w4Lsbb7w5Rnb0w4 inst = new(encoding); + + InstEmitBit.Sbfx(context, inst.Rd, inst.Rn, inst.Lsb, inst.Widthm1); + } + + public static void SbfxT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Imm3b12w3Rdb8w4Imm2b6w2Widthm1b0w5 inst = new(encoding); + + InstEmitBit.Sbfx(context, inst.Rd, inst.Rn, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.Widthm1); + } + + public static void SdivA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb16w4Rmb8w4Rnb0w4 inst = new(encoding); + + InstEmitDivide.Sdiv(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void SdivT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitDivide.Sdiv(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void SelA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Sel(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void SelT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Sel(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void SetendA1(CodeGenContext context, uint encoding) + { + InstEb9w1 inst = new(encoding); + + InstEmitSystem.Setend(context, inst.E != 0); + } + + public static void SetendT1(CodeGenContext context, uint encoding) + { + InstEb19w1 inst = new(encoding); + + InstEmitSystem.Setend(context, inst.E != 0); + } + + public static void SetpanA1(CodeGenContext context, uint encoding) + { + _ = new InstImm1b9w1(encoding); + + throw new NotImplementedException(); + } + + public static void SetpanT1(CodeGenContext context, uint encoding) + { + _ = new InstImm1b19w1(encoding); + + throw new NotImplementedException(); + } + + public static void SevA1(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Sev(); + } + + public static void SevT1(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Sev(); + } + + public static void SevT2(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Sev(); + } + + public static void SevlA1(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Sevl(); + } + + public static void SevlT1(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Sevl(); + } + + public static void SevlT2(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Sevl(); + } + + public static void Sha1cA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonHash.Sha1c(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void Sha1cT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonHash.Sha1c(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void Sha1hA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonHash.Sha1h(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void Sha1hT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonHash.Sha1h(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void Sha1mA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonHash.Sha1m(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void Sha1mT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonHash.Sha1m(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void Sha1pA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonHash.Sha1p(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void Sha1pT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonHash.Sha1p(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void Sha1su0A1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonHash.Sha1su0(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void Sha1su0T1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonHash.Sha1su0(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void Sha1su1A1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonHash.Sha1su1(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void Sha1su1T1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonHash.Sha1su1(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void Sha256hA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonHash.Sha256h(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void Sha256hT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonHash.Sha256h(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void Sha256h2A1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonHash.Sha256h2(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void Sha256h2T1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonHash.Sha256h2(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void Sha256su0A1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonHash.Sha256su0(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void Sha256su0T1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonHash.Sha256su0(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void Sha256su1A1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonHash.Sha256su1(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void Sha256su1T1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonHash.Sha256su1(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void Shadd16A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Shadd16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Shadd16T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Shadd16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Shadd8A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Shadd8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Shadd8T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Shadd8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void ShasxA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Shasx(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void ShasxT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Shasx(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void ShsaxA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Shsax(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void ShsaxT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Shsax(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Shsub16A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Shsub16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Shsub16T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Shsub16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Shsub8A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Shsub8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Shsub8T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Shsub8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void SmcA1(CodeGenContext context, uint encoding) + { + InstEmitSystem.PrivilegedInstruction(context, encoding); + } + + public static void SmcT1(CodeGenContext context, uint encoding) + { + InstEmitSystem.PrivilegedInstruction(context, encoding); + } + + public static void SmlabbA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb16w4Rab12w4Rmb8w4Mb6w1Nb5w1Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Smlabb(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.N != 0, inst.M != 0); + } + + public static void SmlabbT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rab12w4Rdb8w4Nb5w1Mb4w1Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Smlabb(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.N != 0, inst.M != 0); + } + + public static void SmladA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb16w4Rab12w4Rmb8w4Mb5w1Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Smlad(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.M != 0); + } + + public static void SmladT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rab12w4Rdb8w4Mb4w1Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Smlad(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.M != 0); + } + + public static void SmlalA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rdhib16w4Rdlob12w4Rmb8w4Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Smlal(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, inst.S != 0); + } + + public static void SmlalT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdlob12w4Rdhib8w4Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Smlal(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, false); + } + + public static void SmlalbbA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdhib16w4Rdlob12w4Rmb8w4Mb6w1Nb5w1Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Smlalbb(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, inst.N != 0, inst.M != 0); + } + + public static void SmlalbbT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdlob12w4Rdhib8w4Nb5w1Mb4w1Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Smlalbb(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, inst.N != 0, inst.M != 0); + } + + public static void SmlaldA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdhib16w4Rdlob12w4Rmb8w4Mb5w1Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Smlald(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, inst.M != 0); + } + + public static void SmlaldT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdlob12w4Rdhib8w4Mb4w1Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Smlald(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, inst.M != 0); + } + + public static void SmlawbA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb16w4Rab12w4Rmb8w4Mb6w1Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Smlawb(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.M != 0); + } + + public static void SmlawbT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rab12w4Rdb8w4Mb4w1Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Smlawb(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.M != 0); + } + + public static void SmlsdA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb16w4Rab12w4Rmb8w4Mb5w1Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Smlsd(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.M != 0); + } + + public static void SmlsdT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rab12w4Rdb8w4Mb4w1Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Smlsd(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.M != 0); + } + + public static void SmlsldA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdhib16w4Rdlob12w4Rmb8w4Mb5w1Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Smlsld(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, inst.M != 0); + } + + public static void SmlsldT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdlob12w4Rdhib8w4Mb4w1Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Smlsld(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, inst.M != 0); + } + + public static void SmmlaA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb16w4Rab12w4Rmb8w4Rb5w1Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Smmla(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.R != 0); + } + + public static void SmmlaT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rab12w4Rdb8w4Rb4w1Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Smmla(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.R != 0); + } + + public static void SmmlsA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb16w4Rab12w4Rmb8w4Rb5w1Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Smmls(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.R != 0); + } + + public static void SmmlsT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rab12w4Rdb8w4Rb4w1Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Smmls(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.R != 0); + } + + public static void SmmulA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb16w4Rmb8w4Rb5w1Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Smmul(context, inst.Rd, inst.Rn, inst.Rm, inst.R != 0); + } + + public static void SmmulT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rb4w1Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Smmul(context, inst.Rd, inst.Rn, inst.Rm, inst.R != 0); + } + + public static void SmuadA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb16w4Rmb8w4Mb5w1Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Smuad(context, inst.Rd, inst.Rn, inst.Rm, inst.M != 0); + } + + public static void SmuadT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Mb4w1Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Smuad(context, inst.Rd, inst.Rn, inst.Rm, inst.M != 0); + } + + public static void SmulbbA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb16w4Rmb8w4Mb6w1Nb5w1Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Smulbb(context, inst.Rd, inst.Rn, inst.Rm, inst.N != 0, inst.M != 0); + } + + public static void SmulbbT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Nb5w1Mb4w1Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Smulbb(context, inst.Rd, inst.Rn, inst.Rm, inst.N != 0, inst.M != 0); + } + + public static void SmullA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rdhib16w4Rdlob12w4Rmb8w4Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Smull(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, inst.S != 0); + } + + public static void SmullT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdlob12w4Rdhib8w4Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Smull(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, false); + } + + public static void SmulwbA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb16w4Rmb8w4Mb6w1Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Smulwb(context, inst.Rd, inst.Rn, inst.Rm, inst.M != 0); + } + + public static void SmulwbT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Mb4w1Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Smulwb(context, inst.Rd, inst.Rn, inst.Rm, inst.M != 0); + } + + public static void SmusdA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb16w4Rmb8w4Mb5w1Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Smusd(context, inst.Rd, inst.Rn, inst.Rm, inst.M != 0); + } + + public static void SmusdT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Mb4w1Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Smusd(context, inst.Rd, inst.Rn, inst.Rm, inst.M != 0); + } + + public static void SrsA1(CodeGenContext context, uint encoding) + { + InstEmitSystem.PrivilegedInstruction(context, encoding); + } + + public static void SrsT1(CodeGenContext context, uint encoding) + { + InstEmitSystem.PrivilegedInstruction(context, encoding); + } + + public static void SrsT2(CodeGenContext context, uint encoding) + { + InstEmitSystem.PrivilegedInstruction(context, encoding); + } + + public static void SsatA1(CodeGenContext context, uint encoding) + { + InstCondb28w4SatImmb16w5Rdb12w4Imm5b7w5Shb6w1Rnb0w4 inst = new(encoding); + + InstEmitSaturate.Ssat(context, inst.Rd, inst.SatImm, inst.Rn, inst.Sh != 0, inst.Imm5); + } + + public static void SsatT1(CodeGenContext context, uint encoding) + { + InstShb21w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2SatImmb0w5 inst = new(encoding); + + InstEmitSaturate.Ssat(context, inst.Rd, inst.SatImm, inst.Rn, inst.Sh != 0, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3)); + } + + public static void Ssat16A1(CodeGenContext context, uint encoding) + { + InstCondb28w4SatImmb16w4Rdb12w4Rnb0w4 inst = new(encoding); + + InstEmitSaturate.Ssat16(context, inst.Rd, inst.SatImm, inst.Rn); + } + + public static void Ssat16T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4SatImmb0w4 inst = new(encoding); + + InstEmitSaturate.Ssat16(context, inst.Rd, inst.SatImm, inst.Rn); + } + + public static void SsaxA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Ssax(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void SsaxT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Ssax(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void SsbbA1(CodeGenContext context, uint encoding) + { + throw new NotImplementedException(); + } + + public static void SsbbT1(CodeGenContext context, uint encoding) + { + throw new NotImplementedException(); + } + + public static void Ssub16A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Ssub16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Ssub16T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Ssub16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Ssub8A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Ssub8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Ssub8T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Ssub8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void StcA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Imm8b0w8 inst = new(encoding); + + InstEmitMemory.Stc(context, inst.Rn, (int)inst.Imm8 << 2, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void StcT1(CodeGenContext context, uint encoding) + { + InstPb24w1Ub23w1Wb21w1Rnb16w4Imm8b0w8 inst = new(encoding); + + InstEmitMemory.Stc(context, inst.Rn, (int)inst.Imm8 << 2, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void StlA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rtb0w4 inst = new(encoding); + + InstEmitMemory.Stl(context, inst.Rt, inst.Rn); + } + + public static void StlT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Stl(context, inst.Rt, inst.Rn); + } + + public static void StlbA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rtb0w4 inst = new(encoding); + + InstEmitMemory.Stlb(context, inst.Rt, inst.Rn); + } + + public static void StlbT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Stlb(context, inst.Rt, inst.Rn); + } + + public static void StlexA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rtb0w4 inst = new(encoding); + + InstEmitMemory.Stlex(context, inst.Rd, inst.Rt, inst.Rn); + } + + public static void StlexT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Rdb0w4 inst = new(encoding); + + InstEmitMemory.Stlex(context, inst.Rd, inst.Rt, inst.Rn); + } + + public static void StlexbA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rtb0w4 inst = new(encoding); + + InstEmitMemory.Stlexb(context, inst.Rd, inst.Rt, inst.Rn); + } + + public static void StlexbT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Rdb0w4 inst = new(encoding); + + InstEmitMemory.Stlexb(context, inst.Rd, inst.Rt, inst.Rn); + } + + public static void StlexdA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rtb0w4 inst = new(encoding); + + InstEmitMemory.Stlexd(context, inst.Rd, inst.Rt, RegisterUtils.GetRt2(inst.Rt), inst.Rn); + } + + public static void StlexdT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Rt2b8w4Rdb0w4 inst = new(encoding); + + InstEmitMemory.Stlexd(context, inst.Rd, inst.Rt, inst.Rt2, inst.Rn); + } + + public static void StlexhA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rtb0w4 inst = new(encoding); + + InstEmitMemory.Stlexh(context, inst.Rd, inst.Rt, inst.Rn); + } + + public static void StlexhT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Rdb0w4 inst = new(encoding); + + InstEmitMemory.Stlexh(context, inst.Rd, inst.Rt, inst.Rn); + } + + public static void StlhA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rtb0w4 inst = new(encoding); + + InstEmitMemory.Stlh(context, inst.Rt, inst.Rn); + } + + public static void StlhT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4 inst = new(encoding); + + InstEmitMemory.Stlh(context, inst.Rt, inst.Rn); + } + + public static void StmA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Wb21w1Rnb16w4RegisterListb0w16 inst = new(encoding); + + InstEmitMemory.Stm(context, inst.Rn, inst.RegisterList, inst.W != 0); + } + + public static void StmT1(CodeGenContext context, uint encoding) + { + InstRnb24w3RegisterListb16w8 inst = new(encoding); + + InstEmitMemory.Stm(context, inst.Rn, inst.RegisterList, false); + } + + public static void StmT2(CodeGenContext context, uint encoding) + { + InstWb21w1Rnb16w4Mb14w1RegisterListb0w14 inst = new(encoding); + + InstEmitMemory.Stm(context, inst.Rn, ImmUtils.CombineRegisterList(inst.RegisterList, inst.M), inst.W != 0); + } + + public static void StmdaA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Wb21w1Rnb16w4RegisterListb0w16 inst = new(encoding); + + InstEmitMemory.Stmda(context, inst.Rn, inst.RegisterList, inst.W != 0); + } + + public static void StmdbA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Wb21w1Rnb16w4RegisterListb0w16 inst = new(encoding); + + InstEmitMemory.Stmdb(context, inst.Rn, inst.RegisterList, inst.W != 0); + } + + public static void StmdbT1(CodeGenContext context, uint encoding) + { + InstWb21w1Rnb16w4Mb14w1RegisterListb0w14 inst = new(encoding); + + InstEmitMemory.Stmdb(context, inst.Rn, ImmUtils.CombineRegisterList(inst.RegisterList, inst.M), inst.W != 0); + } + + public static void StmibA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Wb21w1Rnb16w4RegisterListb0w16 inst = new(encoding); + + InstEmitMemory.Stmib(context, inst.Rn, inst.RegisterList, inst.W != 0); + } + + public static void StmUA1(CodeGenContext context, uint encoding) + { + InstEmitSystem.PrivilegedInstruction(context, encoding); + } + + public static void StrbtA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.StrbtI(context, inst.Rt, inst.Rn, (int)inst.Imm12, postIndex: true, inst.U != 0); + } + + public static void StrbtA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitMemory.StrbtR(context, inst.Rt, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, postIndex: true, inst.U != 0); + } + + public static void StrbtT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm8b0w8 inst = new(encoding); + + InstEmitMemory.StrbtI(context, inst.Rt, inst.Rn, (int)inst.Imm8, postIndex: false, true); + } + + public static void StrbIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.StrbI(context, inst.Rt, inst.Rn, (int)inst.Imm12, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void StrbIT1(CodeGenContext context, uint encoding) + { + InstImm5b22w5Rnb19w3Rtb16w3 inst = new(encoding); + + InstEmitMemory.StrbI(context, inst.Rt, inst.Rn, (int)inst.Imm5, true, true, false); + } + + public static void StrbIT2(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.StrbI(context, inst.Rt, inst.Rn, (int)inst.Imm12, true, true, false); + } + + public static void StrbIT3(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Pb10w1Ub9w1Wb8w1Imm8b0w8 inst = new(encoding); + + InstEmitMemory.StrbI(context, inst.Rt, inst.Rn, (int)inst.Imm8, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void StrbRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitMemory.StrbR(context, inst.Rt, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void StrbRT1(CodeGenContext context, uint encoding) + { + InstRmb22w3Rnb19w3Rtb16w3 inst = new(encoding); + + InstEmitMemory.StrbR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, true, true, false); + } + + public static void StrbRT2(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm2b4w2Rmb0w4 inst = new(encoding); + + InstEmitMemory.StrbR(context, inst.Rt, inst.Rn, inst.Rm, 0, inst.Imm2, true, true, false); + } + + public static void StrdIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding); + + InstEmitMemory.StrdI(context, inst.Rt, RegisterUtils.GetRt2(inst.Rt), inst.Rn, ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void StrdIT1(CodeGenContext context, uint encoding) + { + InstPb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rt2b8w4Imm8b0w8 inst = new(encoding); + + InstEmitMemory.StrdI(context, inst.Rt, inst.Rt2, inst.Rn, inst.Imm8 << 2, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void StrdRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rmb0w4 inst = new(encoding); + + InstEmitMemory.StrdR(context, inst.Rt, RegisterUtils.GetRt2(inst.Rt), inst.Rn, inst.Rm, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void StrexA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rtb0w4 inst = new(encoding); + + InstEmitMemory.Strex(context, inst.Rd, inst.Rt, inst.Rn); + } + + public static void StrexT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitMemory.Strex(context, inst.Rd, inst.Rt, inst.Rn); + } + + public static void StrexbA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rtb0w4 inst = new(encoding); + + InstEmitMemory.Strexb(context, inst.Rd, inst.Rt, inst.Rn); + } + + public static void StrexbT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Rdb0w4 inst = new(encoding); + + InstEmitMemory.Strexb(context, inst.Rd, inst.Rt, inst.Rn); + } + + public static void StrexdA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rtb0w4 inst = new(encoding); + + InstEmitMemory.Strexd(context, inst.Rd, inst.Rt, RegisterUtils.GetRt2(inst.Rt), inst.Rn); + } + + public static void StrexdT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Rt2b8w4Rdb0w4 inst = new(encoding); + + InstEmitMemory.Strexd(context, inst.Rd, inst.Rt, inst.Rt2, inst.Rn); + } + + public static void StrexhA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rtb0w4 inst = new(encoding); + + InstEmitMemory.Strexh(context, inst.Rd, inst.Rt, inst.Rn); + } + + public static void StrexhT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Rdb0w4 inst = new(encoding); + + InstEmitMemory.Strexh(context, inst.Rd, inst.Rt, inst.Rn); + } + + public static void StrhtA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding); + + InstEmitMemory.StrhtI(context, inst.Rt, inst.Rn, (int)ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), postIndex: true, inst.U != 0); + } + + public static void StrhtA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Ub23w1Rnb16w4Rtb12w4Rmb0w4 inst = new(encoding); + + InstEmitMemory.StrhtR(context, inst.Rt, inst.Rn, inst.Rm, postIndex: true, inst.U != 0); + } + + public static void StrhtT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm8b0w8 inst = new(encoding); + + InstEmitMemory.StrhtI(context, inst.Rt, inst.Rn, (int)inst.Imm8, postIndex: false, true); + } + + public static void StrhIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding); + + InstEmitMemory.StrhI(context, inst.Rt, inst.Rn, (int)ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void StrhIT1(CodeGenContext context, uint encoding) + { + InstImm5b22w5Rnb19w3Rtb16w3 inst = new(encoding); + + InstEmitMemory.StrhI(context, inst.Rt, inst.Rn, (int)inst.Imm5 << 1, true, true, false); + } + + public static void StrhIT2(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.StrhI(context, inst.Rt, inst.Rn, (int)inst.Imm12, true, true, false); + } + + public static void StrhIT3(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Pb10w1Ub9w1Wb8w1Imm8b0w8 inst = new(encoding); + + InstEmitMemory.StrhI(context, inst.Rt, inst.Rn, (int)inst.Imm8, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void StrhRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rmb0w4 inst = new(encoding); + + InstEmitMemory.StrhR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void StrhRT1(CodeGenContext context, uint encoding) + { + InstRmb22w3Rnb19w3Rtb16w3 inst = new(encoding); + + InstEmitMemory.StrhR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, true, true, false); + } + + public static void StrhRT2(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm2b4w2Rmb0w4 inst = new(encoding); + + InstEmitMemory.StrhR(context, inst.Rt, inst.Rn, inst.Rm, 0, inst.Imm2, true, true, false); + } + + public static void StrtA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.StrtI(context, inst.Rt, inst.Rn, (int)inst.Imm12, postIndex: true, inst.U != 0); + } + + public static void StrtA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitMemory.StrtR(context, inst.Rt, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, postIndex: true, inst.U != 0); + } + + public static void StrtT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm8b0w8 inst = new(encoding); + + InstEmitMemory.StrtI(context, inst.Rt, inst.Rn, (int)inst.Imm8, postIndex: false, true); + } + + public static void StrIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.StrI(context, inst.Rt, inst.Rn, (int)inst.Imm12, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void StrIT1(CodeGenContext context, uint encoding) + { + InstImm5b22w5Rnb19w3Rtb16w3 inst = new(encoding); + + InstEmitMemory.StrI(context, inst.Rt, inst.Rn, (int)inst.Imm5 << 2, true, true, false); + } + + public static void StrIT2(CodeGenContext context, uint encoding) + { + InstRtb24w3Imm8b16w8 inst = new(encoding); + + InstEmitMemory.StrI(context, inst.Rt, RegisterUtils.SpRegister, (int)inst.Imm8 << 2, true, true, false); + } + + public static void StrIT3(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm12b0w12 inst = new(encoding); + + InstEmitMemory.StrI(context, inst.Rt, inst.Rn, (int)inst.Imm12, true, true, false); + } + + public static void StrIT4(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Pb10w1Ub9w1Wb8w1Imm8b0w8 inst = new(encoding); + + InstEmitMemory.StrI(context, inst.Rt, inst.Rn, (int)inst.Imm8, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void StrRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitMemory.StrR(context, inst.Rt, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.P != 0, inst.U != 0, inst.W != 0); + } + + public static void StrRT1(CodeGenContext context, uint encoding) + { + InstRmb22w3Rnb19w3Rtb16w3 inst = new(encoding); + + InstEmitMemory.StrR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, true, true, false); + } + + public static void StrRT2(CodeGenContext context, uint encoding) + { + InstRnb16w4Rtb12w4Imm2b4w2Rmb0w4 inst = new(encoding); + + InstEmitMemory.StrR(context, inst.Rt, inst.Rn, inst.Rm, 0, inst.Imm2, true, true, false); + } + + public static void SubIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12 inst = new(encoding); + + InstEmitAlu.SubI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), inst.S != 0); + } + + public static void SubIT1(CodeGenContext context, uint encoding) + { + InstImm3b22w3Rnb19w3Rdb16w3 inst = new(encoding); + + InstEmitAlu.SubI(context, inst.Rd, inst.Rn, inst.Imm3, !context.InITBlock); + } + + public static void SubIT2(CodeGenContext context, uint encoding) + { + InstRdnb24w3Imm8b16w8 inst = new(encoding); + + InstEmitAlu.SubI(context, inst.Rdn, inst.Rdn, inst.Imm8, !context.InITBlock); + } + + public static void SubIT3(CodeGenContext context, uint encoding) + { + InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitAlu.SubI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), inst.S != 0); + } + + public static void SubIT4(CodeGenContext context, uint encoding) + { + InstIb26w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitAlu.SubI(context, inst.Rd, inst.Rn, ImmUtils.CombineImmU12(inst.Imm8, inst.Imm3, inst.I), false); + } + + public static void SubIT5(CodeGenContext context, uint encoding) + { + InstRnb16w4Imm8b0w8 inst = new(encoding); + + InstEmitAlu.SubI(context, RegisterUtils.PcRegister, inst.Rn, inst.Imm8, true); + } + + public static void SubRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.SubR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0); + } + + public static void SubRT1(CodeGenContext context, uint encoding) + { + InstRmb22w3Rnb19w3Rdb16w3 inst = new(encoding); + + InstEmitAlu.SubR(context, inst.Rd, inst.Rn, inst.Rm, 0, 0, !context.InITBlock); + } + + public static void SubRT2(CodeGenContext context, uint encoding) + { + InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.SubR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), !context.InITBlock); + } + + public static void SubRrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.SubRr(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Rs, inst.S != 0); + } + + public static void SubSpIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rdb12w4Imm12b0w12 inst = new(encoding); + + InstEmitAlu.SubI(context, inst.Rd, RegisterUtils.SpRegister, ImmUtils.ExpandImm(inst.Imm12), inst.S != 0); + } + + public static void SubSpIT1(CodeGenContext context, uint encoding) + { + InstImm7b16w7 inst = new(encoding); + + InstEmitAlu.SubI(context, RegisterUtils.SpRegister, RegisterUtils.SpRegister, inst.Imm7 << 2, false); + } + + public static void SubSpIT2(CodeGenContext context, uint encoding) + { + InstIb26w1Sb20w1Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitAlu.SubI(context, inst.Rd, RegisterUtils.SpRegister, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), inst.S != 0); + } + + public static void SubSpIT3(CodeGenContext context, uint encoding) + { + InstIb26w1Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding); + + InstEmitAlu.SubI(context, inst.Rd, RegisterUtils.SpRegister, ImmUtils.CombineImmU12(inst.Imm8, inst.Imm3, inst.I), false); + } + + public static void SubSpRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.SubR(context, inst.Rd, RegisterUtils.SpRegister, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0); + } + + public static void SubSpRT1(CodeGenContext context, uint encoding) + { + InstSb20w1Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.SubR(context, inst.Rd, RegisterUtils.SpRegister, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0); + } + + public static void SvcA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Imm24b0w24 inst = new(encoding); + + InstEmitSystem.Svc(context, inst.Imm24); + } + + public static void SvcT1(CodeGenContext context, uint encoding) + { + InstImm8b16w8 inst = new(encoding); + + InstEmitSystem.Svc(context, inst.Imm8); + } + + public static void SxtabA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Sxtab(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate); + } + + public static void SxtabT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rotateb4w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Sxtab(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate); + } + + public static void Sxtab16A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Sxtab16(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate); + } + + public static void Sxtab16T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rotateb4w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Sxtab16(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate); + } + + public static void SxtahA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Sxtah(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate); + } + + public static void SxtahT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rotateb4w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Sxtah(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate); + } + + public static void SxtbA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Sxtb(context, inst.Rd, inst.Rm, inst.Rotate); + } + + public static void SxtbT1(CodeGenContext context, uint encoding) + { + InstRmb19w3Rdb16w3 inst = new(encoding); + + InstEmitExtension.Sxtb(context, inst.Rd, inst.Rm, 0); + } + + public static void SxtbT2(CodeGenContext context, uint encoding) + { + InstRdb8w4Rotateb4w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Sxtb(context, inst.Rd, inst.Rm, inst.Rotate); + } + + public static void Sxtb16A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Sxtb16(context, inst.Rd, inst.Rm, inst.Rotate); + } + + public static void Sxtb16T1(CodeGenContext context, uint encoding) + { + InstRdb8w4Rotateb4w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Sxtb16(context, inst.Rd, inst.Rm, inst.Rotate); + } + + public static void SxthA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Sxth(context, inst.Rd, inst.Rm, inst.Rotate); + } + + public static void SxthT1(CodeGenContext context, uint encoding) + { + InstRmb19w3Rdb16w3 inst = new(encoding); + + InstEmitExtension.Sxth(context, inst.Rd, inst.Rm, 0); + } + + public static void SxthT2(CodeGenContext context, uint encoding) + { + InstRdb8w4Rotateb4w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Sxth(context, inst.Rd, inst.Rm, inst.Rotate); + } + + public static void TbbT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Hb4w1Rmb0w4 inst = new(encoding); + + InstEmitFlow.Tbb(context, inst.Rn, inst.Rm, inst.H != 0); + } + + public static void TeqIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Imm12b0w12 inst = new(encoding); + + InstEmitAlu.TeqI(context, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), ImmUtils.ExpandedImmRotated(inst.Imm12)); + } + + public static void TeqIT1(CodeGenContext context, uint encoding) + { + InstIb26w1Rnb16w4Imm3b12w3Imm8b0w8 inst = new(encoding); + + InstEmitAlu.TeqI(context, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), ImmUtils.ExpandedImmRotated(inst.Imm8, inst.Imm3, inst.I)); + } + + public static void TeqRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.TeqR(context, inst.Rn, inst.Rm, inst.Stype, inst.Imm5); + } + + public static void TeqRT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Imm3b12w3Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.TeqR(context, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3)); + } + + public static void TeqRrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.TeqRr(context, inst.Rn, inst.Rm, inst.Stype, inst.Rs); + } + + public static void TsbA1(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Tsb(); + } + + public static void TsbT1(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Tsb(); + } + + public static void TstIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Imm12b0w12 inst = new(encoding); + + InstEmitAlu.TstI(context, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), ImmUtils.ExpandedImmRotated(inst.Imm12)); + } + + public static void TstIT1(CodeGenContext context, uint encoding) + { + InstIb26w1Rnb16w4Imm3b12w3Imm8b0w8 inst = new(encoding); + + InstEmitAlu.TstI(context, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), ImmUtils.ExpandedImmRotated(inst.Imm8, inst.Imm3, inst.I)); + } + + public static void TstRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.TstR(context, inst.Rn, inst.Rm, inst.Stype, inst.Imm5); + } + + public static void TstRT1(CodeGenContext context, uint encoding) + { + InstRmb19w3Rnb16w3 inst = new(encoding); + + InstEmitAlu.TstR(context, inst.Rn, inst.Rm, 0, 0); + } + + public static void TstRT2(CodeGenContext context, uint encoding) + { + InstRnb16w4Imm3b12w3Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.TstR(context, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3)); + } + + public static void TstRrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding); + + InstEmitAlu.TstRr(context, inst.Rn, inst.Rm, inst.Stype, inst.Rs); + } + + public static void Uadd16A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Uadd16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Uadd16T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Uadd16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Uadd8A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Uadd8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Uadd8T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Uadd8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void UasxA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Uasx(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void UasxT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Uasx(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void UbfxA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Widthm1b16w5Rdb12w4Lsbb7w5Rnb0w4 inst = new(encoding); + + InstEmitBit.Ubfx(context, inst.Rd, inst.Rn, inst.Lsb, inst.Widthm1); + } + + public static void UbfxT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Imm3b12w3Rdb8w4Imm2b6w2Widthm1b0w5 inst = new(encoding); + + InstEmitBit.Ubfx(context, inst.Rd, inst.Rn, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.Widthm1); + } + + public static void UdfA1(CodeGenContext context, uint encoding) + { + InstImm12b8w12Imm4b0w4 inst = new(encoding); + + InstEmitSystem.Udf(context, encoding, ImmUtils.CombineImmU16(inst.Imm12, inst.Imm4)); + } + + public static void UdfT1(CodeGenContext context, uint encoding) + { + InstImm8b16w8 inst = new(encoding); + + InstEmitSystem.Udf(context, encoding, inst.Imm8); + } + + public static void UdfT2(CodeGenContext context, uint encoding) + { + InstImm4b16w4Imm12b0w12 inst = new(encoding); + + InstEmitSystem.Udf(context, encoding, ImmUtils.CombineImmU16(inst.Imm12, inst.Imm4)); + } + + public static void UdivA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb16w4Rmb8w4Rnb0w4 inst = new(encoding); + + InstEmitDivide.Udiv(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void UdivT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitDivide.Udiv(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Uhadd16A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Uhadd16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Uhadd16T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Uhadd16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Uhadd8A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Uhadd8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Uhadd8T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Uhadd8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void UhasxA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Uhasx(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void UhasxT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Uhasx(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void UhsaxA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Uhsax(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void UhsaxT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Uhsax(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Uhsub16A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Uhsub16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Uhsub16T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Uhsub16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Uhsub8A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Uhsub8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Uhsub8T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitHalve.Uhsub8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void UmaalA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdhib16w4Rdlob12w4Rmb8w4Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Umaal(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm); + } + + public static void UmaalT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdlob12w4Rdhib8w4Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Umaal(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm); + } + + public static void UmlalA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rdhib16w4Rdlob12w4Rmb8w4Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Umlal(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, inst.S != 0); + } + + public static void UmlalT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdlob12w4Rdhib8w4Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Umlal(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, false); + } + + public static void UmullA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Sb20w1Rdhib16w4Rdlob12w4Rmb8w4Rnb0w4 inst = new(encoding); + + InstEmitMultiply.Umull(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, inst.S != 0); + } + + public static void UmullT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdlob12w4Rdhib8w4Rmb0w4 inst = new(encoding); + + InstEmitMultiply.Umull(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, false); + } + + public static void Uqadd16A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Uqadd16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Uqadd16T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Uqadd16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Uqadd8A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Uqadd8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Uqadd8T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Uqadd8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void UqasxA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Uqasx(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void UqasxT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Uqasx(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void UqsaxA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Uqsax(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void UqsaxT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Uqsax(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Uqsub16A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Uqsub16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Uqsub16T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Uqsub16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Uqsub8A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Uqsub8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Uqsub8T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitSaturate.Uqsub8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Usad8A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb16w4Rmb8w4Rnb0w4 inst = new(encoding); + + InstEmitAbsDiff.Usad8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Usad8T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitAbsDiff.Usad8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Usada8A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb16w4Rab12w4Rmb8w4Rnb0w4 inst = new(encoding); + + InstEmitAbsDiff.Usada8(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra); + } + + public static void Usada8T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rab12w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitAbsDiff.Usada8(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra); + } + + public static void UsatA1(CodeGenContext context, uint encoding) + { + InstCondb28w4SatImmb16w5Rdb12w4Imm5b7w5Shb6w1Rnb0w4 inst = new(encoding); + + InstEmitSaturate.Usat(context, inst.Rd, inst.SatImm, inst.Rn, inst.Sh != 0, inst.Imm5); + } + + public static void UsatT1(CodeGenContext context, uint encoding) + { + InstShb21w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2SatImmb0w5 inst = new(encoding); + + InstEmitSaturate.Usat(context, inst.Rd, inst.SatImm, inst.Rn, inst.Sh != 0, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3)); + } + + public static void Usat16A1(CodeGenContext context, uint encoding) + { + InstCondb28w4SatImmb16w4Rdb12w4Rnb0w4 inst = new(encoding); + + InstEmitSaturate.Usat16(context, inst.Rd, inst.SatImm, inst.Rn); + } + + public static void Usat16T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4SatImmb0w4 inst = new(encoding); + + InstEmitSaturate.Usat16(context, inst.Rd, inst.SatImm, inst.Rn); + } + + public static void UsaxA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Usax(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void UsaxT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Usax(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Usub16A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Usub16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Usub16T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Usub16(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Usub8A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Usub8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void Usub8T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding); + + InstEmitGE.Usub8(context, inst.Rd, inst.Rn, inst.Rm); + } + + public static void UxtabA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Uxtab(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate); + } + + public static void UxtabT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rotateb4w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Uxtab(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate); + } + + public static void Uxtab16A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Uxtab16(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate); + } + + public static void Uxtab16T1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rotateb4w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Uxtab16(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate); + } + + public static void UxtahA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rnb16w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Uxtah(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate); + } + + public static void UxtahT1(CodeGenContext context, uint encoding) + { + InstRnb16w4Rdb8w4Rotateb4w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Uxtah(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate); + } + + public static void UxtbA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Uxtb(context, inst.Rd, inst.Rm, inst.Rotate); + } + + public static void UxtbT1(CodeGenContext context, uint encoding) + { + InstRmb19w3Rdb16w3 inst = new(encoding); + + InstEmitExtension.Uxtb(context, inst.Rd, inst.Rm, 0); + } + + public static void UxtbT2(CodeGenContext context, uint encoding) + { + InstRdb8w4Rotateb4w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Uxtb(context, inst.Rd, inst.Rm, inst.Rotate); + } + + public static void Uxtb16A1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Uxtb16(context, inst.Rd, inst.Rm, inst.Rotate); + } + + public static void Uxtb16T1(CodeGenContext context, uint encoding) + { + InstRdb8w4Rotateb4w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Uxtb16(context, inst.Rd, inst.Rm, inst.Rotate); + } + + public static void UxthA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Uxth(context, inst.Rd, inst.Rm, inst.Rotate); + } + + public static void UxthT1(CodeGenContext context, uint encoding) + { + InstRmb19w3Rdb16w3 inst = new(encoding); + + InstEmitExtension.Uxth(context, inst.Rd, inst.Rm, 0); + } + + public static void UxthT2(CodeGenContext context, uint encoding) + { + InstRdb8w4Rotateb4w2Rmb0w4 inst = new(encoding); + + InstEmitExtension.Uxth(context, inst.Rd, inst.Rm, inst.Rotate); + } + + public static void VabaA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vaba(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VabaT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vaba(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VabalA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vabal(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VabalT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vabal(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VabdlIA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vabdl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VabdlIT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vabdl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VabdFA1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VabdF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VabdFT1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VabdF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VabdIA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VabdI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VabdIT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VabdI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VabsA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vabs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VabsA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VabsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VabsT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vabs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VabsT2(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VabsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VacgeA1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.Vacge(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VacgeT1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.Vacge(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VacgtA1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.Vacgt(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VacgtT1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.Vacgt(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VaddhnA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vaddhn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VaddhnT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vaddhn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VaddlA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vaddl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VaddlT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vaddl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VaddwA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vaddw(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VaddwT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vaddw(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VaddFA1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VaddF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VaddFA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VaddF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VaddFT1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VaddF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VaddFT2(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VaddF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VaddIA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VaddI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VaddIT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VaddI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VandRA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonLogical.VandR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void VandRT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonLogical.VandR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void VbicIA1(CodeGenContext context, uint encoding) + { + InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonLogical.VbicI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VbicIA2(CodeGenContext context, uint encoding) + { + InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonLogical.VbicI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VbicIT1(CodeGenContext context, uint encoding) + { + InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonLogical.VbicI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VbicIT2(CodeGenContext context, uint encoding) + { + InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonLogical.VbicI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VbicRA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonLogical.VbicR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void VbicRT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonLogical.VbicR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void VbifA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonLogical.VbifR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void VbifT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonLogical.VbifR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void VbitA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonLogical.VbitR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void VbitT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonLogical.VbitR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void VbslA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonLogical.VbslR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void VbslT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonLogical.VbslR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void VcaddA1(CodeGenContext context, uint encoding) + { + _ = new InstRotb24w1Db22w1Sb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VcaddT1(CodeGenContext context, uint encoding) + { + _ = new InstRotb24w1Db22w1Sb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VceqIA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VceqI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VceqIT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VceqI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VceqRA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VceqR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VceqRA2(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VceqFR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VceqRT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VceqR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VceqRT2(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VceqFR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VcgeIA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VcgeI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VcgeIT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VcgeI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VcgeRA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VcgeR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VcgeRA2(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VcgeFR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VcgeRT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VcgeR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VcgeRT2(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VcgeFR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VcgtIA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VcgtI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VcgtIT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VcgtI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VcgtRA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VcgtR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VcgtRA2(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VcgtFR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VcgtRT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VcgtR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VcgtRT2(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VcgtFR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VcleIA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VcleI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VcleIT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VcleI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VclsA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonBit.Vcls(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VclsT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonBit.Vcls(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VcltIA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VcltI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VcltIT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.VcltI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VclzA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonBit.Vclz(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VclzT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonBit.Vclz(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VcmlaA1(CodeGenContext context, uint encoding) + { + _ = new InstRotb23w2Db22w1Sb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VcmlaT1(CodeGenContext context, uint encoding) + { + _ = new InstRotb23w2Db22w1Sb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VcmlaSA1(CodeGenContext context, uint encoding) + { + _ = new InstSb23w1Db22w1Rotb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VcmlaST1(CodeGenContext context, uint encoding) + { + _ = new InstSb23w1Db22w1Rotb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VcmpA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpCompare.VcmpR(context, inst.Cond, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VcmpA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vdb12w4Sizeb8w2 inst = new(encoding); + + InstEmitVfpCompare.VcmpI(context, inst.Cond, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), inst.Size); + } + + public static void VcmpT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpCompare.VcmpR(context, 0xe, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VcmpT2(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2 inst = new(encoding); + + InstEmitVfpCompare.VcmpI(context, 0xe, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), inst.Size); + } + + public static void VcmpeA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpCompare.VcmpeR(context, inst.Cond, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VcmpeA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vdb12w4Sizeb8w2 inst = new(encoding); + + InstEmitVfpCompare.VcmpeI(context, inst.Cond, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), inst.Size); + } + + public static void VcmpeT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpCompare.VcmpeR(context, 0xe, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VcmpeT2(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2 inst = new(encoding); + + InstEmitVfpCompare.VcmpeI(context, 0xe, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), inst.Size); + } + + public static void VcntA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonBit.Vcnt(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VcntT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonBit.Vcnt(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VcvtaAsimdA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonConvert.Vcvta(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q); + } + + public static void VcvtaAsimdT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonConvert.Vcvta(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q); + } + + public static void VcvtaVfpA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpConvert.Vcvta(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Op != 0, inst.Size); + } + + public static void VcvtaVfpT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpConvert.Vcvta(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Op != 0, inst.Size); + } + + public static void VcvtbA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Opb16w1Vdb12w4Szb8w1Mb5w1Vmb0w4 inst = new(encoding); + + uint dSize = inst.Sz == 1 && inst.Op == 0 ? 3u : 2u; + uint mSize = inst.Sz == 1 && inst.Op == 1 ? 3u : 2u; + + InstEmitVfpConvert.Vcvtb(context, InstEmitCommon.CombineV(inst.Vd, inst.D, dSize), InstEmitCommon.CombineV(inst.Vm, inst.M, mSize), inst.Sz, inst.Op); + } + + public static void VcvtbT1(CodeGenContext context, uint encoding) + { + InstDb22w1Opb16w1Vdb12w4Szb8w1Mb5w1Vmb0w4 inst = new(encoding); + + uint dSize = inst.Sz == 1 && inst.Op == 0 ? 3u : 2u; + uint mSize = inst.Sz == 1 && inst.Op == 1 ? 3u : 2u; + + InstEmitVfpConvert.Vcvtb(context, InstEmitCommon.CombineV(inst.Vd, inst.D, dSize), InstEmitCommon.CombineV(inst.Vm, inst.M, mSize), inst.Sz, inst.Op); + } + + public static void VcvtbBfsA1(CodeGenContext context, uint encoding) + { + _ = new InstCondb28w4Db22w1Vdb12w4Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VcvtbBfsT1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vdb12w4Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VcvtmAsimdA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonConvert.Vcvtm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q); + } + + public static void VcvtmAsimdT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonConvert.Vcvtm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q); + } + + public static void VcvtmVfpA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpConvert.Vcvtm(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Op != 0, inst.Size); + } + + public static void VcvtmVfpT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpConvert.Vcvtm(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Op != 0, inst.Size); + } + + public static void VcvtnAsimdA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonConvert.Vcvtn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q); + } + + public static void VcvtnAsimdT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonConvert.Vcvtn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q); + } + + public static void VcvtnVfpA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpConvert.Vcvtn(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Op != 0, inst.Size); + } + + public static void VcvtnVfpT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpConvert.Vcvtn(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Op != 0, inst.Size); + } + + public static void VcvtpAsimdA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonConvert.Vcvtp(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q); + } + + public static void VcvtpAsimdT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonConvert.Vcvtp(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q); + } + + public static void VcvtpVfpA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpConvert.Vcvtp(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Op != 0, inst.Size); + } + + public static void VcvtpVfpT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpConvert.Vcvtp(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Op != 0, inst.Size); + } + + public static void VcvtrIvA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpConvert.VcvtrIv(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), (encoding >> 16) & 7, inst.Size); + } + + public static void VcvtrIvT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpConvert.VcvtrIv(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), (encoding >> 16) & 7, inst.Size); + } + + public static void VcvttA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Opb16w1Vdb12w4Szb8w1Mb5w1Vmb0w4 inst = new(encoding); + + uint dSize = inst.Sz == 1 && inst.Op == 0 ? 3u : 2u; + uint mSize = inst.Sz == 1 && inst.Op == 1 ? 3u : 2u; + + InstEmitVfpConvert.Vcvtt(context, InstEmitCommon.CombineV(inst.Vd, inst.D, dSize), InstEmitCommon.CombineV(inst.Vm, inst.M, mSize), inst.Sz, inst.Op); + } + + public static void VcvttT1(CodeGenContext context, uint encoding) + { + InstDb22w1Opb16w1Vdb12w4Szb8w1Mb5w1Vmb0w4 inst = new(encoding); + + uint dSize = inst.Sz == 1 && inst.Op == 0 ? 3u : 2u; + uint mSize = inst.Sz == 1 && inst.Op == 1 ? 3u : 2u; + + InstEmitVfpConvert.Vcvtt(context, InstEmitCommon.CombineV(inst.Vd, inst.D, dSize), InstEmitCommon.CombineV(inst.Vm, inst.M, mSize), inst.Sz, inst.Op); + } + + public static void VcvttBfsA1(CodeGenContext context, uint encoding) + { + _ = new InstCondb28w4Db22w1Vdb12w4Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VcvttBfsT1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vdb12w4Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VcvtBfsA1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vdb12w4Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VcvtBfsT1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vdb12w4Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VcvtDsA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + uint size = (encoding >> 8) & 3; + + InstEmitVfpConvert.VcvtDs(context, InstEmitCommon.CombineV(inst.Vd, inst.D, size ^ 1u), InstEmitCommon.CombineV(inst.Vm, inst.M, size), size); + } + + public static void VcvtDsT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + uint size = (encoding >> 8) & 3; + + InstEmitVfpConvert.VcvtDs(context, InstEmitCommon.CombineV(inst.Vd, inst.D, size ^ 1u), InstEmitCommon.CombineV(inst.Vm, inst.M, size), size); + } + + public static void VcvtHsA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Opb8w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonConvert.VcvtHs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0); + } + + public static void VcvtHsT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Opb8w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonConvert.VcvtHs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0); + } + + public static void VcvtIsA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Opb7w2Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonConvert.VcvtIs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op, inst.Size, inst.Q); + } + + public static void VcvtIsT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Opb7w2Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonConvert.VcvtIs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op, inst.Size, inst.Q); + } + + public static void VcvtIvA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpConvert.VcvtIv(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), (encoding & (1u << 16)) == 0, inst.Size); + } + + public static void VcvtIvT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpConvert.VcvtIv(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), (encoding & (1u << 16)) == 0, inst.Size); + } + + public static void VcvtViA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpConvert.VcvtVi(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineVF(inst.M, inst.Vm), inst.Op == 0, inst.Size); + } + + public static void VcvtViT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpConvert.VcvtVi(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineVF(inst.M, inst.Vm), inst.Op == 0, inst.Size); + } + + public static void VcvtXsA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Imm6b16w6Vdb12w4Opb8w2Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonConvert.VcvtXs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm6, inst.Op, inst.U != 0, inst.Q); + } + + public static void VcvtXsT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Imm6b16w6Vdb12w4Opb8w2Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonConvert.VcvtXs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm6, inst.Op, inst.U != 0, inst.Q); + } + + public static void VcvtXvA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Opb18w1Ub16w1Vdb12w4Sfb8w2Sxb7w1Ib5w1Imm4b0w4 inst = new(encoding); + + InstEmitVfpConvert.VcvtXv(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Sf), ImmUtils.CombineImmU5IImm4(inst.I, inst.Imm4), inst.Sx != 0, inst.Sf, inst.Op, inst.U != 0); + } + + public static void VcvtXvT1(CodeGenContext context, uint encoding) + { + InstDb22w1Opb18w1Ub16w1Vdb12w4Sfb8w2Sxb7w1Ib5w1Imm4b0w4 inst = new(encoding); + + InstEmitVfpConvert.VcvtXv(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Sf), ImmUtils.CombineImmU5IImm4(inst.I, inst.Imm4), inst.Sx != 0, inst.Sf, inst.Op, inst.U != 0); + } + + public static void VdivA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VdivF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VdivT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VdivF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VdotA1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VdotT1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VdotSA1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VdotST1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VdupRA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Bb22w1Qb21w1Vdb16w4Rtb12w4Db7w1Eb5w1 inst = new(encoding); + + InstEmitNeonMove.VdupR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rt, inst.B, inst.E, inst.Q); + } + + public static void VdupRT1(CodeGenContext context, uint encoding) + { + InstBb22w1Qb21w1Vdb16w4Rtb12w4Db7w1Eb5w1 inst = new(encoding); + + InstEmitNeonMove.VdupR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rt, inst.B, inst.E, inst.Q); + } + + public static void VdupSA1(CodeGenContext context, uint encoding) + { + InstDb22w1Imm4b16w4Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.VdupS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm4, inst.Q); + } + + public static void VdupST1(CodeGenContext context, uint encoding) + { + InstDb22w1Imm4b16w4Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.VdupS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm4, inst.Q); + } + + public static void VeorA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonLogical.VeorR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void VeorT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonLogical.VeorR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void VextA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Imm4b8w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.Vext(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm4, inst.Q); + } + + public static void VextT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Imm4b8w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.Vext(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm4, inst.Q); + } + + public static void VfmaA1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VfmaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VfmaA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VfmaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VfmaT1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VfmaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VfmaT2(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VfmaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VfmalA1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VfmalT1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VfmalSA1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VfmalST1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VfmaBfA1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VfmaBfT1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VfmaBfsA1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VfmaBfsT1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VfmsA1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VfmsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VfmsA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VfmsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VfmsT1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VfmsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VfmsT2(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VfmsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VfmslA1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VfmslT1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VfmslSA1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VfmslST1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VfnmaA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VfnmaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VfnmaT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VfnmaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VfnmsA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VfnmsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VfnmsT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VfnmsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VhaddA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vhadd(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VhaddT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vhadd(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VhsubA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vhsub(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VhsubT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vhsub(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VinsA1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vdb12w4Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VinsT1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vdb12w4Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VjcvtA1(CodeGenContext context, uint encoding) + { + _ = new InstCondb28w4Db22w1Vdb12w4Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VjcvtT1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vdb12w4Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void Vld11A1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0); + } + + public static void Vld11A2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1); + } + + public static void Vld11A3(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2); + } + + public static void Vld11T1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0); + } + + public static void Vld11T2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1); + } + + public static void Vld11T3(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2); + } + + public static void Vld1AA1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Ab4w1Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld1A(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.A, inst.T, inst.Size); + } + + public static void Vld1AT1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Ab4w1Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld1A(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.A, inst.T, inst.Size); + } + + public static void Vld1MA1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 1, inst.Align, inst.Size); + } + + public static void Vld1MA2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 2, inst.Align, inst.Size); + } + + public static void Vld1MA3(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 3, inst.Align, inst.Size); + } + + public static void Vld1MA4(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 4, inst.Align, inst.Size); + } + + public static void Vld1MT1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 1, inst.Align, inst.Size); + } + + public static void Vld1MT2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 2, inst.Align, inst.Size); + } + + public static void Vld1MT3(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 3, inst.Align, inst.Size); + } + + public static void Vld1MT4(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 4, inst.Align, inst.Size); + } + + public static void Vld21A1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0); + } + + public static void Vld21A2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1); + } + + public static void Vld21A3(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2); + } + + public static void Vld21T1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0); + } + + public static void Vld21T2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1); + } + + public static void Vld21T3(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2); + } + + public static void Vld2AA1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Ab4w1Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld2A(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.A, inst.T, inst.Size); + } + + public static void Vld2AT1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Ab4w1Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld2A(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.A, inst.T, inst.Size); + } + + public static void Vld2MA1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld2M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size); + } + + public static void Vld2MA2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld2M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.Align, inst.Size); + } + + public static void Vld2MT1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld2M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size); + } + + public static void Vld2MT2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld2M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.Align, inst.Size); + } + + public static void Vld31A1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0); + } + + public static void Vld31A2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1); + } + + public static void Vld31A3(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2); + } + + public static void Vld31T1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0); + } + + public static void Vld31T2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1); + } + + public static void Vld31T3(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2); + } + + public static void Vld3AA1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld3A(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 0, inst.T, inst.Size); + } + + public static void Vld3AT1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld3A(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 0, inst.T, inst.Size); + } + + public static void Vld3MA1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld3M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size); + } + + public static void Vld3MT1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld3M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size); + } + + public static void Vld41A1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0); + } + + public static void Vld41A2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1); + } + + public static void Vld41A3(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2); + } + + public static void Vld41T1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0); + } + + public static void Vld41T2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1); + } + + public static void Vld41T3(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2); + } + + public static void Vld4AA1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Ab4w1Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld4A(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.A, inst.T, inst.Size); + } + + public static void Vld4AT1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Ab4w1Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld4A(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.A, inst.T, inst.Size); + } + + public static void Vld4MA1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld4M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size); + } + + public static void Vld4MT1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vld4M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size); + } + + public static void VldmA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7 inst = new(encoding); + + InstEmitNeonMemory.Vldm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Imm871, inst.U != 0, inst.W != 0, singleRegs: false); + } + + public static void VldmA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm8b0w8 inst = new(encoding); + + InstEmitNeonMemory.Vldm(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), inst.Rn, inst.Imm8, inst.U != 0, inst.W != 0, singleRegs: true); + } + + public static void VldmT1(CodeGenContext context, uint encoding) + { + InstPb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7 inst = new(encoding); + + InstEmitNeonMemory.Vldm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Imm871, inst.U != 0, inst.W != 0, singleRegs: false); + } + + public static void VldmT2(CodeGenContext context, uint encoding) + { + InstPb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm8b0w8 inst = new(encoding); + + InstEmitNeonMemory.Vldm(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), inst.Rn, inst.Imm8, inst.U != 0, inst.W != 0, singleRegs: true); + } + + public static void VldrIA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Ub23w1Db22w1Rnb16w4Vdb12w4Sizeb8w2Imm8b0w8 inst = new(encoding); + + InstEmitNeonMemory.Vldr(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), inst.Rn, inst.Imm8, inst.U != 0, inst.Size); + } + + public static void VldrIT1(CodeGenContext context, uint encoding) + { + InstUb23w1Db22w1Rnb16w4Vdb12w4Sizeb8w2Imm8b0w8 inst = new(encoding); + + InstEmitNeonMemory.Vldr(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), inst.Rn, inst.Imm8, inst.U != 0, inst.Size); + } + + public static void VldrLA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Ub23w1Db22w1Vdb12w4Sizeb8w2Imm8b0w8 inst = new(encoding); + + InstEmitNeonMemory.Vldr(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), RegisterUtils.PcRegister, inst.Imm8, inst.U != 0, inst.Size); + } + + public static void VldrLT1(CodeGenContext context, uint encoding) + { + InstUb23w1Db22w1Vdb12w4Sizeb8w2Imm8b0w8 inst = new(encoding); + + InstEmitNeonMemory.Vldr(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), RegisterUtils.PcRegister, inst.Imm8, inst.U != 0, inst.Size); + } + + public static void VmaxnmA1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vmaxnm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VmaxnmA2(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.Vmaxnm(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VmaxnmT1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vmaxnm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VmaxnmT2(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.Vmaxnm(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VmaxFA1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmaxF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VmaxFT1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmaxF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VmaxIA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmaxI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VmaxIT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmaxI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VminnmA1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vminnm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VminnmA2(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.Vminnm(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VminnmT1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vminnm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VminnmT2(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.Vminnm(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VminFA1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VminF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VminFT1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VminF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VminIA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VminI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VminIT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VminI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VmlalIA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmlalI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VmlalIT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmlalI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VmlalSA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmlalS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VmlalST1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmlalS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VmlaFA1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmlaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VmlaFA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VmlaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VmlaFT1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmlaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VmlaFT2(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VmlaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VmlaIA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmlaI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VmlaIT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmlaI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VmlaSA1(CodeGenContext context, uint encoding) + { + InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Fb8w1Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmlaS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VmlaST1(CodeGenContext context, uint encoding) + { + InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Fb8w1Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmlaS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VmlslIA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmlslI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VmlslIT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmlslI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VmlslSA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmlslS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VmlslST1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmlslS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VmlsFA1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmlsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VmlsFA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VmlsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VmlsFT1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmlsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VmlsFT2(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VmlsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VmlsIA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmlsI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VmlsIT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmlsI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VmlsSA1(CodeGenContext context, uint encoding) + { + InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Fb8w1Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmlsS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VmlsST1(CodeGenContext context, uint encoding) + { + InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Fb8w1Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmlsS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VmmlaA1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VmmlaT1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VmovlA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Imm3hb19w3Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.Vmovl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Imm3h); + } + + public static void VmovlT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Imm3hb19w3Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.Vmovl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Imm3h); + } + + public static void VmovnA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.Vmovn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VmovnT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.Vmovn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VmovxA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.Vmovx(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M)); + } + + public static void VmovxT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.Vmovx(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M)); + } + + public static void VmovDA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Opb20w1Rt2b16w4Rtb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.VmovD(context, inst.Rt, inst.Rt2, InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0); + } + + public static void VmovDT1(CodeGenContext context, uint encoding) + { + InstOpb20w1Rt2b16w4Rtb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.VmovD(context, inst.Rt, inst.Rt2, InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0); + } + + public static void VmovHA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Opb20w1Vnb16w4Rtb12w4Nb7w1 inst = new(encoding); + + InstEmitNeonMove.VmovH(context, inst.Rt, InstEmitCommon.CombineVF(inst.N, inst.Vn), inst.Op != 0); + } + + public static void VmovHT1(CodeGenContext context, uint encoding) + { + InstOpb20w1Vnb16w4Rtb12w4Nb7w1 inst = new(encoding); + + InstEmitNeonMove.VmovH(context, inst.Rt, InstEmitCommon.CombineVF(inst.N, inst.Vn), inst.Op != 0); + } + + public static void VmovIA1(CodeGenContext context, uint encoding) + { + InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonMove.VmovI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), 0, (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VmovIA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Imm4hb16w4Vdb12w4Sizeb8w2Imm4lb0w4 inst = new(encoding); + + InstEmitNeonMove.VmovFI(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.Size); + } + + public static void VmovIA3(CodeGenContext context, uint encoding) + { + InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonMove.VmovI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), 0, (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VmovIA4(CodeGenContext context, uint encoding) + { + InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonMove.VmovI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), 0, (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VmovIA5(CodeGenContext context, uint encoding) + { + InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonMove.VmovI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), 1, (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VmovIT1(CodeGenContext context, uint encoding) + { + InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonMove.VmovI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), 0, (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VmovIT2(CodeGenContext context, uint encoding) + { + InstDb22w1Imm4hb16w4Vdb12w4Sizeb8w2Imm4lb0w4 inst = new(encoding); + + InstEmitNeonMove.VmovFI(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.Size); + } + + public static void VmovIT3(CodeGenContext context, uint encoding) + { + InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonMove.VmovI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), 0, (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VmovIT4(CodeGenContext context, uint encoding) + { + InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonMove.VmovI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), 0, (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VmovIT5(CodeGenContext context, uint encoding) + { + InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonMove.VmovI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), 1, (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VmovRA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + uint size = (encoding >> 8) & 3; + + InstEmitNeonMove.VmovR(context, InstEmitCommon.CombineV(inst.Vd, inst.D, size), InstEmitCommon.CombineV(inst.Vm, inst.M, size), size); + } + + public static void VmovRT2(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + uint size = (encoding >> 8) & 3; + + InstEmitNeonMove.VmovR(context, InstEmitCommon.CombineV(inst.Vd, inst.D, size), InstEmitCommon.CombineV(inst.Vm, inst.M, size), size); + } + + public static void VmovRsA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Opc1b21w2Vdb16w4Rtb12w4Db7w1Opc2b5w2 inst = new(encoding); + + InstEmitNeonMove.VmovRs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rt, inst.Opc1, inst.Opc2); + } + + public static void VmovRsT1(CodeGenContext context, uint encoding) + { + InstOpc1b21w2Vdb16w4Rtb12w4Db7w1Opc2b5w2 inst = new(encoding); + + InstEmitNeonMove.VmovRs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rt, inst.Opc1, inst.Opc2); + } + + public static void VmovSA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Opb20w1Vnb16w4Rtb12w4Nb7w1 inst = new(encoding); + + InstEmitNeonMove.VmovS(context, inst.Rt, InstEmitCommon.CombineVF(inst.N, inst.Vn), inst.Op != 0); + } + + public static void VmovST1(CodeGenContext context, uint encoding) + { + InstOpb20w1Vnb16w4Rtb12w4Nb7w1 inst = new(encoding); + + InstEmitNeonMove.VmovS(context, inst.Rt, InstEmitCommon.CombineVF(inst.N, inst.Vn), inst.Op != 0); + } + + public static void VmovSrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Ub23w1Opc1b21w2Vnb16w4Rtb12w4Nb7w1Opc2b5w2 inst = new(encoding); + + InstEmitNeonMove.VmovSr(context, inst.Rt, InstEmitCommon.CombineV(inst.Vn, inst.N), inst.U != 0, inst.Opc1, inst.Opc2); + } + + public static void VmovSrT1(CodeGenContext context, uint encoding) + { + InstUb23w1Opc1b21w2Vnb16w4Rtb12w4Nb7w1Opc2b5w2 inst = new(encoding); + + InstEmitNeonMove.VmovSr(context, inst.Rt, InstEmitCommon.CombineV(inst.Vn, inst.N), inst.U != 0, inst.Opc1, inst.Opc2); + } + + public static void VmovSsA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Opb20w1Rt2b16w4Rtb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.VmovSs(context, inst.Rt, inst.Rt2, InstEmitCommon.CombineVF(inst.M, inst.Vm), inst.Op != 0); + } + + public static void VmovSsT1(CodeGenContext context, uint encoding) + { + InstOpb20w1Rt2b16w4Rtb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.VmovSs(context, inst.Rt, inst.Rt2, InstEmitCommon.CombineVF(inst.M, inst.Vm), inst.Op != 0); + } + + public static void VmrsA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Regb16w4Rtb12w4 inst = new(encoding); + + InstEmitNeonSystem.Vmrs(context, inst.Rt, inst.Reg); + } + + public static void VmrsT1(CodeGenContext context, uint encoding) + { + InstRegb16w4Rtb12w4 inst = new(encoding); + + InstEmitNeonSystem.Vmrs(context, inst.Rt, inst.Reg); + } + + public static void VmsrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Regb16w4Rtb12w4 inst = new(encoding); + + InstEmitNeonSystem.Vmsr(context, inst.Rt, inst.Reg); + } + + public static void VmsrT1(CodeGenContext context, uint encoding) + { + InstRegb16w4Rtb12w4 inst = new(encoding); + + InstEmitNeonSystem.Vmsr(context, inst.Rt, inst.Reg); + } + + public static void VmullIA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Opb9w1Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmullI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.U != 0, inst.Size); + } + + public static void VmullIT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Opb9w1Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmullI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.U != 0, inst.Size); + } + + public static void VmullSA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmullS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VmullST1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmullS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VmulFA1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmulF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VmulFA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VmulF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VmulFT1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmulF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VmulFT2(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VmulF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VmulIA1(CodeGenContext context, uint encoding) + { + InstOpb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmulI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q); + } + + public static void VmulIT1(CodeGenContext context, uint encoding) + { + InstOpb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmulI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q); + } + + public static void VmulSA1(CodeGenContext context, uint encoding) + { + InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Fb8w1Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmulS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VmulST1(CodeGenContext context, uint encoding) + { + InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Fb8w1Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VmulS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VmvnIA1(CodeGenContext context, uint encoding) + { + InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonMove.VmvnI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VmvnIA2(CodeGenContext context, uint encoding) + { + InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonMove.VmvnI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VmvnIA3(CodeGenContext context, uint encoding) + { + InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonMove.VmvnI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VmvnIT1(CodeGenContext context, uint encoding) + { + InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonMove.VmvnI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VmvnIT2(CodeGenContext context, uint encoding) + { + InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonMove.VmvnI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VmvnIT3(CodeGenContext context, uint encoding) + { + InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonMove.VmvnI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VmvnRA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.VmvnR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VmvnRT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.VmvnR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VnegA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vneg(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VnegA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VnegF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VnegT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vneg(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VnegT2(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VnegF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VnmlaA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VnmlaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VnmlaT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VnmlaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VnmlsA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VnmlsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VnmlsT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VnmlsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VnmulA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VnmulF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VnmulT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VnmulF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VornRA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonLogical.VornR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void VornRT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonLogical.VornR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void VorrIA1(CodeGenContext context, uint encoding) + { + InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonLogical.VorrI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VorrIA2(CodeGenContext context, uint encoding) + { + InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonLogical.VorrI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VorrIT1(CodeGenContext context, uint encoding) + { + InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonLogical.VorrI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VorrIT2(CodeGenContext context, uint encoding) + { + InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding); + + InstEmitNeonLogical.VorrI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q); + } + + public static void VorrRA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonLogical.VorrR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void VorrRT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonLogical.VorrR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void VpadalA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vpadal(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q); + } + + public static void VpadalT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vpadal(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q); + } + + public static void VpaddlA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vpaddl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q); + } + + public static void VpaddlT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vpaddl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q); + } + + public static void VpaddFA1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VpaddF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VpaddFT1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VpaddF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VpaddIA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VpaddI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VpaddIT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VpaddI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VpmaxFA1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VpmaxF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, 0); + } + + public static void VpmaxFT1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VpmaxF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, 0); + } + + public static void VpmaxIA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VpmaxI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, 0); + } + + public static void VpmaxIT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VpmaxI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, 0); + } + + public static void VpminFA1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VpminF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, 0); + } + + public static void VpminFT1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VpminF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, 0); + } + + public static void VpminIA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VpminI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, 0); + } + + public static void VpminIT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VpminI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, 0); + } + + public static void VqabsA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqabs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqabsT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqabs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqaddA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqadd(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VqaddT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqadd(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VqdmlalA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqdmlal(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VqdmlalA2(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.VqdmlalS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VqdmlalT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqdmlal(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VqdmlalT2(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.VqdmlalS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VqdmlslA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqdmlsl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VqdmlslA2(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.VqdmlslS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VqdmlslT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqdmlsl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VqdmlslT2(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.VqdmlslS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VqdmulhA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqdmulh(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqdmulhA2(CodeGenContext context, uint encoding) + { + InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.VqdmulhS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqdmulhT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqdmulh(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqdmulhT2(CodeGenContext context, uint encoding) + { + InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.VqdmulhS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqdmullA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqdmull(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VqdmullA2(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.VqdmullS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VqdmullT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqdmull(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VqdmullT2(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.VqdmullS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VqmovnA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Opb6w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqmovn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op, inst.Size); + } + + public static void VqmovnT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Opb6w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqmovn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op, inst.Size); + } + + public static void VqnegA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqneg(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqnegT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqneg(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqrdmlahA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqrdmlah(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqrdmlahA2(CodeGenContext context, uint encoding) + { + InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.VqrdmlahS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqrdmlahT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqrdmlah(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqrdmlahT2(CodeGenContext context, uint encoding) + { + InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.VqrdmlahS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqrdmlshA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqrdmlsh(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqrdmlshA2(CodeGenContext context, uint encoding) + { + InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.VqrdmlshS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqrdmlshT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqrdmlsh(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqrdmlshT2(CodeGenContext context, uint encoding) + { + InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.VqrdmlshS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqrdmulhA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqrdmulh(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqrdmulhA2(CodeGenContext context, uint encoding) + { + InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.VqrdmulhS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqrdmulhT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqrdmulh(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqrdmulhT2(CodeGenContext context, uint encoding) + { + InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.VqrdmulhS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqrshlA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqrshl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqrshlT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqrshl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VqrshrnA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Imm6b16w6Vdb12w4Opb8w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqrshrn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Op, inst.Imm6); + } + + public static void VqrshrnT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Imm6b16w6Vdb12w4Opb8w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqrshrn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Op, inst.Imm6); + } + + public static void VqshlIA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Imm6b16w6Vdb12w4Opb8w1Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.VqshlI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Op, inst.L, inst.Imm6, inst.Q); + } + + public static void VqshlIT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Imm6b16w6Vdb12w4Opb8w1Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.VqshlI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Op, inst.L, inst.Imm6, inst.Q); + } + + public static void VqshlRA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.VqshlR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VqshlRT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.VqshlR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VqshrnA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Imm6b16w6Vdb12w4Opb8w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqshrn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Op, inst.Imm6); + } + + public static void VqshrnT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Imm6b16w6Vdb12w4Opb8w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqshrn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Op, inst.Imm6); + } + + public static void VqsubA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqsub(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VqsubT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonSaturate.Vqsub(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VraddhnA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vraddhn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VraddhnT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vraddhn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VrecpeA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Fb8w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vrecpe(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VrecpeT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Fb8w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vrecpe(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VrecpsA1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vrecps(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VrecpsT1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vrecps(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void Vrev16A1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonBit.Vrev16(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void Vrev16T1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonBit.Vrev16(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void Vrev32A1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonBit.Vrev32(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void Vrev32T1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonBit.Vrev32(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void Vrev64A1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonBit.Vrev64(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void Vrev64T1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonBit.Vrev64(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VrhaddA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrhadd(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VrhaddT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrhadd(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VrintaAsimdA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrinta(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VrintaAsimdT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrinta(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VrintaVfpA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpRound.Vrinta(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VrintaVfpT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpRound.Vrinta(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VrintmAsimdA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrintm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VrintmAsimdT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrintm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VrintmVfpA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpRound.Vrintm(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VrintmVfpT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpRound.Vrintm(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VrintnAsimdA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrintn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VrintnAsimdT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrintn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VrintnVfpA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpRound.Vrintn(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VrintnVfpT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpRound.Vrintn(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VrintpAsimdA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrintp(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VrintpAsimdT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrintp(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VrintpVfpA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpRound.Vrintp(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VrintpVfpT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpRound.Vrintp(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VrintrVfpA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpRound.Vrintr(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VrintrVfpT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpRound.Vrintr(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VrintxAsimdA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrintx(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VrintxAsimdT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrintx(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VrintxVfpA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpRound.Vrintx(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VrintxVfpT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpRound.Vrintx(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VrintzAsimdA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrintz(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VrintzAsimdT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrintz(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VrintzVfpA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpRound.Vrintz(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VrintzVfpT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpRound.Vrintz(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VrshlA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrshl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VrshlT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrshl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VrshrA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrshr(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.L, inst.Imm6, inst.Q); + } + + public static void VrshrT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrshr(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.L, inst.Imm6, inst.Q); + } + + public static void VrshrnA1(CodeGenContext context, uint encoding) + { + InstDb22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrshrn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm6); + } + + public static void VrshrnT1(CodeGenContext context, uint encoding) + { + InstDb22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrshrn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm6); + } + + public static void VrsqrteA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Fb8w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vrsqrte(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VrsqrteT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Fb8w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vrsqrte(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q); + } + + public static void VrsqrtsA1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vrsqrts(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VrsqrtsT1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vrsqrts(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VrsraA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrsra(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.L, inst.Imm6, inst.Q); + } + + public static void VrsraT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrsra(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.L, inst.Imm6, inst.Q); + } + + public static void VrsubhnA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrsubhn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VrsubhnT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonRound.Vrsubhn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VsdotA1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VsdotT1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VsdotSA1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VsdotST1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VselA1(CodeGenContext context, uint encoding) + { + InstDb22w1Ccb20w2Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpMove.Vsel(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Cc, inst.Size); + } + + public static void VselT1(CodeGenContext context, uint encoding) + { + InstDb22w1Ccb20w2Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpMove.Vsel(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Cc, inst.Size); + } + + public static void VshllA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonShift.Vshll(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm6, inst.U != 0); + } + + public static void VshllA2(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonShift.Vshll2(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VshllT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonShift.Vshll(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm6, inst.U != 0); + } + + public static void VshllT2(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonShift.Vshll2(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VshlIA1(CodeGenContext context, uint encoding) + { + InstDb22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonShift.VshlI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.L, inst.Imm6, inst.Q); + } + + public static void VshlIT1(CodeGenContext context, uint encoding) + { + InstDb22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonShift.VshlI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.L, inst.Imm6, inst.Q); + } + + public static void VshlRA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonShift.VshlR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VshlRT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonShift.VshlR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q); + } + + public static void VshrA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonShift.Vshr(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.L, inst.Imm6, inst.Q); + } + + public static void VshrT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonShift.Vshr(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.L, inst.Imm6, inst.Q); + } + + public static void VshrnA1(CodeGenContext context, uint encoding) + { + InstDb22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonShift.Vshrn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm6); + } + + public static void VshrnT1(CodeGenContext context, uint encoding) + { + InstDb22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonShift.Vshrn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm6); + } + + public static void VsliA1(CodeGenContext context, uint encoding) + { + InstDb22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonShift.Vsli(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.L, inst.Imm6, inst.Q); + } + + public static void VsliT1(CodeGenContext context, uint encoding) + { + InstDb22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonShift.Vsli(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.L, inst.Imm6, inst.Q); + } + + public static void VsmmlaA1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VsmmlaT1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VsqrtA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VsqrtF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VsqrtT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VsqrtF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VsraA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonShift.Vsra(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.L, inst.Imm6, inst.Q); + } + + public static void VsraT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonShift.Vsra(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.L, inst.Imm6, inst.Q); + } + + public static void VsriA1(CodeGenContext context, uint encoding) + { + InstDb22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonShift.Vsri(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.L, inst.Imm6, inst.Q); + } + + public static void VsriT1(CodeGenContext context, uint encoding) + { + InstDb22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonShift.Vsri(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.L, inst.Imm6, inst.Q); + } + + public static void Vst11A1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0); + } + + public static void Vst11A2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1); + } + + public static void Vst11A3(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2); + } + + public static void Vst11T1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0); + } + + public static void Vst11T2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1); + } + + public static void Vst11T3(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2); + } + + public static void Vst1MA1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 1, inst.Align, inst.Size); + } + + public static void Vst1MA2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 2, inst.Align, inst.Size); + } + + public static void Vst1MA3(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 3, inst.Align, inst.Size); + } + + public static void Vst1MA4(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 4, inst.Align, inst.Size); + } + + public static void Vst1MT1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 1, inst.Align, inst.Size); + } + + public static void Vst1MT2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 2, inst.Align, inst.Size); + } + + public static void Vst1MT3(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 3, inst.Align, inst.Size); + } + + public static void Vst1MT4(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 4, inst.Align, inst.Size); + } + + public static void Vst21A1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0); + } + + public static void Vst21A2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1); + } + + public static void Vst21A3(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2); + } + + public static void Vst21T1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0); + } + + public static void Vst21T2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1); + } + + public static void Vst21T3(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2); + } + + public static void Vst2MA1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst2M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size); + } + + public static void Vst2MA2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst2M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.Align, inst.Size); + } + + public static void Vst2MT1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst2M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size); + } + + public static void Vst2MT2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst2M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.Align, inst.Size); + } + + public static void Vst31A1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0); + } + + public static void Vst31A2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1); + } + + public static void Vst31A3(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2); + } + + public static void Vst31T1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0); + } + + public static void Vst31T2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1); + } + + public static void Vst31T3(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2); + } + + public static void Vst3MA1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst3M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size); + } + + public static void Vst3MT1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst3M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size); + } + + public static void Vst41A1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0); + } + + public static void Vst41A2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1); + } + + public static void Vst41A3(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2); + } + + public static void Vst41T1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0); + } + + public static void Vst41T2(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1); + } + + public static void Vst41T3(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2); + } + + public static void Vst4MA1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst4M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size); + } + + public static void Vst4MT1(CodeGenContext context, uint encoding) + { + InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding); + + InstEmitNeonMemory.Vst4M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size); + } + + public static void VstmA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7 inst = new(encoding); + + InstEmitNeonMemory.Vstm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Imm871, inst.U != 0, inst.W != 0, singleRegs: false); + } + + public static void VstmA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Pb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm8b0w8 inst = new(encoding); + + InstEmitNeonMemory.Vstm(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), inst.Rn, inst.Imm8, inst.U != 0, inst.W != 0, singleRegs: true); + } + + public static void VstmT1(CodeGenContext context, uint encoding) + { + InstPb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7 inst = new(encoding); + + InstEmitNeonMemory.Vstm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Imm871, inst.U != 0, inst.W != 0, singleRegs: false); + } + + public static void VstmT2(CodeGenContext context, uint encoding) + { + InstPb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm8b0w8 inst = new(encoding); + + InstEmitNeonMemory.Vstm(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), inst.Rn, inst.Imm8, inst.U != 0, inst.W != 0, singleRegs: true); + } + + public static void VstrA1(CodeGenContext context, uint encoding) + { + InstCondb28w4Ub23w1Db22w1Rnb16w4Vdb12w4Sizeb8w2Imm8b0w8 inst = new(encoding); + + InstEmitNeonMemory.Vstr(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), inst.Rn, inst.Imm8, inst.U != 0, inst.Size); + } + + public static void VstrT1(CodeGenContext context, uint encoding) + { + InstUb23w1Db22w1Rnb16w4Vdb12w4Sizeb8w2Imm8b0w8 inst = new(encoding); + + InstEmitNeonMemory.Vstr(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), inst.Rn, inst.Imm8, inst.U != 0, inst.Size); + } + + public static void VsubhnA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vsubhn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VsubhnT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vsubhn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size); + } + + public static void VsublA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vsubl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VsublT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vsubl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VsubwA1(CodeGenContext context, uint encoding) + { + InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vsubw(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VsubwT1(CodeGenContext context, uint encoding) + { + InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.Vsubw(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size); + } + + public static void VsubFA1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VsubF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VsubFA2(CodeGenContext context, uint encoding) + { + InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VsubF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VsubFT1(CodeGenContext context, uint encoding) + { + InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VsubF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q); + } + + public static void VsubFT2(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitVfpArithmetic.VsubF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size); + } + + public static void VsubIA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VsubI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VsubIT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonArithmetic.VsubI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VsudotSA1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VsudotST1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VswpA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.Vswp(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void VswpT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.Vswp(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q); + } + + public static void VtblA1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Lenb8w2Nb7w1Opb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.Vtbl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Len); + } + + public static void VtblT1(CodeGenContext context, uint encoding) + { + InstDb22w1Vnb16w4Vdb12w4Lenb8w2Nb7w1Opb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.Vtbl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Len); + } + + public static void VtrnA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.Vtrn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VtrnT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.Vtrn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VtstA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.Vtst(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VtstT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonCompare.Vtst(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VudotA1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VudotT1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VudotSA1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VudotST1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VummlaA1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VummlaT1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VusdotA1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VusdotT1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VusdotSA1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VusdotST1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VusmmlaA1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VusmmlaT1(CodeGenContext context, uint encoding) + { + _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(encoding); + + throw new NotImplementedException(); + } + + public static void VuzpA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.Vuzp(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VuzpT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.Vuzp(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VzipA1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.Vzip(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void VzipT1(CodeGenContext context, uint encoding) + { + InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding); + + InstEmitNeonMove.Vzip(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q); + } + + public static void WfeA1(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Wfe(); + } + + public static void WfeT1(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Wfe(); + } + + public static void WfeT2(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Wfe(); + } + + public static void WfiA1(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Wfi(); + } + + public static void WfiT1(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Wfi(); + } + + public static void WfiT2(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Wfi(); + } + + public static void YieldA1(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Yield(); + } + + public static void YieldT1(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Yield(); + } + + public static void YieldT2(CodeGenContext context, uint encoding) + { + context.Arm64Assembler.Yield(); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitAbsDiff.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitAbsDiff.cs new file mode 100644 index 000000000..f8100503d --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitAbsDiff.cs @@ -0,0 +1,87 @@ +using Ryujinx.Cpu.LightningJit.CodeGen; +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitAbsDiff + { + public static void Usad8(CodeGenContext context, uint rd, uint rn, uint rm) + { + using ScopedRegister tempD = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempD2 = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + for (int b = 0; b < 4; b++) + { + context.Arm64Assembler.Ubfx(tempN.Operand, rnOperand, b * 8, 8); + context.Arm64Assembler.Ubfx(tempM.Operand, rmOperand, b * 8, 8); + + Operand dest = b == 0 ? tempD.Operand : tempD2.Operand; + + context.Arm64Assembler.Sub(dest, tempN.Operand, tempM.Operand); + + EmitAbs(context, dest); + + if (b > 0) + { + if (b < 3) + { + context.Arm64Assembler.Add(tempD.Operand, tempD.Operand, dest); + } + else + { + context.Arm64Assembler.Add(rdOperand, tempD.Operand, dest); + } + } + } + } + + public static void Usada8(CodeGenContext context, uint rd, uint rn, uint rm, uint ra) + { + using ScopedRegister tempD = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempD2 = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + Operand raOperand = InstEmitCommon.GetInputGpr(context, ra); + + for (int b = 0; b < 4; b++) + { + context.Arm64Assembler.Ubfx(tempN.Operand, rnOperand, b * 8, 8); + context.Arm64Assembler.Ubfx(tempM.Operand, rmOperand, b * 8, 8); + + Operand dest = b == 0 ? tempD.Operand : tempD2.Operand; + + context.Arm64Assembler.Sub(dest, tempN.Operand, tempM.Operand); + + EmitAbs(context, dest); + + if (b > 0) + { + context.Arm64Assembler.Add(tempD.Operand, tempD.Operand, dest); + } + } + + context.Arm64Assembler.Add(rdOperand, tempD.Operand, raOperand); + } + + private static void EmitAbs(CodeGenContext context, Operand value) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + // r = (value + ((int)value >> 31)) ^ ((int)value >> 31). + // Subtracts 1 and then inverts the value if the sign bit is set, same as a conditional negation. + + context.Arm64Assembler.Add(tempRegister.Operand, value, value, ArmShiftType.Asr, 31); + context.Arm64Assembler.Eor(value, tempRegister.Operand, value, ArmShiftType.Asr, 31); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitAlu.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitAlu.cs new file mode 100644 index 000000000..c0762819e --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitAlu.cs @@ -0,0 +1,1105 @@ +using Ryujinx.Cpu.LightningJit.CodeGen; +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; +using System; +using System.Diagnostics; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitAlu + { + private const uint Imm12Limit = 0x1000; + + public static void AdcI(CodeGenContext context, uint rd, uint rn, uint imm, bool s) + { + EmitI(context, s ? context.Arm64Assembler.Adcs : context.Arm64Assembler.Adc, rd, rn, imm, s); + } + + public static void AdcR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s) + { + EmitR(context, s ? context.Arm64Assembler.Adcs : context.Arm64Assembler.Adc, rd, rn, rm, sType, imm5, s); + } + + public static void AdcRr(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint rs, bool s) + { + EmitRr(context, s ? context.Arm64Assembler.Adcs : context.Arm64Assembler.Adc, rd, rn, rm, sType, rs, s); + } + + public static void AddI(CodeGenContext context, uint rd, uint rn, uint imm, bool s) + { + EmitArithmeticI(context, s ? context.Arm64Assembler.Adds : context.Arm64Assembler.Add, rd, rn, imm, s); + } + + public static void AddR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s) + { + EmitArithmeticR(context, s ? context.Arm64Assembler.Adds : context.Arm64Assembler.Add, rd, rn, rm, sType, imm5, s); + } + + public static void AddRr(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint rs, bool s) + { + EmitRr(context, s ? context.Arm64Assembler.Adds : context.Arm64Assembler.Add, rd, rn, rm, sType, rs, s); + } + + public static void Adr(CodeGenContext context, uint rd, uint imm, bool add) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + + uint pc = context.Pc & ~3u; + + if (add) + { + pc += imm; + } + else + { + pc -= imm; + } + + context.Arm64Assembler.Mov(rdOperand, pc); + } + + public static void AndI(CodeGenContext context, uint rd, uint rn, uint imm, bool immRotated, bool s) + { + EmitLogicalI(context, s ? context.Arm64Assembler.Ands : context.Arm64Assembler.And, rd, rn, imm, immRotated, s); + } + + public static void AndR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s) + { + EmitLogicalR(context, s ? context.Arm64Assembler.Ands : context.Arm64Assembler.And, rd, rn, rm, sType, imm5, s); + } + + public static void AndRr(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint rs, bool s) + { + EmitLogicalRr(context, s ? context.Arm64Assembler.Ands : context.Arm64Assembler.And, rd, rn, rm, sType, rs, s); + } + + public static void BicI(CodeGenContext context, uint rd, uint rn, uint imm, bool immRotated, bool s) + { + if (!s && CodeGenCommon.TryEncodeBitMask(OperandType.I32, ~imm, out _, out _, out _)) + { + AndI(context, rd, rn, ~imm, immRotated, s); + } + else + { + EmitLogicalI(context, s ? context.Arm64Assembler.Bics : context.Arm64Assembler.Bic, rd, rn, imm, immRotated, s, immForm: false); + } + } + + public static void BicR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s) + { + EmitLogicalR(context, s ? context.Arm64Assembler.Bics : context.Arm64Assembler.Bic, rd, rn, rm, sType, imm5, s); + } + + public static void BicRr(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint rs, bool s) + { + EmitLogicalRr(context, s ? context.Arm64Assembler.Bics : context.Arm64Assembler.Bic, rd, rn, rm, sType, rs, s); + } + + public static void CmnI(CodeGenContext context, uint rn, uint imm) + { + EmitCompareI(context, context.Arm64Assembler.Cmn, rn, imm); + } + + public static void CmnR(CodeGenContext context, uint rn, uint rm, uint sType, uint imm5) + { + EmitCompareR(context, context.Arm64Assembler.Cmn, rn, rm, sType, imm5); + } + + public static void CmnRr(CodeGenContext context, uint rn, uint rm, uint sType, uint rs) + { + EmitCompareRr(context, context.Arm64Assembler.Cmn, rn, rm, sType, rs); + } + + public static void CmpI(CodeGenContext context, uint rn, uint imm) + { + EmitCompareI(context, context.Arm64Assembler.Cmp, rn, imm); + } + + public static void CmpR(CodeGenContext context, uint rn, uint rm, uint sType, uint imm5) + { + EmitCompareR(context, context.Arm64Assembler.Cmp, rn, rm, sType, imm5); + } + + public static void CmpRr(CodeGenContext context, uint rn, uint rm, uint sType, uint rs) + { + EmitCompareRr(context, context.Arm64Assembler.Cmp, rn, rm, sType, rs); + } + + public static void EorI(CodeGenContext context, uint rd, uint rn, uint imm, bool immRotated, bool s) + { + EmitLogicalI(context, s ? context.Arm64Assembler.Eors : context.Arm64Assembler.Eor, rd, rn, imm, immRotated, s); + } + + public static void EorR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s) + { + EmitLogicalR(context, s ? context.Arm64Assembler.Eors : context.Arm64Assembler.Eor, rd, rn, rm, sType, imm5, s); + } + + public static void EorRr(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint rs, bool s) + { + EmitLogicalRr(context, s ? context.Arm64Assembler.Eors : context.Arm64Assembler.Eor, rd, rn, rm, sType, rs, s); + } + + public static void OrnI(CodeGenContext context, uint rd, uint rn, uint imm, bool immRotated, bool s) + { + if (!s && CodeGenCommon.TryEncodeBitMask(OperandType.I32, ~imm, out _, out _, out _)) + { + OrrI(context, rd, rn, ~imm, immRotated, s); + } + else + { + EmitLogicalI(context, s ? context.Arm64Assembler.Orns : context.Arm64Assembler.Orn, rd, rn, imm, immRotated, s, immForm: false); + } + } + + public static void OrnR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s) + { + EmitLogicalR(context, s ? context.Arm64Assembler.Orns : context.Arm64Assembler.Orn, rd, rn, rm, sType, imm5, s); + } + + public static void OrrI(CodeGenContext context, uint rd, uint rn, uint imm, bool immRotated, bool s) + { + EmitLogicalI(context, s ? context.Arm64Assembler.Orrs : context.Arm64Assembler.Orr, rd, rn, imm, immRotated, s); + } + + public static void OrrR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s) + { + EmitLogicalR(context, s ? context.Arm64Assembler.Orrs : context.Arm64Assembler.Orr, rd, rn, rm, sType, imm5, s); + } + + public static void OrrRr(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint rs, bool s) + { + EmitLogicalRr(context, s ? context.Arm64Assembler.Orrs : context.Arm64Assembler.Orr, rd, rn, rm, sType, rs, s); + } + + public static void RsbI(CodeGenContext context, uint rd, uint rn, uint imm, bool s) + { + if (imm == 0) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + + if (s) + { + context.Arm64Assembler.Negs(rdOperand, rnOperand); + context.SetNzcvModified(); + } + else + { + context.Arm64Assembler.Neg(rdOperand, rnOperand); + } + } + else + { + EmitI(context, s ? context.Arm64Assembler.Subs : context.Arm64Assembler.Sub, rd, rn, imm, s, reverse: true); + } + } + + public static void RsbR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s) + { + EmitR(context, s ? context.Arm64Assembler.Subs : context.Arm64Assembler.Sub, rd, rn, rm, sType, imm5, s, reverse: true); + } + + public static void RsbRr(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint rs, bool s) + { + EmitRr(context, s ? context.Arm64Assembler.Subs : context.Arm64Assembler.Sub, rd, rn, rm, sType, rs, s, reverse: true); + } + + public static void RscI(CodeGenContext context, uint rd, uint rn, uint imm, bool s) + { + EmitI(context, s ? context.Arm64Assembler.Sbcs : context.Arm64Assembler.Sbc, rd, rn, imm, s, reverse: true); + } + + public static void RscR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s) + { + EmitR(context, s ? context.Arm64Assembler.Sbcs : context.Arm64Assembler.Sbc, rd, rn, rm, sType, imm5, s, reverse: true); + } + + public static void RscRr(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint rs, bool s) + { + EmitRr(context, s ? context.Arm64Assembler.Sbcs : context.Arm64Assembler.Sbc, rd, rn, rm, sType, rs, s, reverse: true); + } + + public static void SbcI(CodeGenContext context, uint rd, uint rn, uint imm, bool s) + { + EmitI(context, s ? context.Arm64Assembler.Sbcs : context.Arm64Assembler.Sbc, rd, rn, imm, s); + } + + public static void SbcR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s) + { + EmitR(context, s ? context.Arm64Assembler.Sbcs : context.Arm64Assembler.Sbc, rd, rn, rm, sType, imm5, s); + } + + public static void SbcRr(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint rs, bool s) + { + EmitRr(context, s ? context.Arm64Assembler.Sbcs : context.Arm64Assembler.Sbc, rd, rn, rm, sType, rs, s); + } + + public static void SubI(CodeGenContext context, uint rd, uint rn, uint imm, bool s) + { + EmitArithmeticI(context, s ? context.Arm64Assembler.Subs : context.Arm64Assembler.Sub, rd, rn, imm, s); + } + + public static void SubR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s) + { + EmitArithmeticR(context, s ? context.Arm64Assembler.Subs : context.Arm64Assembler.Sub, rd, rn, rm, sType, imm5, s); + } + + public static void SubRr(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint rs, bool s) + { + EmitRr(context, s ? context.Arm64Assembler.Subs : context.Arm64Assembler.Sub, rd, rn, rm, sType, rs, s); + } + + public static void TeqI(CodeGenContext context, uint rn, uint imm, bool immRotated) + { + EmitLogicalI(context, (rnOperand, rmOperand) => EmitTeq(context, rnOperand, rmOperand), rn, imm, immRotated); + } + + public static void TeqR(CodeGenContext context, uint rn, uint rm, uint sType, uint imm5) + { + EmitLogicalR(context, (rnOperand, rmOperand) => EmitTeq(context, rnOperand, rmOperand), rn, rm, sType, imm5); + } + + public static void TeqRr(CodeGenContext context, uint rn, uint rm, uint sType, uint rs) + { + EmitLogicalRr(context, (rnOperand, rmOperand) => EmitTeq(context, rnOperand, rmOperand), rn, rm, sType, rs); + } + + public static void TstI(CodeGenContext context, uint rn, uint imm, bool immRotated) + { + EmitLogicalI(context, context.Arm64Assembler.Tst, rn, imm, immRotated); + } + + public static void TstR(CodeGenContext context, uint rn, uint rm, uint sType, uint imm5) + { + EmitLogicalR(context, context.Arm64Assembler.Tst, rn, rm, sType, imm5); + } + + public static void TstRr(CodeGenContext context, uint rn, uint rm, uint sType, uint rs) + { + EmitLogicalRr(context, context.Arm64Assembler.Tst, rn, rm, sType, rs); + } + + private static void EmitArithmeticI(CodeGenContext context, Action action, uint rd, uint rn, uint imm, bool s) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + + if (imm < Imm12Limit) + { + Operand rmOperand = new(OperandKind.Constant, OperandType.I32, imm); + + action(rdOperand, rnOperand, rmOperand); + } + else + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Mov(tempRegister.Operand, imm); + + action(rdOperand, rnOperand, tempRegister.Operand); + } + + if (s) + { + context.SetNzcvModified(); + } + } + + private static void EmitArithmeticR( + CodeGenContext context, + Action action, + uint rd, + uint rn, + uint rm, + uint sType, + uint imm5, + bool s) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + if (CanShiftArithmetic(sType, imm5)) + { + action(rdOperand, rnOperand, rmOperand, (ArmShiftType)sType, (int)imm5); + } + else + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + rmOperand = GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType); + + action(rdOperand, rnOperand, rmOperand, ArmShiftType.Lsl, 0); + } + + if (s) + { + context.SetNzcvModified(); + } + } + + private static void EmitCompareI(CodeGenContext context, Action action, uint rn, uint imm) + { + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + + if (imm < Imm12Limit) + { + Operand rmOperand = new(OperandKind.Constant, OperandType.I32, imm); + + action(rnOperand, rmOperand); + } + else + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Mov(tempRegister.Operand, imm); + + action(rnOperand, tempRegister.Operand); + } + + context.SetNzcvModified(); + } + + private static void EmitCompareR( + CodeGenContext context, + Action action, + uint rn, + uint rm, + uint sType, + uint imm5) + { + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + if (CanShiftArithmetic(sType, imm5)) + { + action(rnOperand, rmOperand, (ArmShiftType)sType, (int)imm5); + } + else + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + rmOperand = GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType); + + action(rnOperand, rmOperand, ArmShiftType.Lsl, 0); + } + + context.SetNzcvModified(); + } + + private static void EmitCompareRr(CodeGenContext context, Action action, uint rn, uint rm, uint sType, uint rs) + { + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + Operand rsOperand = InstEmitCommon.GetInputGpr(context, rs); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + rmOperand = GetMShiftedByReg(context, tempRegister.Operand, rmOperand, rsOperand, sType); + + action(rnOperand, rmOperand); + + context.SetNzcvModified(); + } + + private static void EmitI(CodeGenContext context, Action action, uint rd, uint rn, uint imm, bool s, bool reverse = false) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Mov(tempRegister.Operand, imm); + + if (reverse) + { + action(rdOperand, tempRegister.Operand, rnOperand); + } + else + { + action(rdOperand, rnOperand, tempRegister.Operand); + } + + if (s) + { + context.SetNzcvModified(); + } + } + + private static void EmitR(CodeGenContext context, Action action, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s, bool reverse = false) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + rmOperand = GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType); + + if (reverse) + { + action(rdOperand, rmOperand, rnOperand); + } + else + { + action(rdOperand, rnOperand, rmOperand); + } + + if (s) + { + context.SetNzcvModified(); + } + } + + private static void EmitRr(CodeGenContext context, Action action, uint rd, uint rn, uint rm, uint sType, uint rs, bool s, bool reverse = false) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + Operand rsOperand = InstEmitCommon.GetInputGpr(context, rs); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + rmOperand = GetMShiftedByReg(context, tempRegister.Operand, rmOperand, rsOperand, sType); + + if (reverse) + { + action(rdOperand, rmOperand, rnOperand); + } + else + { + action(rdOperand, rnOperand, rmOperand); + } + + if (s) + { + context.SetNzcvModified(); + } + } + + private static void EmitLogicalI(CodeGenContext context, Action action, uint rn, uint imm, bool immRotated) + { + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + + using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand); + + if (immRotated) + { + if ((imm & (1u << 31)) != 0) + { + context.Arm64Assembler.Orr(flagsRegister.Operand, flagsRegister.Operand, InstEmitCommon.Const(2)); + } + else + { + context.Arm64Assembler.Bfc(flagsRegister.Operand, 1, 1); + } + } + + if (CodeGenCommon.TryEncodeBitMask(OperandType.I32, imm, out _, out _, out _)) + { + action(rnOperand, InstEmitCommon.Const((int)imm)); + } + else + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Mov(tempRegister.Operand, imm); + + action(rnOperand, tempRegister.Operand); + } + + InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand); + + context.SetNzcvModified(); + } + + private static void EmitLogicalI( + CodeGenContext context, + Action action, + uint rd, + uint rn, + uint imm, + bool immRotated, + bool s, + bool immForm = true) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + + ScopedRegister flagsRegister = default; + + if (s) + { + flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand); + + if (immRotated) + { + if ((imm & (1u << 31)) != 0) + { + context.Arm64Assembler.Orr(flagsRegister.Operand, flagsRegister.Operand, InstEmitCommon.Const(2)); + } + else + { + context.Arm64Assembler.Bfc(flagsRegister.Operand, 1, 1); + } + } + } + + if (imm == 0 || (immForm && CodeGenCommon.TryEncodeBitMask(OperandType.I32, imm, out _, out _, out _))) + { + action(rdOperand, rnOperand, InstEmitCommon.Const((int)imm)); + } + else + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Mov(tempRegister.Operand, imm); + + action(rdOperand, rnOperand, tempRegister.Operand); + } + + if (s) + { + InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand); + + flagsRegister.Dispose(); + + context.SetNzcvModified(); + } + } + + private static void EmitLogicalR(CodeGenContext context, Action action, uint rn, uint rm, uint sType, uint imm5) + { + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand); + + rmOperand = GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType, flagsRegister.Operand); + + action(rnOperand, rmOperand); + + InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand); + + context.SetNzcvModified(); + } + + private static void EmitLogicalR(CodeGenContext context, Action action, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + if (CanShift(sType, imm5) && !s) + { + action(rdOperand, rnOperand, rmOperand, (ArmShiftType)sType, (int)imm5); + } + else + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + ScopedRegister flagsRegister = default; + + if (s) + { + flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand); + + rmOperand = GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType, flagsRegister.Operand); + } + else + { + rmOperand = GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType, null); + } + + action(rdOperand, rnOperand, rmOperand, ArmShiftType.Lsl, 0); + + if (s) + { + InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand); + + flagsRegister.Dispose(); + + context.SetNzcvModified(); + } + } + } + + private static void EmitLogicalRr(CodeGenContext context, Action action, uint rn, uint rm, uint sType, uint rs) + { + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + Operand rsOperand = InstEmitCommon.GetInputGpr(context, rs); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand); + + rmOperand = GetMShiftedByReg(context, tempRegister.Operand, rmOperand, rsOperand, sType, flagsRegister.Operand); + + action(rnOperand, rmOperand); + + InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand); + + context.SetNzcvModified(); + } + + private static void EmitLogicalRr(CodeGenContext context, Action action, uint rd, uint rn, uint rm, uint sType, uint rs, bool s) + { + if (s) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + Operand rsOperand = InstEmitCommon.GetInputGpr(context, rs); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand); + + rmOperand = GetMShiftedByReg(context, tempRegister.Operand, rmOperand, rsOperand, sType, flagsRegister.Operand); + + action(rdOperand, rnOperand, rmOperand); + + InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand); + + context.SetNzcvModified(); + } + else + { + EmitRr(context, action, rd, rn, rm, sType, rs, s); + } + } + + public static bool CanShiftArithmetic(uint sType, uint imm5) + { + // We can't encode ROR or RRX. + + return sType != 3 && (sType == 0 || imm5 != 0); + } + + public static bool CanShift(uint sType, uint imm5) + { + // We can encode all shift types directly, except RRX. + + return imm5 != 0 || sType == 0; + } + + public static Operand GetMShiftedByImmediate(CodeGenContext context, Operand dest, Operand m, uint imm, uint sType, Operand? carryOut = null) + { + int shift = (int)imm; + + if (shift == 0) + { + switch ((ArmShiftType)sType) + { + case ArmShiftType.Lsr: + shift = 32; + break; + case ArmShiftType.Asr: + shift = 32; + break; + case ArmShiftType.Ror: + shift = 1; + break; + } + } + + if (shift != 0) + { + switch ((ArmShiftType)sType) + { + case ArmShiftType.Lsl: + m = GetLslC(context, dest, m, carryOut, shift); + break; + case ArmShiftType.Lsr: + m = GetLsrC(context, dest, m, carryOut, shift); + break; + case ArmShiftType.Asr: + m = GetAsrC(context, dest, m, carryOut, shift); + break; + case ArmShiftType.Ror: + if (imm != 0) + { + m = GetRorC(context, dest, m, carryOut, shift); + } + else + { + m = GetRrxC(context, dest, m, carryOut); + } + break; + } + } + + return m; + } + + public static Operand GetMShiftedByReg(CodeGenContext context, Operand dest, Operand m, Operand s, uint sType, Operand? carryOut = null) + { + Operand shiftResult = m; + + switch ((ArmShiftType)sType) + { + case ArmShiftType.Lsl: + shiftResult = EmitLslC(context, dest, m, carryOut, s); + break; + case ArmShiftType.Lsr: + shiftResult = EmitLsrC(context, dest, m, carryOut, s); + break; + case ArmShiftType.Asr: + shiftResult = EmitAsrC(context, dest, m, carryOut, s); + break; + case ArmShiftType.Ror: + shiftResult = EmitRorC(context, dest, m, carryOut, s); + break; + } + + return shiftResult; + } + + private static void EmitIfHelper(CodeGenContext context, Operand boolValue, Action action, bool expected = true) + { + Debug.Assert(boolValue.Type == OperandType.I32); + + int branchInstructionPointer = context.CodeWriter.InstructionPointer; + + if (expected) + { + context.Arm64Assembler.Cbnz(boolValue, 0); + } + else + { + context.Arm64Assembler.Cbz(boolValue, 0); + } + + action(); + + int offset = context.CodeWriter.InstructionPointer - branchInstructionPointer; + Debug.Assert(offset >= 0); + Debug.Assert((offset << 13) >> 13 == offset); + uint branchInst = context.CodeWriter.ReadInstructionAt(branchInstructionPointer); + context.CodeWriter.WriteInstructionAt(branchInstructionPointer, branchInst | (uint)(offset << 5)); + } + + private static Operand EmitLslC(CodeGenContext context, Operand dest, Operand m, Operand? carryOut, Operand shift) + { + Debug.Assert(m.Type == OperandType.I32 && shift.Type == OperandType.I32); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand mask = tempRegister.Operand; + context.Arm64Assembler.Uxtb(mask, shift); + context.Arm64Assembler.Sub(mask, mask, InstEmitCommon.Const(32)); + context.Arm64Assembler.Asr(mask, mask, InstEmitCommon.Const(31)); + + Operand dest64 = new(OperandKind.Register, OperandType.I64, dest.Value); + + if (carryOut.HasValue) + { + context.Arm64Assembler.Lslv(dest64, m, shift); + } + else + { + context.Arm64Assembler.Lslv(dest, m, shift); + } + + // If shift >= 32, force the result to 0. + context.Arm64Assembler.And(dest, dest, mask); + + if (carryOut.HasValue) + { + EmitIfHelper(context, shift, () => + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Uxtb(mask, shift); + context.Arm64Assembler.Sub(mask, mask, InstEmitCommon.Const(33)); + context.Arm64Assembler.Lsr(mask, mask, InstEmitCommon.Const(31)); + context.Arm64Assembler.Lsr(tempRegister.Operand, dest64, InstEmitCommon.Const(32)); + context.Arm64Assembler.And(tempRegister.Operand, tempRegister.Operand, mask); + + UpdateCarryFlag(context, tempRegister.Operand, carryOut.Value); + }, false); + } + + return dest; + } + + private static Operand GetLslC(CodeGenContext context, Operand dest, Operand m, Operand? carryOut, int shift) + { + Debug.Assert(m.Type == OperandType.I32); + + if ((uint)shift > 32) + { + return GetShiftByMoreThan32(context, carryOut); + } + else if (shift == 32) + { + if (carryOut.HasValue) + { + SetCarryMLsb(context, m, carryOut.Value); + } + + return InstEmitCommon.Const(0); + } + else + { + if (carryOut.HasValue) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Lsr(tempRegister.Operand, m, InstEmitCommon.Const(32 - shift)); + + UpdateCarryFlag(context, tempRegister.Operand, carryOut.Value); + } + + context.Arm64Assembler.Lsl(dest, m, InstEmitCommon.Const(shift)); + + return dest; + } + } + + private static Operand EmitLsrC(CodeGenContext context, Operand dest, Operand m, Operand? carryOut, Operand shift) + { + Debug.Assert(m.Type == OperandType.I32 && shift.Type == OperandType.I32); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand mask = tempRegister.Operand; + context.Arm64Assembler.Uxtb(mask, shift); + context.Arm64Assembler.Sub(mask, mask, InstEmitCommon.Const(32)); + context.Arm64Assembler.Asr(mask, mask, InstEmitCommon.Const(31)); + + context.Arm64Assembler.Lsrv(dest, m, shift); + + // If shift >= 32, force the result to 0. + context.Arm64Assembler.And(dest, dest, mask); + + if (carryOut.HasValue) + { + EmitIfHelper(context, shift, () => + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Uxtb(mask, shift); + context.Arm64Assembler.Sub(mask, mask, InstEmitCommon.Const(33)); + context.Arm64Assembler.Lsr(mask, mask, InstEmitCommon.Const(31)); + context.Arm64Assembler.Sub(tempRegister.Operand, shift, InstEmitCommon.Const(1)); + context.Arm64Assembler.Lsrv(tempRegister.Operand, m, tempRegister.Operand); + context.Arm64Assembler.And(tempRegister.Operand, tempRegister.Operand, mask); + + UpdateCarryFlag(context, tempRegister.Operand, carryOut.Value); + }, false); + } + + return dest; + } + + public static Operand GetLsrC(CodeGenContext context, Operand dest, Operand m, Operand? carryOut, int shift) + { + Debug.Assert(m.Type == OperandType.I32); + + if ((uint)shift > 32) + { + return GetShiftByMoreThan32(context, carryOut); + } + else if (shift == 32) + { + if (carryOut.HasValue) + { + SetCarryMMsb(context, m, carryOut.Value); + } + + return InstEmitCommon.Const(0); + } + else + { + if (carryOut.HasValue) + { + SetCarryMShrOut(context, m, shift, carryOut.Value); + } + + context.Arm64Assembler.Lsr(dest, m, InstEmitCommon.Const(shift)); + + return dest; + } + } + + private static Operand GetShiftByMoreThan32(CodeGenContext context, Operand? carryOut) + { + if (carryOut.HasValue) + { + // Clear carry flag. + + context.Arm64Assembler.Bfc(carryOut.Value, 1, 1); + } + + return InstEmitCommon.Const(0); + } + + private static Operand EmitAsrC(CodeGenContext context, Operand dest, Operand m, Operand? carryOut, Operand shift) + { + Debug.Assert(m.Type == OperandType.I32 && shift.Type == OperandType.I32); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand mask = tempRegister.Operand; + context.Arm64Assembler.Uxtb(mask, shift); + context.Arm64Assembler.Sub(mask, mask, InstEmitCommon.Const(31)); + context.Arm64Assembler.Orn(mask, shift, mask, ArmShiftType.Asr, 31); + + context.Arm64Assembler.Asrv(dest, m, mask); + + if (carryOut.HasValue) + { + EmitIfHelper(context, shift, () => + { + // If shift >= 32, carry should be equal to the MSB of Rm. + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Sub(tempRegister.Operand, mask, InstEmitCommon.Const(1)); + context.Arm64Assembler.Orr(tempRegister.Operand, tempRegister.Operand, mask, ArmShiftType.Asr, 31); + context.Arm64Assembler.Lsrv(tempRegister.Operand, m, tempRegister.Operand); + + UpdateCarryFlag(context, tempRegister.Operand, carryOut.Value); + }, false); + } + + return dest; + } + + private static Operand GetAsrC(CodeGenContext context, Operand dest, Operand m, Operand? carryOut, int shift) + { + Debug.Assert(m.Type == OperandType.I32); + + if ((uint)shift >= 32) + { + context.Arm64Assembler.Asr(dest, m, InstEmitCommon.Const(31)); + + if (carryOut.HasValue) + { + SetCarryMLsb(context, dest, carryOut.Value); + } + + return dest; + } + else + { + if (carryOut.HasValue) + { + SetCarryMShrOut(context, m, shift, carryOut.Value); + } + + context.Arm64Assembler.Asr(dest, m, InstEmitCommon.Const(shift)); + + return dest; + } + } + + private static Operand EmitRorC(CodeGenContext context, Operand dest, Operand m, Operand? carryOut, Operand shift) + { + Debug.Assert(m.Type == OperandType.I32 && shift.Type == OperandType.I32); + + context.Arm64Assembler.Rorv(dest, m, shift); + + if (carryOut.HasValue) + { + EmitIfHelper(context, shift, () => + { + SetCarryMMsb(context, m, carryOut.Value); + }, false); + } + + return dest; + } + + private static Operand GetRorC(CodeGenContext context, Operand dest, Operand m, Operand? carryOut, int shift) + { + Debug.Assert(m.Type == OperandType.I32); + + shift &= 0x1f; + + context.Arm64Assembler.Ror(dest, m, InstEmitCommon.Const(shift)); + + if (carryOut.HasValue) + { + SetCarryMMsb(context, dest, carryOut.Value); + } + + return dest; + } + + private static Operand GetRrxC(CodeGenContext context, Operand dest, Operand m, Operand? carryOut) + { + Debug.Assert(m.Type == OperandType.I32); + + // Rotate right by 1 with carry. + + if (carryOut.HasValue) + { + SetCarryMLsb(context, m, carryOut.Value); + } + + context.Arm64Assembler.Mov(dest, m); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.MrsNzcv(tempRegister.Operand); + context.Arm64Assembler.Bfxil(dest, tempRegister.Operand, 29, 1); + context.Arm64Assembler.Ror(dest, dest, InstEmitCommon.Const(1)); + + return dest; + } + + private static void SetCarryMLsb(CodeGenContext context, Operand m, Operand carryOut) + { + Debug.Assert(m.Type == OperandType.I32); + + UpdateCarryFlag(context, m, carryOut); + } + + private static void SetCarryMMsb(CodeGenContext context, Operand m, Operand carryOut) + { + Debug.Assert(m.Type == OperandType.I32); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Lsr(tempRegister.Operand, m, InstEmitCommon.Const(31)); + + UpdateCarryFlag(context, tempRegister.Operand, carryOut); + } + + private static void SetCarryMShrOut(CodeGenContext context, Operand m, int shift, Operand carryOut) + { + Debug.Assert(m.Type == OperandType.I32); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Lsr(tempRegister.Operand, m, InstEmitCommon.Const(shift - 1)); + + UpdateCarryFlag(context, tempRegister.Operand, carryOut); + } + + private static void UpdateCarryFlag(CodeGenContext context, Operand value, Operand carryOut) + { + context.Arm64Assembler.Bfi(carryOut, value, 1, 1); + } + + private static void EmitTeq(CodeGenContext context, Operand rnOperand, Operand rmOperand) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Eors(tempRegister.Operand, rnOperand, rmOperand); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitBit.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitBit.cs new file mode 100644 index 000000000..3f91d45f2 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitBit.cs @@ -0,0 +1,103 @@ +using Ryujinx.Cpu.LightningJit.CodeGen; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitBit + { + public static void Bfc(CodeGenContext context, uint rd, uint lsb, uint msb) + { + // This is documented as "unpredictable". + if (msb < lsb) + { + return; + } + + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + + context.Arm64Assembler.Bfc(rdOperand, (int)lsb, (int)(msb - lsb + 1)); + } + + public static void Bfi(CodeGenContext context, uint rd, uint rn, uint lsb, uint msb) + { + // This is documented as "unpredictable". + if (msb < lsb) + { + return; + } + + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + + context.Arm64Assembler.Bfi(rdOperand, rnOperand, (int)lsb, (int)(msb - lsb + 1)); + } + + public static void Clz(CodeGenContext context, uint rd, uint rm) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + context.Arm64Assembler.Clz(rdOperand, rmOperand); + } + + public static void Rbit(CodeGenContext context, uint rd, uint rm) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + context.Arm64Assembler.Rbit(rdOperand, rmOperand); + } + + public static void Rev(CodeGenContext context, uint rd, uint rm) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + context.Arm64Assembler.Rev(rdOperand, rmOperand); + } + + public static void Rev16(CodeGenContext context, uint rd, uint rm) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + context.Arm64Assembler.Rev16(rdOperand, rmOperand); + } + + public static void Revsh(CodeGenContext context, uint rd, uint rm) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + context.Arm64Assembler.Rev16(rdOperand, rmOperand); + context.Arm64Assembler.Sxth(rdOperand, rdOperand); + } + + public static void Sbfx(CodeGenContext context, uint rd, uint rn, uint lsb, uint widthMinus1) + { + // This is documented as "unpredictable". + if (lsb + widthMinus1 > 31) + { + return; + } + + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + + context.Arm64Assembler.Sbfx(rdOperand, rnOperand, (int)lsb, (int)widthMinus1 + 1); + } + + public static void Ubfx(CodeGenContext context, uint rd, uint rn, uint lsb, uint widthMinus1) + { + // This is documented as "unpredictable". + if (lsb + widthMinus1 > 31) + { + return; + } + + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + + context.Arm64Assembler.Ubfx(rdOperand, rnOperand, (int)lsb, (int)widthMinus1 + 1); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitCommon.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitCommon.cs new file mode 100644 index 000000000..1ec4c807e --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitCommon.cs @@ -0,0 +1,263 @@ +using Ryujinx.Cpu.LightningJit.CodeGen; +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; +using System; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitCommon + { + public static Operand Const(int value) + { + return new(OperandKind.Constant, OperandType.I32, (uint)value); + } + + public static Operand GetInputGpr(CodeGenContext context, uint register) + { + Operand operand = context.RegisterAllocator.RemapGprRegister((int)register); + + if (register == RegisterUtils.PcRegister) + { + context.Arm64Assembler.Mov(operand, context.Pc); + } + + return operand; + } + + public static Operand GetOutputGpr(CodeGenContext context, uint register) + { + return context.RegisterAllocator.RemapGprRegister((int)register); + } + + public static void GetCurrentFlags(CodeGenContext context, Operand flagsOut) + { + context.Arm64Assembler.MrsNzcv(flagsOut); + context.Arm64Assembler.Lsr(flagsOut, flagsOut, Const(28)); + } + + public static void RestoreNzcvFlags(CodeGenContext context, Operand nzcvFlags) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Lsl(tempRegister.Operand, nzcvFlags, Const(28)); + context.Arm64Assembler.MsrNzcv(tempRegister.Operand); + } + + public static void RestoreCvFlags(CodeGenContext context, Operand cvFlags) + { + // Arm64 zeros the carry and overflow flags for logical operations, but Arm32 keeps them unchanged. + // This will restore carry and overflow after a operation has zeroed them. + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.MrsNzcv(tempRegister.Operand); + context.Arm64Assembler.Bfi(tempRegister.Operand, cvFlags, 28, 2); + context.Arm64Assembler.MsrNzcv(tempRegister.Operand); + } + + public static void SetThumbFlag(CodeGenContext context) + { + Operand ctx = InstEmitSystem.Register(context.RegisterAllocator.FixedContextRegister); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.LdrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset); + context.Arm64Assembler.Orr(tempRegister.Operand, tempRegister.Operand, Const(1 << 5)); + context.Arm64Assembler.StrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset); + } + + public static void SetThumbFlag(CodeGenContext context, Operand value) + { + Operand ctx = InstEmitSystem.Register(context.RegisterAllocator.FixedContextRegister); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.LdrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset); + context.Arm64Assembler.Bfi(tempRegister.Operand, value, 5, 1); + context.Arm64Assembler.StrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset); + } + + public static void ClearThumbFlag(CodeGenContext context) + { + Operand ctx = InstEmitSystem.Register(context.RegisterAllocator.FixedContextRegister); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.LdrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset); + context.Arm64Assembler.Bfc(tempRegister.Operand, 5, 1); + context.Arm64Assembler.StrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset); + } + + public static void EmitSigned16BitPair(CodeGenContext context, uint rd, uint rn, Action elementAction) + { + using ScopedRegister tempD = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempD2 = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand rdOperand = GetOutputGpr(context, rd); + Operand rnOperand = GetInputGpr(context, rn); + + context.Arm64Assembler.Sxth(tempN.Operand, rnOperand); + elementAction(tempD.Operand, tempN.Operand); + context.Arm64Assembler.Uxth(tempD2.Operand, tempD.Operand); + + context.Arm64Assembler.Asr(tempN.Operand, rnOperand, Const(16)); + elementAction(tempD.Operand, tempN.Operand); + context.Arm64Assembler.Orr(rdOperand, tempD2.Operand, tempD.Operand, ArmShiftType.Lsl, 16); + } + + public static void EmitSigned16BitPair(CodeGenContext context, uint rd, uint rn, uint rm, Action elementAction) + { + using ScopedRegister tempD = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempD2 = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand rdOperand = GetOutputGpr(context, rd); + Operand rnOperand = GetInputGpr(context, rn); + Operand rmOperand = GetInputGpr(context, rm); + + context.Arm64Assembler.Sxth(tempN.Operand, rnOperand); + context.Arm64Assembler.Sxth(tempM.Operand, rmOperand); + elementAction(tempD.Operand, tempN.Operand, tempM.Operand); + context.Arm64Assembler.Uxth(tempD2.Operand, tempD.Operand); + + context.Arm64Assembler.Asr(tempN.Operand, rnOperand, Const(16)); + context.Arm64Assembler.Asr(tempM.Operand, rmOperand, Const(16)); + elementAction(tempD.Operand, tempN.Operand, tempM.Operand); + context.Arm64Assembler.Orr(rdOperand, tempD2.Operand, tempD.Operand, ArmShiftType.Lsl, 16); + } + + public static void EmitSigned16BitXPair(CodeGenContext context, uint rd, uint rn, uint rm, Action elementAction) + { + using ScopedRegister tempD = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempD2 = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand rdOperand = GetOutputGpr(context, rd); + Operand rnOperand = GetInputGpr(context, rn); + Operand rmOperand = GetInputGpr(context, rm); + + context.Arm64Assembler.Sxth(tempN.Operand, rnOperand); + context.Arm64Assembler.Asr(tempM.Operand, rmOperand, Const(16)); + elementAction(tempD.Operand, tempN.Operand, tempM.Operand, 0); + context.Arm64Assembler.Uxth(tempD2.Operand, tempD.Operand); + + context.Arm64Assembler.Asr(tempN.Operand, rnOperand, Const(16)); + context.Arm64Assembler.Sxth(tempM.Operand, rmOperand); + elementAction(tempD.Operand, tempN.Operand, tempM.Operand, 1); + context.Arm64Assembler.Orr(rdOperand, tempD2.Operand, tempD.Operand, ArmShiftType.Lsl, 16); + } + + public static void EmitSigned8BitPair(CodeGenContext context, uint rd, uint rn, uint rm, Action elementAction) + { + Emit8BitPair(context, rd, rn, rm, elementAction, unsigned: false); + } + + public static void EmitUnsigned16BitPair(CodeGenContext context, uint rd, uint rn, uint rm, Action elementAction) + { + using ScopedRegister tempD = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempD2 = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand rdOperand = GetOutputGpr(context, rd); + Operand rnOperand = GetInputGpr(context, rn); + Operand rmOperand = GetInputGpr(context, rm); + + context.Arm64Assembler.Uxth(tempN.Operand, rnOperand); + context.Arm64Assembler.Uxth(tempM.Operand, rmOperand); + elementAction(tempD.Operand, tempN.Operand, tempM.Operand); + context.Arm64Assembler.Uxth(tempD2.Operand, tempD.Operand); + + context.Arm64Assembler.Lsr(tempN.Operand, rnOperand, Const(16)); + context.Arm64Assembler.Lsr(tempM.Operand, rmOperand, Const(16)); + elementAction(tempD.Operand, tempN.Operand, tempM.Operand); + context.Arm64Assembler.Orr(rdOperand, tempD2.Operand, tempD.Operand, ArmShiftType.Lsl, 16); + } + + public static void EmitUnsigned16BitXPair(CodeGenContext context, uint rd, uint rn, uint rm, Action elementAction) + { + using ScopedRegister tempD = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempD2 = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand rdOperand = GetOutputGpr(context, rd); + Operand rnOperand = GetInputGpr(context, rn); + Operand rmOperand = GetInputGpr(context, rm); + + context.Arm64Assembler.Uxth(tempN.Operand, rnOperand); + context.Arm64Assembler.Lsr(tempM.Operand, rmOperand, Const(16)); + elementAction(tempD.Operand, tempN.Operand, tempM.Operand, 0); + context.Arm64Assembler.Uxth(tempD2.Operand, tempD.Operand); + + context.Arm64Assembler.Lsr(tempN.Operand, rnOperand, Const(16)); + context.Arm64Assembler.Uxth(tempM.Operand, rmOperand); + elementAction(tempD.Operand, tempN.Operand, tempM.Operand, 1); + context.Arm64Assembler.Orr(rdOperand, tempD2.Operand, tempD.Operand, ArmShiftType.Lsl, 16); + } + + public static void EmitUnsigned8BitPair(CodeGenContext context, uint rd, uint rn, uint rm, Action elementAction) + { + Emit8BitPair(context, rd, rn, rm, elementAction, unsigned: true); + } + + private static void Emit8BitPair(CodeGenContext context, uint rd, uint rn, uint rm, Action elementAction, bool unsigned) + { + using ScopedRegister tempD = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempD2 = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand rdOperand = GetOutputGpr(context, rd); + Operand rnOperand = GetInputGpr(context, rn); + Operand rmOperand = GetInputGpr(context, rm); + + for (int b = 0; b < 4; b++) + { + if (unsigned) + { + context.Arm64Assembler.Ubfx(tempN.Operand, rnOperand, b * 8, 8); + context.Arm64Assembler.Ubfx(tempM.Operand, rmOperand, b * 8, 8); + } + else + { + context.Arm64Assembler.Sbfx(tempN.Operand, rnOperand, b * 8, 8); + context.Arm64Assembler.Sbfx(tempM.Operand, rmOperand, b * 8, 8); + } + + elementAction(tempD.Operand, tempN.Operand, tempM.Operand); + + if (b == 0) + { + context.Arm64Assembler.Uxtb(tempD2.Operand, tempD.Operand); + } + else if (b < 3) + { + context.Arm64Assembler.Uxtb(tempD.Operand, tempD.Operand); + context.Arm64Assembler.Orr(tempD2.Operand, tempD2.Operand, tempD.Operand, ArmShiftType.Lsl, b * 8); + } + else + { + context.Arm64Assembler.Orr(rdOperand, tempD2.Operand, tempD.Operand, ArmShiftType.Lsl, 24); + } + } + } + + public static uint CombineV(uint low4, uint high1, uint size) + { + return size == 3 ? CombineV(low4, high1) : CombineVF(high1, low4); + } + + public static uint CombineV(uint low4, uint high1) + { + return low4 | (high1 << 4); + } + + public static uint CombineVF(uint low1, uint high4) + { + return low1 | (high4 << 1); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitCrc32.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitCrc32.cs new file mode 100644 index 000000000..ee6341880 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitCrc32.cs @@ -0,0 +1,26 @@ +using Ryujinx.Cpu.LightningJit.CodeGen; +using System; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitCrc32 + { + public static void Crc32(CodeGenContext context, uint rd, uint rn, uint rm, uint sz) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + context.Arm64Assembler.Crc32(rdOperand, rnOperand, rmOperand, Math.Min(2, sz)); + } + + public static void Crc32c(CodeGenContext context, uint rd, uint rn, uint rm, uint sz) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + context.Arm64Assembler.Crc32c(rdOperand, rnOperand, rmOperand, Math.Min(2, sz)); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitDivide.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitDivide.cs new file mode 100644 index 000000000..31c96dc80 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitDivide.cs @@ -0,0 +1,25 @@ +using Ryujinx.Cpu.LightningJit.CodeGen; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitDivide + { + public static void Sdiv(CodeGenContext context, uint rd, uint rn, uint rm) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + context.Arm64Assembler.Sdiv(rdOperand, rnOperand, rmOperand); + } + + public static void Udiv(CodeGenContext context, uint rd, uint rn, uint rm) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + context.Arm64Assembler.Udiv(rdOperand, rnOperand, rmOperand); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitExtension.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitExtension.cs new file mode 100644 index 000000000..dafe2974e --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitExtension.cs @@ -0,0 +1,191 @@ +using Ryujinx.Cpu.LightningJit.CodeGen; +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; +using System; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitExtension + { + public static void Sxtab(CodeGenContext context, uint rd, uint rn, uint rm, uint rotate) + { + EmitRotated(context, ArmExtensionType.Sxtb, rd, rn, rm, rotate); + } + + public static void Sxtab16(CodeGenContext context, uint rd, uint rn, uint rm, uint rotate) + { + EmitExtendAccumulate8(context, rd, rn, rm, rotate, unsigned: false); + } + + public static void Sxtah(CodeGenContext context, uint rd, uint rn, uint rm, uint rotate) + { + EmitRotated(context, ArmExtensionType.Sxth, rd, rn, rm, rotate); + } + + public static void Sxtb(CodeGenContext context, uint rd, uint rm, uint rotate) + { + EmitRotated(context, context.Arm64Assembler.Sxtb, rd, rm, rotate); + } + + public static void Sxtb16(CodeGenContext context, uint rd, uint rm, uint rotate) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempRegister2 = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + if (rotate != 0) + { + context.Arm64Assembler.Ror(tempRegister.Operand, rmOperand, InstEmitCommon.Const((int)rotate * 8)); + context.Arm64Assembler.And(rdOperand, tempRegister.Operand, InstEmitCommon.Const(0xff00ff)); + } + else + { + context.Arm64Assembler.And(rdOperand, rmOperand, InstEmitCommon.Const(0xff00ff)); + } + + // Sign-extend by broadcasting sign bits. + context.Arm64Assembler.And(tempRegister.Operand, rdOperand, InstEmitCommon.Const(0x800080)); + context.Arm64Assembler.Lsl(tempRegister2.Operand, tempRegister.Operand, InstEmitCommon.Const(9)); + context.Arm64Assembler.Sub(tempRegister.Operand, tempRegister2.Operand, tempRegister.Operand); + context.Arm64Assembler.Orr(rdOperand, rdOperand, tempRegister.Operand); + } + + public static void Sxth(CodeGenContext context, uint rd, uint rm, uint rotate) + { + EmitRotated(context, context.Arm64Assembler.Sxth, rd, rm, rotate); + } + + public static void Uxtab(CodeGenContext context, uint rd, uint rn, uint rm, uint rotate) + { + EmitRotated(context, ArmExtensionType.Uxtb, rd, rn, rm, rotate); + } + + public static void Uxtab16(CodeGenContext context, uint rd, uint rn, uint rm, uint rotate) + { + EmitExtendAccumulate8(context, rd, rn, rm, rotate, unsigned: true); + } + + public static void Uxtah(CodeGenContext context, uint rd, uint rn, uint rm, uint rotate) + { + EmitRotated(context, ArmExtensionType.Uxth, rd, rn, rm, rotate); + } + + public static void Uxtb(CodeGenContext context, uint rd, uint rm, uint rotate) + { + EmitRotated(context, context.Arm64Assembler.Uxtb, rd, rm, rotate); + } + + public static void Uxtb16(CodeGenContext context, uint rd, uint rm, uint rotate) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + if (rotate != 0) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Ror(tempRegister.Operand, rmOperand, InstEmitCommon.Const((int)rotate * 8)); + context.Arm64Assembler.And(rdOperand, tempRegister.Operand, InstEmitCommon.Const(0xff00ff)); + } + else + { + context.Arm64Assembler.And(rdOperand, rmOperand, InstEmitCommon.Const(0xff00ff)); + } + } + + public static void Uxth(CodeGenContext context, uint rd, uint rm, uint rotate) + { + EmitRotated(context, context.Arm64Assembler.Uxth, rd, rm, rotate); + } + + private static void EmitRotated(CodeGenContext context, Action action, uint rd, uint rm, uint rotate) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + if (rotate != 0) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Ror(tempRegister.Operand, rmOperand, InstEmitCommon.Const((int)rotate * 8)); + action(rdOperand, tempRegister.Operand); + } + else + { + action(rdOperand, rmOperand); + } + } + + private static void EmitRotated(CodeGenContext context, ArmExtensionType extensionType, uint rd, uint rn, uint rm, uint rotate) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + if (rotate != 0) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Ror(tempRegister.Operand, rmOperand, InstEmitCommon.Const((int)rotate * 8)); + context.Arm64Assembler.Add(rdOperand, rnOperand, tempRegister.Operand, extensionType); + } + else + { + context.Arm64Assembler.Add(rdOperand, rnOperand, rmOperand, extensionType); + } + } + + private static void EmitExtendAccumulate8(CodeGenContext context, uint rd, uint rn, uint rm, uint rotate, bool unsigned) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + if (rotate != 0) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Ror(tempRegister.Operand, rmOperand, InstEmitCommon.Const((int)rotate * 8)); + + EmitExtendAccumulate8Core(context, rdOperand, rnOperand, tempRegister.Operand, unsigned); + } + else + { + EmitExtendAccumulate8Core(context, rdOperand, rnOperand, rmOperand, unsigned); + } + } + + private static void EmitExtendAccumulate8Core(CodeGenContext context, Operand rd, Operand rn, Operand rm, bool unsigned) + { + using ScopedRegister tempD = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempD2 = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + if (unsigned) + { + context.Arm64Assembler.Uxth(tempN.Operand, rn); + } + else + { + context.Arm64Assembler.Sxth(tempN.Operand, rn); + } + + context.Arm64Assembler.Add(tempD.Operand, tempN.Operand, rm, unsigned ? ArmExtensionType.Uxtb : ArmExtensionType.Sxtb); + context.Arm64Assembler.Uxth(tempD2.Operand, tempD.Operand); + + if (unsigned) + { + context.Arm64Assembler.Lsr(tempN.Operand, rn, InstEmitCommon.Const(16)); + } + else + { + context.Arm64Assembler.Asr(tempN.Operand, rn, InstEmitCommon.Const(16)); + } + + context.Arm64Assembler.Lsr(tempD.Operand, rm, InstEmitCommon.Const(16)); + context.Arm64Assembler.Add(tempD.Operand, tempN.Operand, tempD.Operand, unsigned ? ArmExtensionType.Uxtb : ArmExtensionType.Sxtb); + context.Arm64Assembler.Orr(rd, tempD2.Operand, tempD.Operand, ArmShiftType.Lsl, 16); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitFlow.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitFlow.cs new file mode 100644 index 000000000..81e44ba00 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitFlow.cs @@ -0,0 +1,256 @@ +using ARMeilleure.Common; +using Ryujinx.Cpu.LightningJit.CodeGen; +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; +using System; +using System.Diagnostics; +using System.Numerics; +using System.Runtime.CompilerServices; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitFlow + { + private const int SpIndex = 31; + + public static void B(CodeGenContext context, int imm, ArmCondition condition) + { + context.AddPendingBranch(InstName.B, imm); + + if (condition == ArmCondition.Al) + { + context.Arm64Assembler.B(0); + } + else + { + context.Arm64Assembler.B(condition, 0); + } + } + + public static void Bl(CodeGenContext context, int imm, bool sourceIsThumb, bool targetIsThumb) + { + uint nextAddress = sourceIsThumb ? context.Pc | 1u : context.Pc - 4; + uint targetAddress = targetIsThumb ? context.Pc + (uint)imm : (context.Pc & ~3u) + (uint)imm; + + if (sourceIsThumb != targetIsThumb) + { + if (targetIsThumb) + { + InstEmitCommon.SetThumbFlag(context); + } + else + { + InstEmitCommon.ClearThumbFlag(context); + } + } + + context.AddPendingCall(targetAddress, nextAddress); + + context.Arm64Assembler.B(0); + } + + public static void Blx(CodeGenContext context, uint rm, bool sourceIsThumb) + { + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + InstEmitCommon.SetThumbFlag(context, rmOperand); + + uint nextAddress = sourceIsThumb ? (context.Pc - 2) | 1u : context.Pc - 4; + + context.AddPendingIndirectCall(rm, nextAddress); + + context.Arm64Assembler.B(0); + } + + public static void Bx(CodeGenContext context, uint rm) + { + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + InstEmitCommon.SetThumbFlag(context, rmOperand); + + context.AddPendingIndirectBranch(InstName.Bx, rm); + + context.Arm64Assembler.B(0); + } + + public static void Cbnz(CodeGenContext context, uint rn, int imm, bool op) + { + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + + context.AddPendingBranch(InstName.Cbnz, imm); + + if (op) + { + context.Arm64Assembler.Cbnz(rnOperand, 0); + } + else + { + context.Arm64Assembler.Cbz(rnOperand, 0); + } + } + + public static void It(CodeGenContext context, uint firstCond, uint mask) + { + Debug.Assert(mask != 0); + + int instCount = 4 - BitOperations.TrailingZeroCount(mask); + + Span conditions = stackalloc ArmCondition[instCount]; + + int i = 0; + + for (int index = 5 - instCount; index < 4; index++) + { + bool invert = (mask & (1u << index)) != 0; + + if (invert) + { + conditions[i++] = ((ArmCondition)firstCond).Invert(); + } + else + { + conditions[i++] = (ArmCondition)firstCond; + } + } + + conditions[i] = (ArmCondition)firstCond; + + context.SetItBlockStart(conditions); + } + + public static void Tbb(CodeGenContext context, uint rn, uint rm, bool h) + { + context.Arm64Assembler.Mov(context.RegisterAllocator.RemapGprRegister(RegisterUtils.PcRegister), context.Pc); + + context.AddPendingTableBranch(rn, rm, h); + + context.Arm64Assembler.B(0); + } + + public unsafe static void WriteCallWithGuestAddress( + CodeWriter writer, + ref Assembler asm, + RegisterAllocator regAlloc, + TailMerger tailMerger, + Action writeEpilogue, + AddressTable funcTable, + IntPtr funcPtr, + int spillBaseOffset, + uint nextAddress, + Operand guestAddress, + bool isTail = false) + { + int tempRegister; + + if (guestAddress.Kind == OperandKind.Constant) + { + tempRegister = regAlloc.AllocateTempGprRegister(); + + asm.Mov(Register(tempRegister), guestAddress.Value); + asm.StrRiUn(Register(tempRegister), Register(regAlloc.FixedContextRegister), NativeContextOffsets.DispatchAddressOffset); + + regAlloc.FreeTempGprRegister(tempRegister); + } + else + { + asm.StrRiUn(guestAddress, Register(regAlloc.FixedContextRegister), NativeContextOffsets.DispatchAddressOffset); + } + + tempRegister = regAlloc.FixedContextRegister == 1 ? 2 : 1; + + if (!isTail) + { + WriteSpillSkipContext(ref asm, regAlloc, spillBaseOffset); + } + + Operand rn = Register(tempRegister); + + if (regAlloc.FixedContextRegister != 0) + { + asm.Mov(Register(0), Register(regAlloc.FixedContextRegister)); + } + + if (guestAddress.Kind == OperandKind.Constant && funcTable != null) + { + ulong funcPtrLoc = (ulong)Unsafe.AsPointer(ref funcTable.GetValue(guestAddress.Value)); + + asm.Mov(rn, funcPtrLoc & ~0xfffUL); + asm.LdrRiUn(rn, rn, (int)(funcPtrLoc & 0xfffUL)); + } + else + { + asm.Mov(rn, (ulong)funcPtr); + } + + if (isTail) + { + writeEpilogue(); + asm.Br(rn); + } + else + { + asm.Blr(rn); + + asm.Mov(rn, nextAddress); + asm.Cmp(Register(0), rn); + + tailMerger.AddConditionalReturn(writer, asm, ArmCondition.Ne); + + WriteFillSkipContext(ref asm, regAlloc, spillBaseOffset); + } + } + + private static void WriteSpillSkipContext(ref Assembler asm, RegisterAllocator regAlloc, int spillOffset) + { + WriteSpillOrFillSkipContext(ref asm, regAlloc, spillOffset, spill: true); + } + + private static void WriteFillSkipContext(ref Assembler asm, RegisterAllocator regAlloc, int spillOffset) + { + WriteSpillOrFillSkipContext(ref asm, regAlloc, spillOffset, spill: false); + } + + private static void WriteSpillOrFillSkipContext(ref Assembler asm, RegisterAllocator regAlloc, int spillOffset, bool spill) + { + uint gprMask = regAlloc.UsedGprsMask & ((1u << regAlloc.FixedContextRegister) | (1u << regAlloc.FixedPageTableRegister)); + + while (gprMask != 0) + { + int reg = BitOperations.TrailingZeroCount(gprMask); + + if (reg < 31 && (gprMask & (2u << reg)) != 0 && spillOffset < RegisterSaveRestore.Encodable9BitsOffsetLimit) + { + if (spill) + { + asm.StpRiUn(Register(reg), Register(reg + 1), Register(SpIndex), spillOffset); + } + else + { + asm.LdpRiUn(Register(reg), Register(reg + 1), Register(SpIndex), spillOffset); + } + + gprMask &= ~(3u << reg); + spillOffset += 16; + } + else + { + if (spill) + { + asm.StrRiUn(Register(reg), Register(SpIndex), spillOffset); + } + else + { + asm.LdrRiUn(Register(reg), Register(SpIndex), spillOffset); + } + + gprMask &= ~(1u << reg); + spillOffset += 8; + } + } + } + + private static Operand Register(int register, OperandType type = OperandType.I64) + { + return new Operand(register, RegisterType.Integer, type); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitGE.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitGE.cs new file mode 100644 index 000000000..dffcc511e --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitGE.cs @@ -0,0 +1,265 @@ +using Ryujinx.Cpu.LightningJit.CodeGen; +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitGE + { + public static void Sadd16(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitAddSub(context, rd, rn, rm, is16Bit: true, add: true, unsigned: false); + } + + public static void Sadd8(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitAddSub(context, rd, rn, rm, is16Bit: false, add: true, unsigned: false); + } + + public static void Sasx(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitAsxSax(context, rd, rn, rm, isAsx: true, unsigned: false); + } + + public static void Sel(CodeGenContext context, uint rd, uint rn, uint rm) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + using ScopedRegister geFlags = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + ExtractGEFlags(context, geFlags.Operand); + + // Broadcast compact GE flags (one bit to one byte, 0b1111 -> 0x1010101). + context.Arm64Assembler.Mov(tempRegister.Operand, 0x204081u); + context.Arm64Assembler.Mul(geFlags.Operand, geFlags.Operand, tempRegister.Operand); + context.Arm64Assembler.And(geFlags.Operand, geFlags.Operand, InstEmitCommon.Const(0x1010101)); + + // Build mask from expanded flags (0x1010101 -> 0xFFFFFFFF). + context.Arm64Assembler.Lsl(tempRegister.Operand, geFlags.Operand, InstEmitCommon.Const(8)); + context.Arm64Assembler.Sub(geFlags.Operand, tempRegister.Operand, geFlags.Operand); + + // Result = (n & mask) | (m & ~mask). + context.Arm64Assembler.And(tempRegister.Operand, geFlags.Operand, rnOperand); + context.Arm64Assembler.Bic(rdOperand, rmOperand, geFlags.Operand); + context.Arm64Assembler.Orr(rdOperand, rdOperand, tempRegister.Operand); + } + + public static void Ssax(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitAsxSax(context, rd, rn, rm, isAsx: false, unsigned: false); + } + + public static void Ssub16(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitAddSub(context, rd, rn, rm, is16Bit: true, add: false, unsigned: false); + } + + public static void Ssub8(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitAddSub(context, rd, rn, rm, is16Bit: false, add: false, unsigned: false); + } + + public static void Uadd16(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitAddSub(context, rd, rn, rm, is16Bit: true, add: true, unsigned: true); + } + + public static void Uadd8(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitAddSub(context, rd, rn, rm, is16Bit: false, add: true, unsigned: true); + } + + public static void Uasx(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitAsxSax(context, rd, rn, rm, isAsx: true, unsigned: true); + } + + public static void Usax(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitAsxSax(context, rd, rn, rm, isAsx: false, unsigned: true); + } + + public static void Usub16(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitAddSub(context, rd, rn, rm, is16Bit: true, add: false, unsigned: true); + } + + public static void Usub8(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitAddSub(context, rd, rn, rm, is16Bit: false, add: false, unsigned: true); + } + + private static void EmitAddSub(CodeGenContext context, uint rd, uint rn, uint rm, bool is16Bit, bool add, bool unsigned) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + using ScopedRegister geFlags = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + int e = 0; + + void Emit(Operand d, Operand n, Operand m) + { + if (add) + { + context.Arm64Assembler.Add(d, n, m); + } + else + { + context.Arm64Assembler.Sub(d, n, m); + } + + if (unsigned && add) + { + if (e == 0) + { + context.Arm64Assembler.Lsr(geFlags.Operand, d, InstEmitCommon.Const(is16Bit ? 16 : 8)); + } + else + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Lsr(tempRegister.Operand, d, InstEmitCommon.Const(is16Bit ? 16 : 8)); + context.Arm64Assembler.Orr(geFlags.Operand, geFlags.Operand, tempRegister.Operand, ArmShiftType.Lsl, e); + } + } + else + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Mvn(tempRegister.Operand, d); + + if (e == 0) + { + context.Arm64Assembler.Lsr(geFlags.Operand, tempRegister.Operand, InstEmitCommon.Const(31)); + } + else + { + context.Arm64Assembler.Lsr(tempRegister.Operand, tempRegister.Operand, InstEmitCommon.Const(31)); + context.Arm64Assembler.Orr(geFlags.Operand, geFlags.Operand, tempRegister.Operand, ArmShiftType.Lsl, e); + } + } + + e += is16Bit ? 2 : 1; + } + + if (is16Bit) + { + if (unsigned) + { + InstEmitCommon.EmitUnsigned16BitPair(context, rd, rn, rm, Emit); + } + else + { + InstEmitCommon.EmitSigned16BitPair(context, rd, rn, rm, Emit); + } + + // Duplicate bits. + context.Arm64Assembler.Orr(geFlags.Operand, geFlags.Operand, geFlags.Operand, ArmShiftType.Lsl, 1); + } + else + { + if (unsigned) + { + InstEmitCommon.EmitUnsigned8BitPair(context, rd, rn, rm, Emit); + } + else + { + InstEmitCommon.EmitSigned8BitPair(context, rd, rn, rm, Emit); + } + } + + UpdateGEFlags(context, geFlags.Operand); + } + + private static void EmitAsxSax(CodeGenContext context, uint rd, uint rn, uint rm, bool isAsx, bool unsigned) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + using ScopedRegister geFlags = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + void Emit(Operand d, Operand n, Operand m, int e) + { + bool add = e == (isAsx ? 1 : 0); + + if (add) + { + context.Arm64Assembler.Add(d, n, m); + } + else + { + context.Arm64Assembler.Sub(d, n, m); + } + + if (unsigned && add) + { + if (e == 0) + { + context.Arm64Assembler.Lsr(geFlags.Operand, d, InstEmitCommon.Const(16)); + } + else + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Lsr(tempRegister.Operand, d, InstEmitCommon.Const(16)); + context.Arm64Assembler.Orr(geFlags.Operand, geFlags.Operand, tempRegister.Operand, ArmShiftType.Lsl, e * 2); + } + } + else + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Mvn(tempRegister.Operand, d); + + if (e == 0) + { + context.Arm64Assembler.Lsr(geFlags.Operand, tempRegister.Operand, InstEmitCommon.Const(31)); + } + else + { + context.Arm64Assembler.Lsr(tempRegister.Operand, tempRegister.Operand, InstEmitCommon.Const(31)); + context.Arm64Assembler.Orr(geFlags.Operand, geFlags.Operand, tempRegister.Operand, ArmShiftType.Lsl, e * 2); + } + } + } + + if (unsigned) + { + InstEmitCommon.EmitUnsigned16BitXPair(context, rd, rn, rm, Emit); + } + else + { + InstEmitCommon.EmitSigned16BitXPair(context, rd, rn, rm, Emit); + } + + // Duplicate bits. + context.Arm64Assembler.Orr(geFlags.Operand, geFlags.Operand, geFlags.Operand, ArmShiftType.Lsl, 1); + + UpdateGEFlags(context, geFlags.Operand); + } + + public static void UpdateGEFlags(CodeGenContext context, Operand flags) + { + Operand ctx = InstEmitSystem.Register(context.RegisterAllocator.FixedContextRegister); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.LdrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset); + context.Arm64Assembler.Bfi(tempRegister.Operand, flags, 16, 4); + context.Arm64Assembler.StrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset); + } + + public static void ExtractGEFlags(CodeGenContext context, Operand flags) + { + Operand ctx = InstEmitSystem.Register(context.RegisterAllocator.FixedContextRegister); + + context.Arm64Assembler.LdrRiUn(flags, ctx, NativeContextOffsets.FlagsBaseOffset); + context.Arm64Assembler.Ubfx(flags, flags, 16, 4); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitHalve.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitHalve.cs new file mode 100644 index 000000000..567acfbf1 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitHalve.cs @@ -0,0 +1,178 @@ +using Ryujinx.Cpu.LightningJit.CodeGen; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitHalve + { + public static void Shadd16(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitHadd(context, rd, rn, rm, 0x7fff7fff, unsigned: false); + } + + public static void Shadd8(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitHadd(context, rd, rn, rm, 0x7f7f7f7f, unsigned: false); + } + + public static void Shsub16(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitHsub(context, rd, rn, rm, 0x7fff7fff, unsigned: false); + } + + public static void Shsub8(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitHsub(context, rd, rn, rm, 0x7f7f7f7f, unsigned: false); + } + + public static void Shasx(CodeGenContext context, uint rd, uint rn, uint rm) + { + InstEmitCommon.EmitSigned16BitXPair(context, rd, rn, rm, (d, n, m, e) => + { + if (e == 0) + { + context.Arm64Assembler.Sub(d, n, m); + } + else + { + context.Arm64Assembler.Add(d, n, m); + } + + context.Arm64Assembler.Lsr(d, d, InstEmitCommon.Const(1)); + }); + } + + public static void Shsax(CodeGenContext context, uint rd, uint rn, uint rm) + { + InstEmitCommon.EmitSigned16BitXPair(context, rd, rn, rm, (d, n, m, e) => + { + if (e == 0) + { + context.Arm64Assembler.Add(d, n, m); + } + else + { + context.Arm64Assembler.Sub(d, n, m); + } + + context.Arm64Assembler.Lsr(d, d, InstEmitCommon.Const(1)); + }); + } + + public static void Uhadd16(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitHadd(context, rd, rn, rm, 0x7fff7fff, unsigned: true); + } + + public static void Uhadd8(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitHadd(context, rd, rn, rm, 0x7f7f7f7f, unsigned: true); + } + + public static void Uhasx(CodeGenContext context, uint rd, uint rn, uint rm) + { + InstEmitCommon.EmitUnsigned16BitXPair(context, rd, rn, rm, (d, n, m, e) => + { + if (e == 0) + { + context.Arm64Assembler.Sub(d, n, m); + } + else + { + context.Arm64Assembler.Add(d, n, m); + } + + context.Arm64Assembler.Lsr(d, d, InstEmitCommon.Const(1)); + }); + } + + public static void Uhsax(CodeGenContext context, uint rd, uint rn, uint rm) + { + InstEmitCommon.EmitUnsigned16BitXPair(context, rd, rn, rm, (d, n, m, e) => + { + if (e == 0) + { + context.Arm64Assembler.Add(d, n, m); + } + else + { + context.Arm64Assembler.Sub(d, n, m); + } + + context.Arm64Assembler.Lsr(d, d, InstEmitCommon.Const(1)); + }); + } + + public static void Uhsub16(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitHsub(context, rd, rn, rm, 0x7fff7fff, unsigned: true); + } + + public static void Uhsub8(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitHsub(context, rd, rn, rm, 0x7f7f7f7f, unsigned: true); + } + + private static void EmitHadd(CodeGenContext context, uint rd, uint rn, uint rm, int mask, bool unsigned) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + using ScopedRegister res = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister carry = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + // This relies on the equality x+y == ((x&y) << 1) + (x^y). + // Note that x^y always contains the LSB of the result. + // Since we want to calculate (x+y)/2, we can instead calculate (x&y) + ((x^y)>>1). + // We mask by 0x7F/0x7FFF to remove the LSB so that it doesn't leak into the field below. + + context.Arm64Assembler.And(res.Operand, rmOperand, rnOperand); + context.Arm64Assembler.Eor(carry.Operand, rmOperand, rnOperand); + context.Arm64Assembler.Lsr(rdOperand, carry.Operand, InstEmitCommon.Const(1)); + context.Arm64Assembler.And(rdOperand, rdOperand, InstEmitCommon.Const(mask)); + context.Arm64Assembler.Add(rdOperand, rdOperand, res.Operand); + + if (!unsigned) + { + // Propagates the sign bit from (x^y)>>1 upwards by one. + context.Arm64Assembler.And(carry.Operand, carry.Operand, InstEmitCommon.Const(~mask)); + context.Arm64Assembler.Eor(rdOperand, rdOperand, carry.Operand); + } + } + + private static void EmitHsub(CodeGenContext context, uint rd, uint rn, uint rm, int mask, bool unsigned) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + using ScopedRegister carry = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister left = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister right = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + // This relies on the equality x-y == (x^y) - (((x^y)&y) << 1). + // Note that x^y always contains the LSB of the result. + // Since we want to calculate (x+y)/2, we can instead calculate ((x^y)>>1) - ((x^y)&y). + + context.Arm64Assembler.Eor(carry.Operand, rmOperand, rnOperand); + context.Arm64Assembler.Lsr(left.Operand, carry.Operand, InstEmitCommon.Const(1)); + context.Arm64Assembler.And(right.Operand, carry.Operand, rmOperand); + + // We must now perform a partitioned subtraction. + // We can do this because minuend contains 7/15 bit fields. + // We use the extra bit in minuend as a bit to borrow from; we set this bit. + // We invert this bit at the end as this tells us if that bit was borrowed from. + + context.Arm64Assembler.Orr(rdOperand, left.Operand, InstEmitCommon.Const(~mask)); + context.Arm64Assembler.Sub(rdOperand, rdOperand, right.Operand); + context.Arm64Assembler.Eor(rdOperand, rdOperand, InstEmitCommon.Const(~mask)); + + if (!unsigned) + { + // We then sign extend the result into this bit. + context.Arm64Assembler.And(carry.Operand, carry.Operand, InstEmitCommon.Const(~mask)); + context.Arm64Assembler.Eor(rdOperand, rdOperand, carry.Operand); + } + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMemory.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMemory.cs new file mode 100644 index 000000000..6ab4b9495 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMemory.cs @@ -0,0 +1,1172 @@ +using ARMeilleure.Memory; +using Ryujinx.Cpu.LightningJit.CodeGen; +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; +using System; +using System.Diagnostics; +using System.Numerics; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitMemory + { + private enum PrefetchType : uint + { + Pld = 0, + Pli = 1, + Pst = 2, + } + + public static void Lda(CodeGenContext context, uint rt, uint rn) + { + EmitMemoryInstruction(context, rt, rn, isStore: false, context.Arm64Assembler.Ldar); + } + + public static void Ldab(CodeGenContext context, uint rt, uint rn) + { + EmitMemoryInstruction(context, rt, rn, isStore: false, context.Arm64Assembler.Ldarb); + } + + public static void Ldaex(CodeGenContext context, uint rt, uint rn) + { + EmitMemoryInstruction(context, rt, rn, isStore: false, context.Arm64Assembler.Ldaxr); + } + + public static void Ldaexb(CodeGenContext context, uint rt, uint rn) + { + EmitMemoryInstruction(context, rt, rn, isStore: false, context.Arm64Assembler.Ldaxrb); + } + + public static void Ldaexd(CodeGenContext context, uint rt, uint rt2, uint rn) + { + EmitMemoryDWordInstruction(context, rt, rt2, rn, isStore: false, context.Arm64Assembler.Ldaxp); + } + + public static void Ldaexh(CodeGenContext context, uint rt, uint rn) + { + EmitMemoryInstruction(context, rt, rn, isStore: false, context.Arm64Assembler.Ldaxrh); + } + + public static void Ldah(CodeGenContext context, uint rt, uint rn) + { + EmitMemoryInstruction(context, rt, rn, isStore: false, context.Arm64Assembler.Ldarh); + } + + public static void LdcI(CodeGenContext context, uint rn, int imm, bool p, bool u, bool w) + { + // TODO. + } + + public static void LdcL(CodeGenContext context, uint imm, bool p, bool u, bool w) + { + // TODO. + } + + public static void Ldm(CodeGenContext context, uint rn, uint registerList, bool w) + { + Operand baseAddress = InstEmitCommon.GetInputGpr(context, rn); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, baseAddress); + + EmitMemoryMultipleInstructionCore( + context, + tempRegister.Operand, + registerList, + isStore: false, + context.Arm64Assembler.LdrRiUn, + context.Arm64Assembler.LdpRiUn); + + if (w) + { + Operand offset = InstEmitCommon.Const(BitOperations.PopCount(registerList) * 4); + + WriteAddShiftOffset(context.Arm64Assembler, baseAddress, baseAddress, offset, true, ArmShiftType.Lsl, 0); + } + } + + public static void Ldmda(CodeGenContext context, uint rn, uint registerList, bool w) + { + EmitMemoryMultipleDaInstruction(context, rn, registerList, w, isStore: false, context.Arm64Assembler.LdrRiUn, context.Arm64Assembler.LdpRiUn); + } + + public static void Ldmdb(CodeGenContext context, uint rn, uint registerList, bool w) + { + EmitMemoryMultipleDbInstruction(context, rn, registerList, w, isStore: false, context.Arm64Assembler.LdrRiUn, context.Arm64Assembler.LdpRiUn); + } + + public static void Ldmib(CodeGenContext context, uint rn, uint registerList, bool w) + { + EmitMemoryMultipleIbInstruction(context, rn, registerList, w, isStore: false, context.Arm64Assembler.LdrRiUn, context.Arm64Assembler.LdpRiUn); + } + + public static void LdrI(CodeGenContext context, uint rt, uint rn, int imm, bool p, bool u, bool w) + { + EmitMemoryInstruction(context, rt, rn, imm, 2, p, u, w, isStore: false, context.Arm64Assembler.LdrRiUn, context.Arm64Assembler.Ldur); + } + + public static void LdrL(CodeGenContext context, uint rt, uint imm, bool p, bool u, bool w) + { + EmitMemoryLiteralInstruction(context, rt, imm, 2, p, u, w, context.Arm64Assembler.LdrRiUn); + } + + public static void LdrR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool p, bool u, bool w) + { + EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, p, u, w, isStore: false, context.Arm64Assembler.LdrRiUn, context.Arm64Assembler.Ldur); + } + + public static void LdrbI(CodeGenContext context, uint rt, uint rn, int imm, bool p, bool u, bool w) + { + EmitMemoryInstruction(context, rt, rn, imm, 0, p, u, w, isStore: false, context.Arm64Assembler.LdrbRiUn, context.Arm64Assembler.Ldurb); + } + + public static void LdrbL(CodeGenContext context, uint rt, uint imm, bool p, bool u, bool w) + { + EmitMemoryLiteralInstruction(context, rt, imm, 0, p, u, w, context.Arm64Assembler.LdrbRiUn); + } + + public static void LdrbR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool p, bool u, bool w) + { + EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, p, u, w, isStore: false, context.Arm64Assembler.LdrbRiUn, context.Arm64Assembler.Ldurb); + } + + public static void LdrbtI(CodeGenContext context, uint rt, uint rn, int imm, bool postIndex, bool u) + { + EmitMemoryInstruction(context, rt, rn, imm, 0, !postIndex, u, false, isStore: false, context.Arm64Assembler.LdrbRiUn, context.Arm64Assembler.Ldurb); + } + + public static void LdrbtR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool postIndex, bool u) + { + EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, !postIndex, u, false, isStore: false, context.Arm64Assembler.LdrbRiUn, context.Arm64Assembler.Ldurb); + } + + public static void LdrdI(CodeGenContext context, uint rt, uint rt2, uint rn, uint imm, bool p, bool u, bool w) + { + EmitMemoryDWordInstructionI(context, rt, rt2, rn, imm, p, u, w, isStore: false, context.Arm64Assembler.LdpRiUn); + } + + public static void LdrdL(CodeGenContext context, uint rt, uint rt2, uint imm, bool p, bool u, bool w) + { + EmitMemoryDWordLiteralInstruction(context, rt, rt2, imm, p, u, w, context.Arm64Assembler.LdpRiUn); + } + + public static void LdrdR(CodeGenContext context, uint rt, uint rt2, uint rn, uint rm, bool p, bool u, bool w) + { + EmitMemoryDWordInstructionR(context, rt, rt2, rn, rm, p, u, w, isStore: false, context.Arm64Assembler.LdpRiUn); + } + + public static void Ldrex(CodeGenContext context, uint rt, uint rn) + { + EmitMemoryInstruction(context, rt, rn, isStore: false, context.Arm64Assembler.Ldaxr); + } + + public static void Ldrexb(CodeGenContext context, uint rt, uint rn) + { + EmitMemoryInstruction(context, rt, rn, isStore: false, context.Arm64Assembler.Ldaxrb); + } + + public static void Ldrexd(CodeGenContext context, uint rt, uint rt2, uint rn) + { + EmitMemoryDWordInstruction(context, rt, rt2, rn, isStore: false, context.Arm64Assembler.Ldaxp); + } + + public static void Ldrexh(CodeGenContext context, uint rt, uint rn) + { + EmitMemoryInstruction(context, rt, rn, isStore: false, context.Arm64Assembler.Ldaxrh); + } + + public static void LdrhI(CodeGenContext context, uint rt, uint rn, int imm, bool p, bool u, bool w) + { + EmitMemoryInstruction(context, rt, rn, imm, 1, p, u, w, isStore: false, context.Arm64Assembler.LdrhRiUn, context.Arm64Assembler.Ldurh); + } + + public static void LdrhL(CodeGenContext context, uint rt, uint imm, bool p, bool u, bool w) + { + EmitMemoryLiteralInstruction(context, rt, imm, 1, p, u, w, context.Arm64Assembler.LdrhRiUn); + } + + public static void LdrhR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool p, bool u, bool w) + { + EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, p, u, w, isStore: false, context.Arm64Assembler.LdrhRiUn, context.Arm64Assembler.Ldurh); + } + + public static void LdrhtI(CodeGenContext context, uint rt, uint rn, int imm, bool postIndex, bool u) + { + EmitMemoryInstruction(context, rt, rn, imm, 1, !postIndex, u, false, isStore: false, context.Arm64Assembler.LdrhRiUn, context.Arm64Assembler.Ldurh); + } + + public static void LdrhtR(CodeGenContext context, uint rt, uint rn, uint rm, bool postIndex, bool u) + { + EmitMemoryInstruction(context, rt, rn, rm, 0, 0, !postIndex, u, false, isStore: false, context.Arm64Assembler.LdrhRiUn, context.Arm64Assembler.Ldurh); + } + + public static void LdrsbI(CodeGenContext context, uint rt, uint rn, int imm, bool p, bool u, bool w) + { + EmitMemoryInstruction(context, rt, rn, imm, 0, p, u, w, isStore: false, context.Arm64Assembler.LdrsbRiUn, context.Arm64Assembler.Ldursb); + } + + public static void LdrsbL(CodeGenContext context, uint rt, uint imm, bool p, bool u, bool w) + { + EmitMemoryLiteralInstruction(context, rt, imm, 0, p, u, w, context.Arm64Assembler.LdrsbRiUn); + } + + public static void LdrsbR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool p, bool u, bool w) + { + EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, p, u, w, isStore: false, context.Arm64Assembler.LdrsbRiUn, context.Arm64Assembler.Ldursb); + } + + public static void LdrsbtI(CodeGenContext context, uint rt, uint rn, int imm, bool postIndex, bool u) + { + EmitMemoryInstruction(context, rt, rn, imm, 0, !postIndex, u, false, isStore: false, context.Arm64Assembler.LdrsbRiUn, context.Arm64Assembler.Ldursb); + } + + public static void LdrsbtR(CodeGenContext context, uint rt, uint rn, uint rm, bool postIndex, bool u) + { + EmitMemoryInstruction(context, rt, rn, rm, 0, 0, !postIndex, u, false, isStore: false, context.Arm64Assembler.LdrsbRiUn, context.Arm64Assembler.Ldursb); + } + + public static void LdrshI(CodeGenContext context, uint rt, uint rn, int imm, bool p, bool u, bool w) + { + EmitMemoryInstruction(context, rt, rn, imm, 1, p, u, w, isStore: false, context.Arm64Assembler.LdrshRiUn, context.Arm64Assembler.Ldursh); + } + + public static void LdrshL(CodeGenContext context, uint rt, uint imm, bool p, bool u, bool w) + { + EmitMemoryLiteralInstruction(context, rt, imm, 1, p, u, w, context.Arm64Assembler.LdrshRiUn); + } + + public static void LdrshR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool p, bool u, bool w) + { + EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, p, u, w, isStore: false, context.Arm64Assembler.LdrshRiUn, context.Arm64Assembler.Ldursh); + } + + public static void LdrshtI(CodeGenContext context, uint rt, uint rn, int imm, bool postIndex, bool u) + { + EmitMemoryInstruction(context, rt, rn, imm, 1, !postIndex, u, false, isStore: false, context.Arm64Assembler.LdrshRiUn, context.Arm64Assembler.Ldursh); + } + + public static void LdrshtR(CodeGenContext context, uint rt, uint rn, uint rm, bool postIndex, bool u) + { + EmitMemoryInstruction(context, rt, rn, rm, 0, 0, !postIndex, u, false, isStore: false, context.Arm64Assembler.LdrshRiUn, context.Arm64Assembler.Ldursh); + } + + public static void LdrtI(CodeGenContext context, uint rt, uint rn, int imm, bool postIndex, bool u) + { + EmitMemoryInstruction(context, rt, rn, imm, 2, !postIndex, u, false, isStore: false, context.Arm64Assembler.LdrRiUn, context.Arm64Assembler.Ldur); + } + + public static void LdrtR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool postIndex, bool u) + { + EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, !postIndex, u, false, isStore: false, context.Arm64Assembler.LdrRiUn, context.Arm64Assembler.Ldur); + } + + public static void PldI(CodeGenContext context, uint rn, uint imm, bool u, bool r) + { + EmitMemoryPrefetchInstruction(context, rn, imm, u, r ? PrefetchType.Pld : PrefetchType.Pst); + } + + public static void PldL(CodeGenContext context, uint imm, bool u) + { + EmitMemoryPrefetchLiteralInstruction(context, imm, u, PrefetchType.Pld); + } + + public static void PldR(CodeGenContext context, uint rn, uint rm, uint sType, uint imm5, bool u, bool r) + { + EmitMemoryPrefetchInstruction(context, rn, rm, u, sType, imm5, r ? PrefetchType.Pld : PrefetchType.Pst); + } + + public static void PliI(CodeGenContext context, uint rn, uint imm, bool u) + { + EmitMemoryPrefetchInstruction(context, rn, imm, u, PrefetchType.Pli); + } + + public static void PliL(CodeGenContext context, uint imm, bool u) + { + EmitMemoryPrefetchLiteralInstruction(context, imm, u, PrefetchType.Pli); + } + + public static void PliR(CodeGenContext context, uint rn, uint rm, uint sType, uint imm5, bool u) + { + EmitMemoryPrefetchInstruction(context, rn, rm, u, sType, imm5, PrefetchType.Pli); + } + + public static void Stc(CodeGenContext context, uint rn, int imm, bool p, bool u, bool w) + { + // TODO. + } + + public static void Stl(CodeGenContext context, uint rt, uint rn) + { + EmitMemoryInstruction(context, rt, rn, isStore: true, context.Arm64Assembler.Stlr); + } + + public static void Stlb(CodeGenContext context, uint rt, uint rn) + { + EmitMemoryInstruction(context, rt, rn, isStore: true, context.Arm64Assembler.Stlrb); + } + + public static void Stlex(CodeGenContext context, uint rd, uint rt, uint rn) + { + EmitMemoryStrexInstruction(context, rd, rt, rn, context.Arm64Assembler.Stlxr); + } + + public static void Stlexb(CodeGenContext context, uint rd, uint rt, uint rn) + { + EmitMemoryStrexInstruction(context, rd, rt, rn, context.Arm64Assembler.Stlxrb); + } + + public static void Stlexd(CodeGenContext context, uint rd, uint rt, uint rt2, uint rn) + { + EmitMemoryDWordStrexInstruction(context, rd, rt, rt2, rn, context.Arm64Assembler.Stlxp); + } + + public static void Stlexh(CodeGenContext context, uint rd, uint rt, uint rn) + { + EmitMemoryStrexInstruction(context, rd, rt, rn, context.Arm64Assembler.Stlxrh); + } + + public static void Stlh(CodeGenContext context, uint rt, uint rn) + { + EmitMemoryInstruction(context, rt, rn, isStore: true, context.Arm64Assembler.Stlrh); + } + + public static void Stm(CodeGenContext context, uint rn, uint registerList, bool w) + { + Operand baseAddress = InstEmitCommon.GetInputGpr(context, rn); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, baseAddress); + + EmitMemoryMultipleInstructionCore( + context, + tempRegister.Operand, + registerList, + isStore: true, + context.Arm64Assembler.StrRiUn, + context.Arm64Assembler.StpRiUn); + + if (w) + { + Operand offset = InstEmitCommon.Const(BitOperations.PopCount(registerList) * 4); + + WriteAddShiftOffset(context.Arm64Assembler, baseAddress, baseAddress, offset, true, ArmShiftType.Lsl, 0); + } + } + + public static void Stmda(CodeGenContext context, uint rn, uint registerList, bool w) + { + EmitMemoryMultipleDaInstruction(context, rn, registerList, w, isStore: true, context.Arm64Assembler.StrRiUn, context.Arm64Assembler.StpRiUn); + } + + public static void Stmdb(CodeGenContext context, uint rn, uint registerList, bool w) + { + EmitMemoryMultipleDbInstruction(context, rn, registerList, w, isStore: true, context.Arm64Assembler.StrRiUn, context.Arm64Assembler.StpRiUn); + } + + public static void Stmib(CodeGenContext context, uint rn, uint registerList, bool w) + { + EmitMemoryMultipleIbInstruction(context, rn, registerList, w, isStore: true, context.Arm64Assembler.StrRiUn, context.Arm64Assembler.StpRiUn); + } + + public static void StrI(CodeGenContext context, uint rt, uint rn, int imm, bool p, bool u, bool w) + { + EmitMemoryInstruction(context, rt, rn, imm, 2, p, u, w, isStore: true, context.Arm64Assembler.StrRiUn, context.Arm64Assembler.Stur); + } + + public static void StrR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool p, bool u, bool w) + { + EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, p, u, w, isStore: true, context.Arm64Assembler.StrRiUn, context.Arm64Assembler.Stur); + } + + public static void StrbI(CodeGenContext context, uint rt, uint rn, int imm, bool p, bool u, bool w) + { + EmitMemoryInstruction(context, rt, rn, imm, 0, p, u, w, isStore: true, context.Arm64Assembler.StrbRiUn, context.Arm64Assembler.Sturb); + } + + public static void StrbR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool p, bool u, bool w) + { + EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, p, u, w, isStore: true, context.Arm64Assembler.StrbRiUn, context.Arm64Assembler.Sturb); + } + + public static void StrbtI(CodeGenContext context, uint rt, uint rn, int imm, bool postIndex, bool u) + { + EmitMemoryInstruction(context, rt, rn, imm, 0, !postIndex, u, false, isStore: true, context.Arm64Assembler.StrbRiUn, context.Arm64Assembler.Sturb); + } + + public static void StrbtR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool postIndex, bool u) + { + EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, !postIndex, u, false, isStore: true, context.Arm64Assembler.StrbRiUn, context.Arm64Assembler.Sturb); + } + + public static void StrdI(CodeGenContext context, uint rt, uint rt2, uint rn, uint imm, bool p, bool u, bool w) + { + EmitMemoryDWordInstructionI(context, rt, rt2, rn, imm, p, u, w, isStore: true, context.Arm64Assembler.StpRiUn); + } + + public static void StrdR(CodeGenContext context, uint rt, uint rt2, uint rn, uint rm, bool p, bool u, bool w) + { + EmitMemoryDWordInstructionR(context, rt, rt2, rn, rm, p, u, w, isStore: true, context.Arm64Assembler.StpRiUn); + } + + public static void Strex(CodeGenContext context, uint rd, uint rt, uint rn) + { + EmitMemoryStrexInstruction(context, rd, rt, rn, context.Arm64Assembler.Stlxr); + } + + public static void Strexb(CodeGenContext context, uint rd, uint rt, uint rn) + { + EmitMemoryStrexInstruction(context, rd, rt, rn, context.Arm64Assembler.Stlxrb); + } + + public static void Strexd(CodeGenContext context, uint rd, uint rt, uint rt2, uint rn) + { + EmitMemoryDWordStrexInstruction(context, rd, rt, rt2, rn, context.Arm64Assembler.Stlxp); + } + + public static void Strexh(CodeGenContext context, uint rd, uint rt, uint rn) + { + EmitMemoryStrexInstruction(context, rd, rt, rn, context.Arm64Assembler.Stlxrh); + } + + public static void StrhI(CodeGenContext context, uint rt, uint rn, int imm, bool p, bool u, bool w) + { + EmitMemoryInstruction(context, rt, rn, imm, 1, p, u, w, isStore: true, context.Arm64Assembler.StrhRiUn, context.Arm64Assembler.Sturh); + } + + public static void StrhR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool p, bool u, bool w) + { + EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, p, u, w, isStore: true, context.Arm64Assembler.StrhRiUn, context.Arm64Assembler.Sturh); + } + + public static void StrhtI(CodeGenContext context, uint rt, uint rn, int imm, bool postIndex, bool u) + { + EmitMemoryInstruction(context, rt, rn, imm, 1, !postIndex, u, false, isStore: true, context.Arm64Assembler.StrhRiUn, context.Arm64Assembler.Sturh); + } + + public static void StrhtR(CodeGenContext context, uint rt, uint rn, uint rm, bool postIndex, bool u) + { + EmitMemoryInstruction(context, rt, rn, rm, 0, 0, !postIndex, u, false, isStore: true, context.Arm64Assembler.StrhRiUn, context.Arm64Assembler.Sturh); + } + + public static void StrtI(CodeGenContext context, uint rt, uint rn, int imm, bool postIndex, bool u) + { + EmitMemoryInstruction(context, rt, rn, imm, 2, !postIndex, u, false, isStore: true, context.Arm64Assembler.StrRiUn, context.Arm64Assembler.Stur); + } + + public static void StrtR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool postIndex, bool u) + { + EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, !postIndex, u, false, isStore: true, context.Arm64Assembler.StrRiUn, context.Arm64Assembler.Stur); + } + + private static void EmitMemoryMultipleDaInstruction( + CodeGenContext context, + uint rn, + uint registerList, + bool w, + bool isStore, + Action writeInst, + Action writeInstPair) + { + Operand baseAddress = InstEmitCommon.GetInputGpr(context, rn); + Operand offset; + + if (registerList != 0) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + offset = InstEmitCommon.Const(BitOperations.PopCount(registerList) * 4 - 4); + + WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, baseAddress, offset, false, ArmShiftType.Lsl, 0); + WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand); + + EmitMemoryMultipleInstructionCore( + context, + tempRegister.Operand, + registerList, + isStore, + writeInst, + writeInstPair); + } + + if (w) + { + offset = InstEmitCommon.Const(BitOperations.PopCount(registerList) * 4); + + WriteAddShiftOffset(context.Arm64Assembler, baseAddress, baseAddress, offset, false, ArmShiftType.Lsl, 0); + } + } + + private static void EmitMemoryMultipleDbInstruction( + CodeGenContext context, + uint rn, + uint registerList, + bool w, + bool isStore, + Action writeInst, + Action writeInstPair) + { + Operand baseAddress = InstEmitCommon.GetInputGpr(context, rn); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand offset = InstEmitCommon.Const(BitOperations.PopCount(registerList) * 4); + + bool writesToRn = (registerList & (1u << (int)rn)) != 0; + + if (w && !writesToRn) + { + WriteAddShiftOffset(context.Arm64Assembler, baseAddress, baseAddress, offset, false, ArmShiftType.Lsl, 0); + WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, baseAddress); + } + else + { + WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, baseAddress, offset, false, ArmShiftType.Lsl, 0); + WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand); + } + + EmitMemoryMultipleInstructionCore( + context, + tempRegister.Operand, + registerList, + isStore, + writeInst, + writeInstPair); + + if (w && writesToRn) + { + WriteAddShiftOffset(context.Arm64Assembler, baseAddress, baseAddress, offset, false, ArmShiftType.Lsl, 0); + } + } + + private static void EmitMemoryMultipleIbInstruction( + CodeGenContext context, + uint rn, + uint registerList, + bool w, + bool isStore, + Action writeInst, + Action writeInstPair) + { + Operand baseAddress = InstEmitCommon.GetInputGpr(context, rn); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand offset = InstEmitCommon.Const(4); + + WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, baseAddress, offset, true, ArmShiftType.Lsl, 0); + WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand); + + EmitMemoryMultipleInstructionCore( + context, + tempRegister.Operand, + registerList, + isStore, + writeInst, + writeInstPair); + + if (w) + { + offset = InstEmitCommon.Const(BitOperations.PopCount(registerList) * 4); + + WriteAddShiftOffset(context.Arm64Assembler, baseAddress, baseAddress, offset, true, ArmShiftType.Lsl, 0); + } + } + + private static void EmitMemoryMultipleInstructionCore( + CodeGenContext context, + Operand baseAddress, + uint registerList, + bool isStore, + Action writeInst, + Action writeInstPair) + { + uint registers = registerList; + int offs = 0; + + while (registers != 0) + { + int regIndex = BitOperations.TrailingZeroCount(registers); + + registers &= ~(1u << regIndex); + + Operand rt = isStore + ? InstEmitCommon.GetInputGpr(context, (uint)regIndex) + : InstEmitCommon.GetOutputGpr(context, (uint)regIndex); + + int regIndex2 = BitOperations.TrailingZeroCount(registers); + if (regIndex2 < 32) + { + registers &= ~(1u << regIndex2); + + Operand rt2 = isStore + ? InstEmitCommon.GetInputGpr(context, (uint)regIndex2) + : InstEmitCommon.GetOutputGpr(context, (uint)regIndex2); + + writeInstPair(rt, rt2, baseAddress, offs); + + offs += 8; + } + else + { + writeInst(rt, baseAddress, offs); + + offs += 4; + } + } + } + + private static void EmitMemoryInstruction( + CodeGenContext context, + uint rt, + uint rn, + int imm, + int scale, + bool p, + bool u, + bool w, + bool isStore, + Action writeInst, + Action writeInstUnscaled) + { + Operand rtOperand = isStore ? InstEmitCommon.GetInputGpr(context, rt) : InstEmitCommon.GetOutputGpr(context, rt); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand offset = InstEmitCommon.Const(imm); + + EmitMemoryInstruction(context, writeInst, writeInstUnscaled, rtOperand, rnOperand, offset, scale, p, u, w); + } + + private static void EmitMemoryInstruction( + CodeGenContext context, + uint rt, + uint rn, + uint rm, + uint sType, + uint imm5, + bool p, + bool u, + bool w, + bool isStore, + Action writeInst, + Action writeInstUnscaled) + { + Operand rtOperand = isStore ? InstEmitCommon.GetInputGpr(context, rt) : InstEmitCommon.GetOutputGpr(context, rt); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + EmitMemoryInstruction(context, writeInst, writeInstUnscaled, rtOperand, rnOperand, rmOperand, 0, p, u, w, (ArmShiftType)sType, (int)imm5); + } + + private static void EmitMemoryInstruction(CodeGenContext context, uint rt, uint rn, bool isStore, Action action) + { + Operand rtOperand = isStore ? InstEmitCommon.GetInputGpr(context, rt) : InstEmitCommon.GetOutputGpr(context, rt); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand); + + action(rtOperand, tempRegister.Operand); + } + + private static void EmitMemoryDWordInstruction(CodeGenContext context, uint rt, uint rt2, uint rn, bool isStore, Action action) + { + Operand rtOperand = isStore ? InstEmitCommon.GetInputGpr(context, rt) : InstEmitCommon.GetOutputGpr(context, rt); + Operand rt2Operand = isStore ? InstEmitCommon.GetInputGpr(context, rt2) : InstEmitCommon.GetOutputGpr(context, rt2); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand); + + action(rtOperand, rt2Operand, tempRegister.Operand); + } + + private static void EmitMemoryDWordInstructionI( + CodeGenContext context, + uint rt, + uint rt2, + uint rn, + uint imm, + bool p, + bool u, + bool w, + bool isStore, + Action action) + { + Operand rtOperand = isStore ? InstEmitCommon.GetInputGpr(context, rt) : InstEmitCommon.GetOutputGpr(context, rt); + Operand rt2Operand = isStore ? InstEmitCommon.GetInputGpr(context, rt2) : InstEmitCommon.GetOutputGpr(context, rt2); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand offset = InstEmitCommon.Const((int)imm); + + EmitMemoryDWordInstruction(context, rtOperand, rt2Operand, rnOperand, offset, p, u, w, action); + } + + private static void EmitMemoryDWordInstructionR( + CodeGenContext context, + uint rt, + uint rt2, + uint rn, + uint rm, + bool p, + bool u, + bool w, + bool isStore, + Action action) + { + Operand rtOperand = isStore ? InstEmitCommon.GetInputGpr(context, rt) : InstEmitCommon.GetOutputGpr(context, rt); + Operand rt2Operand = isStore ? InstEmitCommon.GetInputGpr(context, rt2) : InstEmitCommon.GetOutputGpr(context, rt2); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + EmitMemoryDWordInstruction(context, rtOperand, rt2Operand, rnOperand, rmOperand, p, u, w, action); + } + + private static void EmitMemoryDWordInstruction( + CodeGenContext context, + Operand rt, + Operand rt2, + Operand baseAddress, + Operand offset, + bool index, + bool add, + bool wBack, + Action action) + { + Assembler asm = context.Arm64Assembler; + RegisterAllocator regAlloc = context.RegisterAllocator; + + if (index && !wBack) + { + // Offset. + + using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped(); + + int signedOffs = add ? offset.AsInt32() : -offset.AsInt32(); + int offs = 0; + + if (offset.Kind == OperandKind.Constant && offset.Value == 0) + { + WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress); + } + else if (offset.Kind == OperandKind.Constant && CanFoldDWordOffset(context.MemoryManagerType, signedOffs)) + { + WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress); + offs = signedOffs; + } + else + { + WriteAddShiftOffset(asm, tempRegister.Operand, baseAddress, offset, add, ArmShiftType.Lsl, 0); + WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, tempRegister.Operand); + } + + action(rt, rt2, tempRegister.Operand, offs); + } + else if (context.IsThumb ? !index && wBack : !index && !wBack) + { + // Post-indexed. + + using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped(); + + WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress); + + action(rt, rt2, tempRegister.Operand, 0); + + WriteAddShiftOffset(asm, baseAddress, baseAddress, offset, add, ArmShiftType.Lsl, 0); + } + else if (index && wBack) + { + // Pre-indexed. + + using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped(); + + if (rt.Value == baseAddress.Value) + { + // If Rt and Rn are the same register, ensure we perform the write back after the read/write. + + WriteAddShiftOffset(asm, tempRegister.Operand, baseAddress, offset, add, ArmShiftType.Lsl, 0); + WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, tempRegister.Operand); + + action(rt, rt2, tempRegister.Operand, 0); + + context.Arm64Assembler.Mov(baseAddress, tempRegister.Operand); + } + else + { + WriteAddShiftOffset(asm, baseAddress, baseAddress, offset, add, ArmShiftType.Lsl, 0); + WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress); + + action(rt, rt2, tempRegister.Operand, 0); + } + } + } + + private static void EmitMemoryStrexInstruction(CodeGenContext context, uint rd, uint rt, uint rn, Action action) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand); + + action(rdOperand, rtOperand, tempRegister.Operand); + } + + private static void EmitMemoryDWordStrexInstruction(CodeGenContext context, uint rd, uint rt, uint rt2, uint rn, Action action) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt); + Operand rt2Operand = InstEmitCommon.GetInputGpr(context, rt2); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand); + + action(rdOperand, rtOperand, rt2Operand, tempRegister.Operand); + } + + private static void EmitMemoryInstruction( + CodeGenContext context, + Action writeInst, + Action writeInstUnscaled, + Operand rt, + Operand baseAddress, + Operand offset, + int scale, + bool index, + bool add, + bool wBack, + ArmShiftType shiftType = ArmShiftType.Lsl, + int shift = 0) + { + Assembler asm = context.Arm64Assembler; + RegisterAllocator regAlloc = context.RegisterAllocator; + + if (index && !wBack) + { + // Offset. + + using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped(); + + int signedOffs = add ? offset.AsInt32() : -offset.AsInt32(); + int offs = 0; + bool unscaled = false; + + if (offset.Kind == OperandKind.Constant && offset.Value == 0) + { + WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress); + } + else if (offset.Kind == OperandKind.Constant && shift == 0 && CanFoldOffset(context.MemoryManagerType, signedOffs, scale, writeInstUnscaled != null, out unscaled)) + { + WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress); + offs = signedOffs; + } + else + { + WriteAddShiftOffset(asm, tempRegister.Operand, baseAddress, offset, add, shiftType, shift); + WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, tempRegister.Operand); + } + + if (unscaled) + { + writeInstUnscaled(rt, tempRegister.Operand, offs); + } + else + { + writeInst(rt, tempRegister.Operand, offs); + } + } + else if (context.IsThumb ? !index && wBack : !index && !wBack) + { + // Post-indexed. + + if (rt.Type == offset.Type && rt.Value == offset.Value) + { + // If Rt and Rm are the same register, we must ensure we add the register offset (Rm) + // before the value is loaded, otherwise we will be adding the wrong value. + + if (rt.Type != baseAddress.Type || rt.Value != baseAddress.Value) + { + using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped(); + + WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress); + WriteAddShiftOffset(asm, baseAddress, baseAddress, offset, add, shiftType, shift); + + writeInst(rt, tempRegister.Operand, 0); + } + else + { + using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped(); + using ScopedRegister tempRegister2 = regAlloc.AllocateTempGprRegisterScoped(); + + WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress); + WriteAddShiftOffset(asm, tempRegister2.Operand, baseAddress, offset, add, shiftType, shift); + + writeInst(rt, tempRegister.Operand, 0); + + asm.Mov(baseAddress, tempRegister2.Operand); + } + } + else + { + using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped(); + + WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress); + + writeInst(rt, tempRegister.Operand, 0); + + WriteAddShiftOffset(asm, baseAddress, baseAddress, offset, add, shiftType, shift); + } + } + else if (index && wBack) + { + // Pre-indexed. + + using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped(); + + if (rt.Value == baseAddress.Value) + { + // If Rt and Rn are the same register, ensure we perform the write back after the read/write. + + WriteAddShiftOffset(asm, tempRegister.Operand, baseAddress, offset, add, shiftType, shift); + WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, tempRegister.Operand); + + writeInst(rt, tempRegister.Operand, 0); + + context.Arm64Assembler.Mov(baseAddress, tempRegister.Operand); + } + else + { + WriteAddShiftOffset(asm, baseAddress, baseAddress, offset, add, shiftType, shift); + WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress); + + writeInst(rt, tempRegister.Operand, 0); + } + } + else + { + Debug.Fail($"Invalid pre-index and write-back combination."); + } + } + + private static void EmitMemoryLiteralInstruction(CodeGenContext context, uint rt, uint imm, int scale, bool p, bool u, bool w, Action action) + { + if (!p || w) + { + EmitMemoryInstruction(context, rt, RegisterUtils.PcRegister, (int)imm, scale, p, u, w, isStore: false, action, null); + + return; + } + + Operand rtOperand = InstEmitCommon.GetOutputGpr(context, rt); + uint targetAddress = context.Pc & ~3u; + + if (u) + { + targetAddress += imm; + } + else + { + targetAddress -= imm; + } + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, targetAddress); + + action(rtOperand, tempRegister.Operand, 0); + } + + private static void EmitMemoryDWordLiteralInstruction(CodeGenContext context, uint rt, uint rt2, uint imm, bool p, bool u, bool w, Action action) + { + if (!p || w) + { + EmitMemoryDWordInstructionI(context, rt, rt2, RegisterUtils.PcRegister, imm, p, u, w, isStore: false, action); + + return; + } + + Operand rtOperand = InstEmitCommon.GetOutputGpr(context, rt); + Operand rt2Operand = InstEmitCommon.GetOutputGpr(context, rt2); + uint targetAddress = context.Pc & ~3u; + + if (u) + { + targetAddress += imm; + } + else + { + targetAddress -= imm; + } + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, targetAddress); + + action(rtOperand, rt2Operand, tempRegister.Operand, 0); + } + + private static void EmitMemoryPrefetchInstruction(CodeGenContext context, uint rn, uint imm, bool u, PrefetchType type) + { + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + int signedOffs = u ? (int)imm : -(int)imm; + int offs = 0; + bool unscaled = false; + + if (imm == 0) + { + WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand); + } + else if (CanFoldOffset(context.MemoryManagerType, signedOffs, 3, true, out unscaled)) + { + WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand); + offs = signedOffs; + } + else + { + WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, rnOperand, InstEmitCommon.Const((int)imm), u, ArmShiftType.Lsl, 0); + WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand); + } + + if (unscaled) + { + context.Arm64Assembler.Prfum(tempRegister.Operand, offs, (uint)type, 0, 0); + } + else + { + context.Arm64Assembler.PrfmI(tempRegister.Operand, offs, (uint)type, 0, 0); + } + } + + private static void EmitMemoryPrefetchInstruction(CodeGenContext context, uint rn, uint rm, bool u, uint sType, uint shift, PrefetchType type) + { + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, rnOperand, rmOperand, u, (ArmShiftType)sType, (int)shift); + WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand); + + context.Arm64Assembler.PrfmI(tempRegister.Operand, 0, (uint)type, 0, 0); + } + + private static void EmitMemoryPrefetchLiteralInstruction(CodeGenContext context, uint imm, bool u, PrefetchType type) + { + uint targetAddress = context.Pc & ~3u; + + if (u) + { + targetAddress += imm; + } + else + { + targetAddress -= imm; + } + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, targetAddress); + + context.Arm64Assembler.PrfmI(tempRegister.Operand, 0, (uint)type, 0, 0); + } + + public static bool CanFoldOffset(MemoryManagerType mmType, int offset, int scale, bool hasUnscaled, out bool unscaled) + { + if (mmType != MemoryManagerType.HostMappedUnsafe) + { + unscaled = false; + + return false; + } + + int mask = (1 << scale) - 1; + + if ((offset & mask) == 0 && offset >= 0 && offset < 0x1000) + { + // We can use the unsigned, scaled encoding. + + unscaled = false; + + return true; + } + + // Check if we can use the signed, unscaled encoding. + + unscaled = hasUnscaled && offset >= -0x100 && offset < 0x100; + + return unscaled; + } + + private static bool CanFoldDWordOffset(MemoryManagerType mmType, int offset) + { + if (mmType != MemoryManagerType.HostMappedUnsafe) + { + return false; + } + + return offset >= 0 && offset < 0x40 && (offset & 3) == 0; + } + + private static void WriteAddressTranslation(MemoryManagerType mmType, RegisterAllocator regAlloc, in Assembler asm, Operand destination, uint guestAddress) + { + asm.Mov(destination, guestAddress); + + WriteAddressTranslation(mmType, regAlloc, asm, destination, destination); + } + + public static void WriteAddressTranslation(MemoryManagerType mmType, RegisterAllocator regAlloc, in Assembler asm, Operand destination, Operand guestAddress) + { + Operand destination64 = new(destination.Kind, OperandType.I64, destination.Value); + Operand basePointer = new(regAlloc.FixedPageTableRegister, RegisterType.Integer, OperandType.I64); + + if (mmType == MemoryManagerType.HostMapped || mmType == MemoryManagerType.HostMappedUnsafe) + { + // We don't need to mask the address for the safe mode, since it is already naturally limited to 32-bit + // and can never reach out of the guest address space. + + asm.Add(destination64, basePointer, guestAddress); + } + else + { + throw new NotImplementedException(mmType.ToString()); + } + } + + public static void WriteAddShiftOffset(in Assembler asm, Operand rd, Operand rn, Operand offset, bool add, ArmShiftType shiftType, int shift) + { + Debug.Assert(offset.Kind != OperandKind.Constant || offset.AsInt32() >= 0); + + if (shiftType == ArmShiftType.Ror) + { + asm.Ror(rd, rn, InstEmitCommon.Const(shift & 31)); + + if (add) + { + asm.Add(rd, rd, offset, ArmShiftType.Lsl, 0); + } + else + { + asm.Sub(rd, rd, offset, ArmShiftType.Lsl, 0); + } + } + else + { + if (add) + { + asm.Add(rd, rn, offset, shiftType, shift); + } + else + { + asm.Sub(rd, rn, offset, shiftType, shift); + } + } + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMove.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMove.cs new file mode 100644 index 000000000..88850cb33 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMove.cs @@ -0,0 +1,350 @@ +using Ryujinx.Cpu.LightningJit.CodeGen; +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; +using System.Diagnostics; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitMove + { + public static void MvnI(CodeGenContext context, uint rd, uint imm, bool immRotated, bool s) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + + if (s) + { + using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand); + + if (immRotated) + { + if ((imm & (1u << 31)) != 0) + { + context.Arm64Assembler.Orr(flagsRegister.Operand, flagsRegister.Operand, InstEmitCommon.Const(1 << 29)); + } + else + { + context.Arm64Assembler.Bfc(flagsRegister.Operand, 29, 1); + } + } + + context.Arm64Assembler.Mov(rdOperand, ~imm); + context.Arm64Assembler.Tst(rdOperand, rdOperand); + + InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand); + + context.SetNzcvModified(); + } + else + { + context.Arm64Assembler.Mov(rdOperand, ~imm); + } + } + + public static void MvnR(CodeGenContext context, uint rd, uint rm, uint sType, uint imm5, bool s) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + ScopedRegister flagsRegister = default; + + if (s) + { + flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand); + + rmOperand = InstEmitAlu.GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType, flagsRegister.Operand); + } + else + { + rmOperand = InstEmitAlu.GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType); + } + + context.Arm64Assembler.Mvn(rdOperand, rmOperand); + + if (s) + { + InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand); + + flagsRegister.Dispose(); + + context.SetNzcvModified(); + } + } + + public static void MvnRr(CodeGenContext context, uint rd, uint rm, uint sType, uint rs, bool s) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + Operand rsOperand = InstEmitCommon.GetInputGpr(context, rs); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + ScopedRegister flagsRegister = default; + + if (s) + { + flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand); + + rmOperand = InstEmitAlu.GetMShiftedByReg(context, tempRegister.Operand, rmOperand, rsOperand, sType, flagsRegister.Operand); + } + else + { + rmOperand = InstEmitAlu.GetMShiftedByReg(context, tempRegister.Operand, rmOperand, rsOperand, sType); + } + + context.Arm64Assembler.Mvn(rdOperand, rmOperand); + + if (s) + { + InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand); + + flagsRegister.Dispose(); + + context.SetNzcvModified(); + } + } + + public static void MovI(CodeGenContext context, uint rd, uint imm, bool immRotated, bool s) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + + if (s) + { + using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand); + + if (immRotated) + { + if ((imm & (1u << 31)) != 0) + { + context.Arm64Assembler.Orr(flagsRegister.Operand, flagsRegister.Operand, InstEmitCommon.Const(2)); + } + else + { + context.Arm64Assembler.Bfc(flagsRegister.Operand, 1, 1); + } + } + + context.Arm64Assembler.Mov(rdOperand, imm); + context.Arm64Assembler.Tst(rdOperand, rdOperand); + + InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand); + + context.SetNzcvModified(); + } + else + { + context.Arm64Assembler.Mov(rdOperand, imm); + } + } + + public static void MovR(CodeGenContext context, uint rd, uint rm, uint sType, uint imm5, bool s) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + if (InstEmitAlu.CanShift(sType, imm5) && !s) + { + if (imm5 != 0) + { + switch ((ArmShiftType)sType) + { + case ArmShiftType.Lsl: + context.Arm64Assembler.Lsl(rdOperand, rmOperand, InstEmitCommon.Const((int)imm5)); + break; + case ArmShiftType.Lsr: + context.Arm64Assembler.Lsr(rdOperand, rmOperand, InstEmitCommon.Const((int)imm5)); + break; + case ArmShiftType.Asr: + context.Arm64Assembler.Asr(rdOperand, rmOperand, InstEmitCommon.Const((int)imm5)); + break; + case ArmShiftType.Ror: + context.Arm64Assembler.Ror(rdOperand, rmOperand, InstEmitCommon.Const((int)imm5)); + break; + } + } + else + { + context.Arm64Assembler.Mov(rdOperand, rmOperand); + } + } + else + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + ScopedRegister flagsRegister = default; + + if (s) + { + flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand); + + rmOperand = InstEmitAlu.GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType, flagsRegister.Operand); + } + else + { + rmOperand = InstEmitAlu.GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType, null); + } + + context.Arm64Assembler.Mov(rdOperand, rmOperand); + + if (s) + { + context.Arm64Assembler.Tst(rdOperand, rdOperand); + + InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand); + + flagsRegister.Dispose(); + + context.SetNzcvModified(); + } + } + } + + public static void MovR(CodeGenContext context, uint cond, uint rd, uint rm, uint sType, uint imm5, bool s) + { + if (context.ConsumeSkipNextInstruction()) + { + return; + } + + if ((ArmCondition)cond >= ArmCondition.Al || s) + { + MovR(context, rd, rm, sType, imm5, s); + + return; + } + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + if (InstEmitAlu.CanShift(sType, imm5)) + { + if (imm5 != 0) + { + switch ((ArmShiftType)sType) + { + case ArmShiftType.Lsl: + context.Arm64Assembler.Lsl(tempRegister.Operand, rmOperand, InstEmitCommon.Const((int)imm5)); + break; + case ArmShiftType.Lsr: + context.Arm64Assembler.Lsr(tempRegister.Operand, rmOperand, InstEmitCommon.Const((int)imm5)); + break; + case ArmShiftType.Asr: + context.Arm64Assembler.Asr(tempRegister.Operand, rmOperand, InstEmitCommon.Const((int)imm5)); + break; + case ArmShiftType.Ror: + context.Arm64Assembler.Ror(tempRegister.Operand, rmOperand, InstEmitCommon.Const((int)imm5)); + break; + } + + context.Arm64Assembler.Csel(rdOperand, tempRegister.Operand, rdOperand, (ArmCondition)cond); + } + else + { + Operand other = rdOperand; + + InstInfo nextInstruction = context.PeekNextInstruction(); + + if (nextInstruction.Name == InstName.MovR) + { + // If this instruction is followed by another move with the inverse condition, + // we can just put it into the second operand of the CSEL instruction and skip the next move. + + InstCondb28w4Sb20w1Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 nextInst = new(nextInstruction.Encoding); + + if (nextInst.Rd == rd && + nextInst.S == 0 && + nextInst.Stype == 0 && + nextInst.Imm5 == 0 && + nextInst.Cond == (cond ^ 1u) && + nextInst.Rm != RegisterUtils.PcRegister) + { + other = InstEmitCommon.GetInputGpr(context, nextInst.Rm); + context.SetSkipNextInstruction(); + } + } + + context.Arm64Assembler.Csel(rdOperand, rmOperand, other, (ArmCondition)cond); + } + } + else + { + rmOperand = InstEmitAlu.GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType, null); + + context.Arm64Assembler.Csel(rdOperand, rmOperand, rdOperand, (ArmCondition)cond); + } + } + + public static void MovRr(CodeGenContext context, uint rd, uint rm, uint sType, uint rs, bool s) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + Operand rsOperand = InstEmitCommon.GetInputGpr(context, rs); + + if (!s) + { + InstEmitAlu.GetMShiftedByReg(context, rdOperand, rmOperand, rsOperand, sType); + } + else + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand); + + rmOperand = InstEmitAlu.GetMShiftedByReg(context, tempRegister.Operand, rmOperand, rsOperand, sType, flagsRegister.Operand); + + context.Arm64Assembler.Mov(rdOperand, rmOperand); + context.Arm64Assembler.Tst(rdOperand, rdOperand); + + InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand); + + context.SetNzcvModified(); + } + } + + public static void Movt(CodeGenContext context, uint rd, uint imm) + { + Operand rdOperand = InstEmitCommon.GetInputGpr(context, rd); + + context.Arm64Assembler.Movk(rdOperand, (int)imm, 1); + } + + public static void Pkh(CodeGenContext context, uint rd, uint rn, uint rm, bool tb, uint imm5) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + if (!tb && imm5 == 0) + { + context.Arm64Assembler.Extr(rdOperand, rnOperand, rmOperand, 16); + } + else + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + if (tb) + { + context.Arm64Assembler.Asr(tempRegister.Operand, rmOperand, InstEmitCommon.Const(imm5 == 0 ? 31 : (int)imm5)); + context.Arm64Assembler.Extr(rdOperand, tempRegister.Operand, rnOperand, 16); + } + else + { + context.Arm64Assembler.Lsl(tempRegister.Operand, rmOperand, InstEmitCommon.Const((int)imm5)); + context.Arm64Assembler.Extr(rdOperand, rnOperand, tempRegister.Operand, 16); + } + } + + context.Arm64Assembler.Ror(rdOperand, rdOperand, InstEmitCommon.Const(16)); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMultiply.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMultiply.cs new file mode 100644 index 000000000..042ab8157 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMultiply.cs @@ -0,0 +1,603 @@ +using Ryujinx.Cpu.LightningJit.CodeGen; +using System; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitMultiply + { + public static void Mla(CodeGenContext context, uint rd, uint rn, uint rm, uint ra) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + Operand raOperand = InstEmitCommon.GetInputGpr(context, ra); + + context.Arm64Assembler.Madd(rdOperand, rnOperand, rmOperand, raOperand); + } + + public static void Mls(CodeGenContext context, uint rd, uint rn, uint rm, uint ra) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + Operand raOperand = InstEmitCommon.GetInputGpr(context, ra); + + context.Arm64Assembler.Msub(rdOperand, rnOperand, rmOperand, raOperand); + } + + public static void Mul(CodeGenContext context, uint rd, uint rn, uint rm, bool s) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + if (s) + { + using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand); + + context.Arm64Assembler.Mul(rdOperand, rnOperand, rmOperand); + context.Arm64Assembler.Tst(rdOperand, rdOperand); + + InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand); + + context.SetNzcvModified(); + } + else + { + context.Arm64Assembler.Mul(rdOperand, rnOperand, rmOperand); + } + } + + public static void Smlabb(CodeGenContext context, uint rd, uint rn, uint rm, uint ra, bool nHigh, bool mHigh) + { + using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempA = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand tempM64 = new(OperandKind.Register, OperandType.I64, tempM.Operand.Value); + Operand tempA64 = new(OperandKind.Register, OperandType.I64, tempA.Operand.Value); + + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + Operand raOperand = InstEmitCommon.GetInputGpr(context, ra); + + SelectSignedHalfword(context, tempN.Operand, rnOperand, nHigh); + SelectSignedHalfword(context, tempM.Operand, rmOperand, mHigh); + + context.Arm64Assembler.Sxtw(tempA64, raOperand); + context.Arm64Assembler.Smaddl(tempN.Operand, tempN.Operand, tempM.Operand, tempA64); + + CheckResultOverflow(context, tempM64, tempN.Operand); + + context.Arm64Assembler.Mov(rdOperand, tempN.Operand); + } + + public static void Smlad(CodeGenContext context, uint rd, uint rn, uint rm, uint ra, bool x) + { + EmitSmladSmlsd(context, rd, rn, rm, ra, x, add: true); + } + + public static void Smlal(CodeGenContext context, uint rdLo, uint rdHi, uint rn, uint rm, bool s) + { + EmitMultiplyAddLong(context, context.Arm64Assembler.Smaddl, rdLo, rdHi, rn, rm, s); + } + + public static void Smlalbb(CodeGenContext context, uint rdLo, uint rdHi, uint rn, uint rm, bool nHigh, bool mHigh) + { + Operand rdLoOperand = InstEmitCommon.GetOutputGpr(context, rdLo); + Operand rdHiOperand = InstEmitCommon.GetOutputGpr(context, rdHi); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + Operand rdLoOperand64 = new(OperandKind.Register, OperandType.I64, rdLoOperand.Value); + Operand rdHiOperand64 = new(OperandKind.Register, OperandType.I64, rdHiOperand.Value); + + using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempA = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + SelectSignedHalfword(context, tempN.Operand, rnOperand, nHigh); + SelectSignedHalfword(context, tempM.Operand, rmOperand, mHigh); + + Operand tempA64 = new(OperandKind.Register, OperandType.I64, tempA.Operand.Value); + + context.Arm64Assembler.Lsl(tempA64, rdHiOperand64, InstEmitCommon.Const(32)); + context.Arm64Assembler.Orr(tempA64, tempA64, rdLoOperand); + + context.Arm64Assembler.Smaddl(rdLoOperand64, tempN.Operand, tempM.Operand, tempA64); + + if (rdLo != rdHi) + { + context.Arm64Assembler.Lsr(rdHiOperand64, rdLoOperand64, InstEmitCommon.Const(32)); + } + + context.Arm64Assembler.Mov(rdLoOperand, rdLoOperand); // Zero-extend. + } + + public static void Smlald(CodeGenContext context, uint rdLo, uint rdHi, uint rn, uint rm, bool x) + { + EmitSmlaldSmlsld(context, rdLo, rdHi, rn, rm, x, add: true); + } + + public static void Smlawb(CodeGenContext context, uint rd, uint rn, uint rm, uint ra, bool mHigh) + { + using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempA = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand tempN64 = new(OperandKind.Register, OperandType.I64, tempN.Operand.Value); + Operand tempM64 = new(OperandKind.Register, OperandType.I64, tempM.Operand.Value); + Operand tempA64 = new(OperandKind.Register, OperandType.I64, tempA.Operand.Value); + + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + Operand raOperand = InstEmitCommon.GetInputGpr(context, ra); + + SelectSignedHalfword(context, tempM.Operand, rmOperand, mHigh); + + context.Arm64Assembler.Sxtw(tempA64, raOperand); + context.Arm64Assembler.Lsl(tempA64, tempA64, InstEmitCommon.Const(16)); + context.Arm64Assembler.Smaddl(tempN.Operand, rnOperand, tempM.Operand, tempA64); + context.Arm64Assembler.Asr(tempN64, tempN64, InstEmitCommon.Const(16)); + + CheckResultOverflow(context, tempM64, tempN.Operand); + + context.Arm64Assembler.Mov(rdOperand, tempN.Operand); + } + + public static void Smlsd(CodeGenContext context, uint rd, uint rn, uint rm, uint ra, bool x) + { + EmitSmladSmlsd(context, rd, rn, rm, ra, x, add: false); + } + + public static void Smlsld(CodeGenContext context, uint rdLo, uint rdHi, uint rn, uint rm, bool x) + { + EmitSmlaldSmlsld(context, rdLo, rdHi, rn, rm, x, add: false); + } + + public static void Smmla(CodeGenContext context, uint rd, uint rn, uint rm, uint ra, bool r) + { + EmitSmmlaSmmls(context, rd, rn, rm, ra, r, add: true); + } + + public static void Smmls(CodeGenContext context, uint rd, uint rn, uint rm, uint ra, bool r) + { + EmitSmmlaSmmls(context, rd, rn, rm, ra, r, add: false); + } + + public static void Smmul(CodeGenContext context, uint rd, uint rn, uint rm, bool r) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + Operand rdOperand64 = new(OperandKind.Register, OperandType.I64, rdOperand.Value); + + context.Arm64Assembler.Smull(rdOperand64, rnOperand, rmOperand); + + if (r) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Mov(tempRegister.Operand, 0x80000000u); + context.Arm64Assembler.Add(rdOperand64, rdOperand64, tempRegister.Operand); + } + + context.Arm64Assembler.Lsr(rdOperand64, rdOperand64, InstEmitCommon.Const(32)); + } + + public static void Smuad(CodeGenContext context, uint rd, uint rn, uint rm, bool x) + { + EmitSmuadSmusd(context, rd, rn, rm, x, add: true); + } + + public static void Smulbb(CodeGenContext context, uint rd, uint rn, uint rm, bool nHigh, bool mHigh) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + Operand rdOperand64 = new(OperandKind.Register, OperandType.I64, rdOperand.Value); + + using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + SelectSignedHalfword(context, tempN.Operand, rnOperand, nHigh); + SelectSignedHalfword(context, tempM.Operand, rmOperand, mHigh); + + context.Arm64Assembler.Smull(rdOperand64, tempN.Operand, tempM.Operand); + + context.Arm64Assembler.Mov(rdOperand, rdOperand); // Zero-extend. + } + + public static void Smull(CodeGenContext context, uint rdLo, uint rdHi, uint rn, uint rm, bool s) + { + EmitMultiplyLong(context, context.Arm64Assembler.Smull, rdLo, rdHi, rn, rm, s); + } + + public static void Smulwb(CodeGenContext context, uint rd, uint rn, uint rm, bool mHigh) + { + using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand tempN64 = new(OperandKind.Register, OperandType.I64, tempN.Operand.Value); + Operand tempM64 = new(OperandKind.Register, OperandType.I64, tempM.Operand.Value); + + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + SelectSignedHalfword(context, tempM.Operand, rmOperand, mHigh); + + context.Arm64Assembler.Smull(tempN.Operand, rnOperand, tempM.Operand); + context.Arm64Assembler.Asr(tempN64, tempN64, InstEmitCommon.Const(16)); + + CheckResultOverflow(context, tempM64, tempN.Operand); + + context.Arm64Assembler.Mov(rdOperand, tempN.Operand); + } + + public static void Smusd(CodeGenContext context, uint rd, uint rn, uint rm, bool x) + { + EmitSmuadSmusd(context, rd, rn, rm, x, add: false); + } + + public static void Umaal(CodeGenContext context, uint rdLo, uint rdHi, uint rn, uint rm) + { + Operand rdLoOperand = InstEmitCommon.GetOutputGpr(context, rdLo); + Operand rdHiOperand = InstEmitCommon.GetOutputGpr(context, rdHi); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + Operand rdLoOperand64 = new(OperandKind.Register, OperandType.I64, rdLoOperand.Value); + Operand rdHiOperand64 = new(OperandKind.Register, OperandType.I64, rdHiOperand.Value); + + if (rdLo == rdHi) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand tempRegister64 = new(OperandKind.Register, OperandType.I64, tempRegister.Operand.Value); + + context.Arm64Assembler.Umaddl(tempRegister64, rnOperand, rmOperand, rdLoOperand64); + context.Arm64Assembler.Add(rdLoOperand64, tempRegister64, rdHiOperand64); + } + else + { + context.Arm64Assembler.Umaddl(rdLoOperand64, rnOperand, rmOperand, rdLoOperand64); + context.Arm64Assembler.Add(rdLoOperand64, rdLoOperand64, rdHiOperand64); + } + + if (rdLo != rdHi) + { + context.Arm64Assembler.Lsr(rdHiOperand64, rdLoOperand64, InstEmitCommon.Const(32)); + } + + context.Arm64Assembler.Mov(rdLoOperand, rdLoOperand); // Zero-extend. + } + + public static void Umlal(CodeGenContext context, uint rdLo, uint rdHi, uint rn, uint rm, bool s) + { + EmitMultiplyAddLong(context, context.Arm64Assembler.Umaddl, rdLo, rdHi, rn, rm, s); + } + + public static void Umull(CodeGenContext context, uint rdLo, uint rdHi, uint rn, uint rm, bool s) + { + EmitMultiplyLong(context, context.Arm64Assembler.Umull, rdLo, rdHi, rn, rm, s); + } + + private static void EmitMultiplyLong(CodeGenContext context, Action action, uint rdLo, uint rdHi, uint rn, uint rm, bool s) + { + Operand rdLoOperand = InstEmitCommon.GetOutputGpr(context, rdLo); + Operand rdHiOperand = InstEmitCommon.GetOutputGpr(context, rdHi); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + Operand rdLoOperand64 = new(OperandKind.Register, OperandType.I64, rdLoOperand.Value); + Operand rdHiOperand64 = new(OperandKind.Register, OperandType.I64, rdHiOperand.Value); + + if (s) + { + using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand); + + action(rdLoOperand64, rnOperand, rmOperand); + context.Arm64Assembler.Tst(rdLoOperand64, rdLoOperand64); + + InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand); + } + else + { + action(rdLoOperand64, rnOperand, rmOperand); + } + + if (rdLo != rdHi) + { + context.Arm64Assembler.Lsr(rdHiOperand64, rdLoOperand64, InstEmitCommon.Const(32)); + } + + context.Arm64Assembler.Mov(rdLoOperand, rdLoOperand); // Zero-extend. + } + + private static void EmitMultiplyAddLong(CodeGenContext context, Action action, uint rdLo, uint rdHi, uint rn, uint rm, bool s) + { + Operand rdLoOperand = InstEmitCommon.GetOutputGpr(context, rdLo); + Operand rdHiOperand = InstEmitCommon.GetOutputGpr(context, rdHi); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + Operand rdLoOperand64 = new(OperandKind.Register, OperandType.I64, rdLoOperand.Value); + Operand rdHiOperand64 = new(OperandKind.Register, OperandType.I64, rdHiOperand.Value); + + using ScopedRegister raRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand raOperand64 = new(OperandKind.Register, OperandType.I64, raRegister.Operand.Value); + + context.Arm64Assembler.Lsl(raOperand64, rdHiOperand64, InstEmitCommon.Const(32)); + context.Arm64Assembler.Orr(raOperand64, raOperand64, rdLoOperand); + + if (s) + { + using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand); + + action(rdLoOperand64, rnOperand, rmOperand, raOperand64); + context.Arm64Assembler.Tst(rdLoOperand64, rdLoOperand64); + + InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand); + + context.SetNzcvModified(); + } + else + { + action(rdLoOperand64, rnOperand, rmOperand, raOperand64); + } + + if (rdLo != rdHi) + { + context.Arm64Assembler.Lsr(rdHiOperand64, rdLoOperand64, InstEmitCommon.Const(32)); + } + + context.Arm64Assembler.Mov(rdLoOperand, rdLoOperand); // Zero-extend. + } + + private static void EmitSmladSmlsd(CodeGenContext context, uint rd, uint rn, uint rm, uint ra, bool x, bool add) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + Operand raOperand = InstEmitCommon.GetInputGpr(context, ra); + + Operand rdOperand64 = new(OperandKind.Register, OperandType.I64, rdOperand.Value); + + using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempA = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand tempN64 = new(OperandKind.Register, OperandType.I64, tempN.Operand.Value); + Operand tempM64 = new(OperandKind.Register, OperandType.I64, tempM.Operand.Value); + Operand tempA64 = new(OperandKind.Register, OperandType.I64, tempA.Operand.Value); + + ScopedRegister swapTemp = default; + + if (x) + { + swapTemp = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Ror(swapTemp.Operand, rmOperand, InstEmitCommon.Const(16)); + + rmOperand = swapTemp.Operand; + } + + context.Arm64Assembler.Sxth(tempN64, rnOperand); + context.Arm64Assembler.Sxth(tempM64, rmOperand); + context.Arm64Assembler.Sxtw(tempA64, raOperand); + + context.Arm64Assembler.Mul(rdOperand64, tempN64, tempM64); + + context.Arm64Assembler.Asr(tempN.Operand, rnOperand, InstEmitCommon.Const(16)); + context.Arm64Assembler.Asr(tempM.Operand, rmOperand, InstEmitCommon.Const(16)); + + if (add) + { + context.Arm64Assembler.Smaddl(rdOperand64, tempN.Operand, tempM.Operand, rdOperand64); + } + else + { + context.Arm64Assembler.Smsubl(rdOperand64, tempN.Operand, tempM.Operand, rdOperand64); + } + + context.Arm64Assembler.Add(rdOperand64, rdOperand64, tempA64); + + CheckResultOverflow(context, tempM64, rdOperand64); + + context.Arm64Assembler.Mov(rdOperand, rdOperand); // Zero-extend. + + if (x) + { + swapTemp.Dispose(); + } + } + + private static void EmitSmlaldSmlsld(CodeGenContext context, uint rdLo, uint rdHi, uint rn, uint rm, bool x, bool add) + { + Operand rdLoOperand = InstEmitCommon.GetOutputGpr(context, rdLo); + Operand rdHiOperand = InstEmitCommon.GetOutputGpr(context, rdHi); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + Operand rdLoOperand64 = new(OperandKind.Register, OperandType.I64, rdLoOperand.Value); + Operand rdHiOperand64 = new(OperandKind.Register, OperandType.I64, rdHiOperand.Value); + + using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempA = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand tempN64 = new(OperandKind.Register, OperandType.I64, tempN.Operand.Value); + Operand tempM64 = new(OperandKind.Register, OperandType.I64, tempM.Operand.Value); + Operand tempA64 = new(OperandKind.Register, OperandType.I64, tempA.Operand.Value); + + ScopedRegister swapTemp = default; + + if (x) + { + swapTemp = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Ror(swapTemp.Operand, rmOperand, InstEmitCommon.Const(16)); + + rmOperand = swapTemp.Operand; + } + + context.Arm64Assembler.Sxth(tempN64, rnOperand); + context.Arm64Assembler.Sxth(tempM64, rmOperand); + + context.Arm64Assembler.Mul(rdLoOperand64, tempN64, tempM64); + + context.Arm64Assembler.Asr(tempN.Operand, rnOperand, InstEmitCommon.Const(16)); + context.Arm64Assembler.Asr(tempM.Operand, rmOperand, InstEmitCommon.Const(16)); + + if (add) + { + context.Arm64Assembler.Smaddl(rdLoOperand64, tempN.Operand, tempM.Operand, rdLoOperand64); + } + else + { + context.Arm64Assembler.Smsubl(rdLoOperand64, tempN.Operand, tempM.Operand, rdLoOperand64); + } + + context.Arm64Assembler.Lsl(tempA64, rdHiOperand64, InstEmitCommon.Const(32)); + context.Arm64Assembler.Orr(tempA64, tempA64, rdLoOperand); + + context.Arm64Assembler.Add(rdLoOperand64, rdLoOperand64, tempA64); + + if (rdLo != rdHi) + { + context.Arm64Assembler.Lsr(rdHiOperand64, rdLoOperand64, InstEmitCommon.Const(32)); + } + + context.Arm64Assembler.Mov(rdLoOperand, rdLoOperand); // Zero-extend. + + if (x) + { + swapTemp.Dispose(); + } + } + + private static void EmitSmmlaSmmls(CodeGenContext context, uint rd, uint rn, uint rm, uint ra, bool r, bool add) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + Operand raOperand = InstEmitCommon.GetInputGpr(context, ra); + + Operand rdOperand64 = new(OperandKind.Register, OperandType.I64, rdOperand.Value); + Operand raOperand64 = new(OperandKind.Register, OperandType.I64, raOperand.Value); + + using ScopedRegister tempA = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand tempA64 = new(OperandKind.Register, OperandType.I64, tempA.Operand.Value); + + context.Arm64Assembler.Lsl(tempA64, raOperand64, InstEmitCommon.Const(32)); + + if (add) + { + context.Arm64Assembler.Smaddl(rdOperand64, rnOperand, rmOperand, tempA64); + } + else + { + context.Arm64Assembler.Smsubl(rdOperand64, rnOperand, rmOperand, tempA64); + } + + if (r) + { + context.Arm64Assembler.Mov(tempA.Operand, 0x80000000u); + context.Arm64Assembler.Add(rdOperand64, rdOperand64, tempA64); + } + + context.Arm64Assembler.Lsr(rdOperand64, rdOperand64, InstEmitCommon.Const(32)); + } + + private static void EmitSmuadSmusd(CodeGenContext context, uint rd, uint rn, uint rm, bool x, bool add) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + Operand rdOperand64 = new(OperandKind.Register, OperandType.I64, rdOperand.Value); + + using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand tempN64 = new(OperandKind.Register, OperandType.I64, tempN.Operand.Value); + Operand tempM64 = new(OperandKind.Register, OperandType.I64, tempM.Operand.Value); + + ScopedRegister swapTemp = default; + + if (x) + { + swapTemp = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Ror(swapTemp.Operand, rmOperand, InstEmitCommon.Const(16)); + + rmOperand = swapTemp.Operand; + } + + context.Arm64Assembler.Sxth(tempN64, rnOperand); + context.Arm64Assembler.Sxth(tempM64, rmOperand); + + context.Arm64Assembler.Mul(rdOperand64, tempN64, tempM64); + + context.Arm64Assembler.Asr(tempN.Operand, rnOperand, InstEmitCommon.Const(16)); + context.Arm64Assembler.Asr(tempM.Operand, rmOperand, InstEmitCommon.Const(16)); + + if (add) + { + context.Arm64Assembler.Smaddl(rdOperand64, tempN.Operand, tempM.Operand, rdOperand64); + } + else + { + context.Arm64Assembler.Smsubl(rdOperand64, tempN.Operand, tempM.Operand, rdOperand64); + } + + context.Arm64Assembler.Mov(rdOperand, rdOperand); // Zero-extend. + + if (x) + { + swapTemp.Dispose(); + } + } + + private static void SelectSignedHalfword(CodeGenContext context, Operand dest, Operand source, bool high) + { + if (high) + { + context.Arm64Assembler.Asr(dest, source, InstEmitCommon.Const(16)); + } + else + { + context.Arm64Assembler.Sxth(dest, source); + } + } + + private static void CheckResultOverflow(CodeGenContext context, Operand temp64, Operand result) + { + context.Arm64Assembler.Sxtw(temp64, result); + context.Arm64Assembler.Sub(temp64, temp64, result); + + int branchIndex = context.CodeWriter.InstructionPointer; + + context.Arm64Assembler.Cbz(temp64, 0); + + // Set Q flag if we had an overflow. + InstEmitSaturate.SetQFlag(context); + + int delta = context.CodeWriter.InstructionPointer - branchIndex; + context.CodeWriter.WriteInstructionAt(branchIndex, context.CodeWriter.ReadInstructionAt(branchIndex) | (uint)((delta & 0x7ffff) << 5)); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonArithmetic.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonArithmetic.cs new file mode 100644 index 000000000..a59f00fc3 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonArithmetic.cs @@ -0,0 +1,344 @@ +using System; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitNeonArithmetic + { + public static void Vaba(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, u ? context.Arm64Assembler.Uaba : context.Arm64Assembler.Saba, null); + } + + public static void Vabal(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size) + { + InstEmitNeonCommon.EmitVectorBinaryLong(context, rd, rn, rm, size, u ? context.Arm64Assembler.Uabal : context.Arm64Assembler.Sabal); + } + + public static void VabdF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FabdV, context.Arm64Assembler.FabdVH); + } + + public static void VabdI(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, u ? context.Arm64Assembler.Uabd : context.Arm64Assembler.Sabd, null); + } + + public static void Vabdl(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size) + { + InstEmitNeonCommon.EmitVectorBinaryLong(context, rd, rn, rm, size, u ? context.Arm64Assembler.Uabdl : context.Arm64Assembler.Sabdl); + } + + public static void Vabs(CodeGenContext context, uint rd, uint rm, bool f, uint size, uint q) + { + if (f) + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FabsSingleAndDouble, context.Arm64Assembler.FabsHalf); + } + else + { + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.AbsV); + } + } + + public static void VaddF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FaddSingleAndDouble, context.Arm64Assembler.FaddHalf); + } + + public static void VaddI(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, context.Arm64Assembler.AddV, context.Arm64Assembler.AddS); + } + + public static void Vaddhn(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitVectorBinaryNarrow(context, rd, rn, rm, size, context.Arm64Assembler.Addhn); + } + + public static void Vaddl(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size) + { + InstEmitNeonCommon.EmitVectorBinaryLong(context, rd, rn, rm, size, u ? context.Arm64Assembler.Uaddl : context.Arm64Assembler.Saddl); + } + + public static void Vaddw(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size) + { + InstEmitNeonCommon.EmitVectorBinaryWide(context, rd, rn, rm, size, u ? context.Arm64Assembler.Uaddw : context.Arm64Assembler.Saddw); + } + + public static void VfmaF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorTernaryRdF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FmlaVecSingleAndDouble, context.Arm64Assembler.FmlaVecHalf); + } + + public static void VfmsF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorTernaryRdF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FmlsVecSingleAndDouble, context.Arm64Assembler.FmlsVecHalf); + } + + public static void Vhadd(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, u ? context.Arm64Assembler.Uhadd : context.Arm64Assembler.Shadd, null); + } + + public static void Vhsub(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, u ? context.Arm64Assembler.Uhsub : context.Arm64Assembler.Shsub, null); + } + + public static void Vmaxnm(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FmaxnmSingleAndDouble, context.Arm64Assembler.FmaxnmHalf); + } + + public static void VmaxF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FmaxSingleAndDouble, context.Arm64Assembler.FmaxHalf); + } + + public static void VmaxI(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, u ? context.Arm64Assembler.Umax : context.Arm64Assembler.Smax, null); + } + + public static void Vminnm(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FminnmSingleAndDouble, context.Arm64Assembler.FminnmHalf); + } + + public static void VminF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FminSingleAndDouble, context.Arm64Assembler.FminHalf); + } + + public static void VminI(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, u ? context.Arm64Assembler.Umin : context.Arm64Assembler.Smin, null); + } + + public static void VmlaF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorTernaryMulNegRdF(context, rd, rn, rm, sz, q, negProduct: false); + } + + public static void VmlaI(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorTernaryRd(context, rd, rn, rm, size, q, context.Arm64Assembler.MlaVec); + } + + public static void VmlaS(CodeGenContext context, uint rd, uint rn, uint rm, bool f, uint size, uint q) + { + if (f) + { + InstEmitNeonCommon.EmitVectorTernaryMulNegRdByScalarAnyF(context, rd, rn, rm, size, q, negProduct: false); + } + else + { + InstEmitNeonCommon.EmitVectorTernaryRdByScalar(context, rd, rn, rm, size, q, context.Arm64Assembler.MlaElt); + } + } + + public static void VmlalI(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size) + { + InstEmitNeonCommon.EmitVectorTernaryRdLong(context, rd, rn, rm, size, u ? context.Arm64Assembler.UmlalVec : context.Arm64Assembler.SmlalVec); + } + + public static void VmlalS(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size) + { + InstEmitNeonCommon.EmitVectorTernaryRdLongByScalar(context, rd, rn, rm, size, u ? context.Arm64Assembler.UmlalElt : context.Arm64Assembler.SmlalElt); + } + + public static void VmlsF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorTernaryMulNegRdF(context, rd, rn, rm, sz, q, negProduct: true); + } + + public static void VmlsI(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorTernaryRd(context, rd, rn, rm, size, q, context.Arm64Assembler.MlsVec); + } + + public static void VmlsS(CodeGenContext context, uint rd, uint rn, uint rm, bool f, uint size, uint q) + { + if (f) + { + InstEmitNeonCommon.EmitVectorTernaryMulNegRdByScalarAnyF(context, rd, rn, rm, size, q, negProduct: true); + } + else + { + InstEmitNeonCommon.EmitVectorTernaryRdByScalar(context, rd, rn, rm, size, q, context.Arm64Assembler.MlsElt); + } + } + + public static void VmlslI(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size) + { + InstEmitNeonCommon.EmitVectorTernaryRdLong(context, rd, rn, rm, size, u ? context.Arm64Assembler.UmlslVec : context.Arm64Assembler.SmlslVec); + } + + public static void VmlslS(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size) + { + InstEmitNeonCommon.EmitVectorTernaryRdLongByScalar(context, rd, rn, rm, size, u ? context.Arm64Assembler.UmlslElt : context.Arm64Assembler.SmlslElt); + } + + public static void VmulF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FmulVecSingleAndDouble, context.Arm64Assembler.FmulVecHalf); + } + + public static void VmulI(CodeGenContext context, uint rd, uint rn, uint rm, bool op, uint size, uint q) + { + if (op) + { + // TODO: Feature check, emulation if not supported. + + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, context.Arm64Assembler.Pmul, null); + } + else + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, context.Arm64Assembler.MulVec, null); + } + } + + public static void VmulS(CodeGenContext context, uint rd, uint rn, uint rm, bool f, uint size, uint q) + { + if (f) + { + InstEmitNeonCommon.EmitVectorBinaryByScalarAnyF(context, rd, rn, rm, size, q, context.Arm64Assembler.FmulElt2regElementSingleAndDouble, context.Arm64Assembler.FmulElt2regElementHalf); + } + else + { + InstEmitNeonCommon.EmitVectorBinaryByScalar(context, rd, rn, rm, size, q, context.Arm64Assembler.MulElt); + } + } + + public static void VmullI(CodeGenContext context, uint rd, uint rn, uint rm, bool op, bool u, uint size) + { + if (op) + { + // TODO: Feature check, emulation if not supported. + + InstEmitNeonCommon.EmitVectorBinaryLong(context, rd, rn, rm, size == 2 ? 3 : size, context.Arm64Assembler.Pmull); + } + else + { + InstEmitNeonCommon.EmitVectorBinaryLong(context, rd, rn, rm, size, u ? context.Arm64Assembler.UmullVec : context.Arm64Assembler.SmullVec); + } + } + + public static void VmullS(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size) + { + InstEmitNeonCommon.EmitVectorBinaryLongByScalar(context, rd, rn, rm, size, u ? context.Arm64Assembler.UmullElt : context.Arm64Assembler.SmullElt); + } + + public static void Vneg(CodeGenContext context, uint rd, uint rm, bool f, uint size, uint q) + { + if (f) + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FnegSingleAndDouble, context.Arm64Assembler.FnegHalf); + } + else + { + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.NegV); + } + } + + public static void Vpadal(CodeGenContext context, uint rd, uint rm, bool op, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinaryRd(context, rd, rm, size, q, op ? context.Arm64Assembler.Uadalp : context.Arm64Assembler.Sadalp); + } + + public static void VpaddF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FaddpVecSingleAndDouble, context.Arm64Assembler.FaddpVecHalf); + } + + public static void VpaddI(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, context.Arm64Assembler.AddpVec, null); + } + + public static void Vpaddl(CodeGenContext context, uint rd, uint rm, bool op, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, op ? context.Arm64Assembler.Uaddlp : context.Arm64Assembler.Saddlp); + } + + public static void VpmaxF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FmaxpVecSingleAndDouble, context.Arm64Assembler.FmaxpVecHalf); + } + + public static void VpmaxI(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, u ? context.Arm64Assembler.Umaxp : context.Arm64Assembler.Smaxp, null); + } + + public static void VpminF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FminpVecSingleAndDouble, context.Arm64Assembler.FminpVecHalf); + } + + public static void VpminI(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, u ? context.Arm64Assembler.Uminp : context.Arm64Assembler.Sminp, null); + } + + public static void Vrecpe(CodeGenContext context, uint rd, uint rm, bool f, uint size, uint q) + { + if (f) + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FrecpeV, context.Arm64Assembler.FrecpeVH); + } + else + { + throw new NotImplementedException(); + } + } + + public static void Vrecps(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FrecpsV, context.Arm64Assembler.FrecpsVH); + } + + public static void Vrsqrte(CodeGenContext context, uint rd, uint rm, bool f, uint size, uint q) + { + if (f) + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FrsqrteV, context.Arm64Assembler.FrsqrteVH); + } + else + { + throw new NotImplementedException(); + } + } + + public static void Vrsqrts(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FrsqrtsV, context.Arm64Assembler.FrsqrtsVH); + } + + public static void VsubF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FsubSingleAndDouble, context.Arm64Assembler.FsubHalf); + } + + public static void VsubI(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, context.Arm64Assembler.SubV, context.Arm64Assembler.SubS); + } + + public static void Vsubhn(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitVectorBinaryNarrow(context, rd, rn, rm, size, context.Arm64Assembler.Subhn); + } + + public static void Vsubl(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size) + { + InstEmitNeonCommon.EmitVectorBinaryLong(context, rd, rn, rm, size, u ? context.Arm64Assembler.Usubl : context.Arm64Assembler.Ssubl); + } + + public static void Vsubw(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size) + { + InstEmitNeonCommon.EmitVectorBinaryWide(context, rd, rn, rm, size, u ? context.Arm64Assembler.Usubw : context.Arm64Assembler.Ssubw); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonBit.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonBit.cs new file mode 100644 index 000000000..9601f4c27 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonBit.cs @@ -0,0 +1,35 @@ +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitNeonBit + { + public static void Vcls(CodeGenContext context, uint rd, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.Cls); + } + + public static void Vclz(CodeGenContext context, uint rd, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.Clz); + } + + public static void Vcnt(CodeGenContext context, uint rd, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.Cnt); + } + + public static void Vrev16(CodeGenContext context, uint rd, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.Rev16); + } + + public static void Vrev32(CodeGenContext context, uint rd, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.Rev32); + } + + public static void Vrev64(CodeGenContext context, uint rd, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.Rev64); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonCommon.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonCommon.cs new file mode 100644 index 000000000..dce6556e4 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonCommon.cs @@ -0,0 +1,1513 @@ + +using Ryujinx.Cpu.LightningJit.CodeGen; +using System; +using System.Diagnostics; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitNeonCommon + { + public static ScopedRegister MoveScalarToSide(CodeGenContext context, uint srcReg, bool isFP32, bool forceAllocation = false) + { + int shift = isFP32 ? 2 : 1; + uint mask = isFP32 ? 3u : 1u; + uint elt = srcReg & mask; + + if (elt == 0 && !forceAllocation) + { + return new ScopedRegister(context.RegisterAllocator, context.RegisterAllocator.RemapFpRegister((int)(srcReg >> shift), isFP32), false); + } + + Operand source = context.RegisterAllocator.RemapSimdRegister((int)(srcReg >> shift)); + ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempFpRegisterScoped(isFP32); + + uint imm5 = GetImm5ForElementIndex(elt, isFP32); + + context.Arm64Assembler.DupEltScalarFromElement(tempRegister.Operand, source, imm5); + + return tempRegister; + } + + public static ScopedRegister Move16BitScalarToSide(CodeGenContext context, uint srcReg, bool top = false) + { + uint elt = srcReg & 3; + + Operand source = context.RegisterAllocator.RemapSimdRegister((int)(srcReg >> 2)); + ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempFpRegisterScoped(true); + + uint imm5 = GetImm5ForElementIndex((elt << 1) | (top ? 1u : 0u), 1); + + context.Arm64Assembler.DupEltScalarFromElement(tempRegister.Operand, source, imm5); + + return tempRegister; + } + + public static void MoveScalarToSide(CodeGenContext context, Operand dest, uint srcReg, bool isFP32) + { + int shift = isFP32 ? 2 : 1; + uint mask = isFP32 ? 3u : 1u; + uint elt = srcReg & mask; + + Operand source = context.RegisterAllocator.RemapSimdRegister((int)(srcReg >> shift)); + + uint imm5 = GetImm5ForElementIndex(elt, isFP32); + + context.Arm64Assembler.DupEltScalarFromElement(dest, source, imm5); + } + + public static ScopedRegister MoveScalarToSideIntoGpr(CodeGenContext context, uint srcReg, bool isFP32) + { + int shift = isFP32 ? 2 : 1; + uint mask = isFP32 ? 3u : 1u; + uint elt = srcReg & mask; + + Operand source = context.RegisterAllocator.RemapSimdRegister((int)(srcReg >> shift)); + ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Umov(tempRegister.Operand, source, (int)elt, isFP32 ? 2 : 3); + + return tempRegister; + } + + public static void InsertResult(CodeGenContext context, Operand source, uint dstReg, bool isFP32) + { + int shift = isFP32 ? 2 : 1; + uint mask = isFP32 ? 3u : 1u; + uint elt = dstReg & mask; + + uint imm5 = GetImm5ForElementIndex(elt, isFP32); + + Operand dest = context.RegisterAllocator.RemapSimdRegister((int)(dstReg >> shift)); + + context.Arm64Assembler.InsElt(dest, source, 0, imm5); + } + + public static void Insert16BitResult(CodeGenContext context, Operand source, uint dstReg, bool top = false) + { + uint elt = dstReg & 3u; + + uint imm5 = GetImm5ForElementIndex((elt << 1) | (top ? 1u : 0u), 1); + + Operand dest = context.RegisterAllocator.RemapSimdRegister((int)(dstReg >> 2)); + + context.Arm64Assembler.InsElt(dest, source, 0, imm5); + } + + public static void InsertResultFromGpr(CodeGenContext context, Operand source, uint dstReg, bool isFP32) + { + int shift = isFP32 ? 2 : 1; + uint mask = isFP32 ? 3u : 1u; + uint elt = dstReg & mask; + + uint imm5 = GetImm5ForElementIndex(elt, isFP32); + + Operand dest = context.RegisterAllocator.RemapSimdRegister((int)(dstReg >> shift)); + + context.Arm64Assembler.InsGen(dest, source, imm5); + } + + public static uint GetImm5ForElementIndex(uint elt, bool isFP32) + { + return isFP32 ? (4u | (elt << 3)) : (8u | (elt << 4)); + } + + public static uint GetImm5ForElementIndex(uint elt, uint size) + { + return (1u << (int)size) | (elt << ((int)size + 1)); + } + + public static void EmitScalarUnaryF(CodeGenContext context, uint rd, uint rm, uint size, Action action) + { + Debug.Assert(size == 1 || size == 2 || size == 3); + + bool singleRegs = size != 3; + + using ScopedRegister rmReg = MoveScalarToSide(context, rm, singleRegs); + + using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rmReg); + + action(tempRegister.Operand, rmReg.Operand, size ^ 2u); + + InsertResult(context, tempRegister.Operand, rd, singleRegs); + } + + public static void EmitScalarUnaryF(CodeGenContext context, uint rd, uint rm, uint size, Action action, Action actionHalf) + { + Debug.Assert(size == 1 || size == 2 || size == 3); + + bool singleRegs = size != 3; + + using ScopedRegister rmReg = MoveScalarToSide(context, rm, singleRegs); + + using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rmReg); + + if (size == 1) + { + actionHalf(tempRegister.Operand, rmReg.Operand); + } + else + { + action(tempRegister.Operand, rmReg.Operand, size & 1); + } + + InsertResult(context, tempRegister.Operand, rd, singleRegs); + } + + public static void EmitScalarUnaryToGprTempF( + CodeGenContext context, + uint rd, + uint rm, + uint size, + uint sf, + Action action) + { + Debug.Assert(size == 1 || size == 2 || size == 3); + + bool singleRegs = size != 3; + + using ScopedRegister rmReg = MoveScalarToSide(context, rm, singleRegs); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + action(tempRegister.Operand, rmReg.Operand, size ^ 2u, sf); + + InsertResultFromGpr(context, tempRegister.Operand, rd, sf == 0); + } + + public static void EmitScalarUnaryFromGprTempF( + CodeGenContext context, + uint rd, + uint rm, + uint size, + uint sf, + Action action) + { + Debug.Assert(size == 1 || size == 2 || size == 3); + + bool singleRegs = size != 3; + + using ScopedRegister rmReg = MoveScalarToSideIntoGpr(context, rm, sf == 0); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + action(tempRegister.Operand, rmReg.Operand, size ^ 2u, sf); + + InsertResult(context, tempRegister.Operand, rd, singleRegs); + } + + public static void EmitScalarUnaryFixedF(CodeGenContext context, uint rd, uint rm, uint fbits, uint size, bool is16Bit, Action action) + { + Debug.Assert(size == 1 || size == 2 || size == 3); + + bool singleRegs = size != 3; + + (uint immb, uint immh) = GetImmbImmh(fbits, size); + + using ScopedRegister rmReg = is16Bit ? Move16BitScalarToSide(context, rm) : MoveScalarToSide(context, rm, singleRegs); + + using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rmReg); + + action(tempRegister.Operand, rmReg.Operand, immb, immh); + + InsertResult(context, tempRegister.Operand, rd, singleRegs); + } + + public static void EmitScalarBinaryF(CodeGenContext context, uint rd, uint rn, uint rm, uint size, Action action) + { + Debug.Assert(size == 1 || size == 2 || size == 3); + + bool singleRegs = size != 3; + + using ScopedRegister rnReg = MoveScalarToSide(context, rn, singleRegs); + using ScopedRegister rmReg = MoveScalarToSide(context, rm, singleRegs); + + using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rnReg, rmReg); + + action(tempRegister.Operand, rnReg.Operand, rmReg.Operand, size ^ 2u); + + InsertResult(context, tempRegister.Operand, rd, singleRegs); + } + + public static void EmitScalarBinaryShift( + CodeGenContext context, + uint rd, + uint rm, + uint shift, + uint size, + bool isShl, + Action action) + { + bool singleRegs = size != 3; + + (uint immb, uint immh) = GetImmbImmhForShift(shift, size, isShl); + + using ScopedRegister rmReg = MoveScalarToSide(context, rm, singleRegs); + + using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rmReg); + + action(tempRegister.Operand, rmReg.Operand, immb, immh); + + InsertResult(context, tempRegister.Operand, rd, singleRegs); + } + + public static void EmitScalarTernaryRdF(CodeGenContext context, uint rd, uint rn, uint rm, uint size, Action action) + { + Debug.Assert(size == 1 || size == 2 || size == 3); + + bool singleRegs = size != 3; + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + MoveScalarToSide(context, tempRegister.Operand, rd, singleRegs); + + using ScopedRegister rnReg = MoveScalarToSide(context, rn, singleRegs); + using ScopedRegister rmReg = MoveScalarToSide(context, rm, singleRegs); + + action(tempRegister.Operand, rnReg.Operand, rmReg.Operand, size ^ 2u); + + InsertResult(context, tempRegister.Operand, rd, singleRegs); + } + + public static void EmitScalarTernaryRdF( + CodeGenContext context, + uint rd, + uint rn, + uint rm, + uint size, + Action action) + { + Debug.Assert(size == 1 || size == 2 || size == 3); + + bool singleRegs = size != 3; + + using ScopedRegister rdReg = MoveScalarToSide(context, rd, singleRegs); + using ScopedRegister rnReg = MoveScalarToSide(context, rn, singleRegs); + using ScopedRegister rmReg = MoveScalarToSide(context, rm, singleRegs); + + using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rdReg, rnReg, rmReg); + + action(tempRegister.Operand, rnReg.Operand, rmReg.Operand, rdReg.Operand, size ^ 2u); + + InsertResult(context, tempRegister.Operand, rd, singleRegs); + } + + public static void EmitScalarTernaryMulNegRdF( + CodeGenContext context, + uint rd, + uint rn, + uint rm, + uint size, + bool negD, + bool negProduct) + { + Debug.Assert(size == 1 || size == 2 || size == 3); + + bool singleRegs = size != 3; + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + MoveScalarToSide(context, tempRegister.Operand, rd, singleRegs); + + using ScopedRegister rnReg = MoveScalarToSide(context, rn, singleRegs); + using ScopedRegister rmReg = MoveScalarToSide(context, rm, singleRegs); + + using ScopedRegister productRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + uint ftype = size ^ 2u; + + context.Arm64Assembler.FmulFloat(productRegister.Operand, rnReg.Operand, rmReg.Operand, ftype); + + if (negD) + { + context.Arm64Assembler.FnegFloat(tempRegister.Operand, tempRegister.Operand, ftype); + } + + if (negProduct) + { + context.Arm64Assembler.FnegFloat(productRegister.Operand, productRegister.Operand, ftype); + } + + context.Arm64Assembler.FaddFloat(tempRegister.Operand, tempRegister.Operand, productRegister.Operand, ftype); + + InsertResult(context, tempRegister.Operand, rd, singleRegs); + } + + public static void EmitVectorUnary(CodeGenContext context, uint rd, uint rm, Action action) + { + Debug.Assert(((rd | rm) & 1) == 0); + + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + action(rdOperand, rmOperand); + } + + public static void EmitVectorUnary(CodeGenContext context, uint rd, uint rm, uint q, Action action) + { + if (q == 0) + { + using ScopedRegister rmReg = MoveScalarToSide(context, rm, false); + + using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rmReg); + + action(tempRegister.Operand, rmReg.Operand, q); + + InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + action(rdOperand, rmOperand, q); + } + } + + public static void EmitVectorUnary(CodeGenContext context, uint rd, uint rm, uint size, uint q, Action action) + { + Debug.Assert(size < 3); + + if (q == 0) + { + using ScopedRegister rmReg = MoveScalarToSide(context, rm, false); + + using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rmReg); + + action(tempRegister.Operand, rmReg.Operand, size, q); + + InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + action(rdOperand, rmOperand, size, q); + } + } + + public static void EmitVectorUnaryLong(CodeGenContext context, uint rd, uint rm, uint size, Action action) + { + Debug.Assert((rd & 1) == 0); + + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + uint q = rm & 1; + + action(rdOperand, rmOperand, size, q); + } + + public static void EmitVectorUnaryNarrow(CodeGenContext context, uint rd, uint rm, uint size, Action action) + { + Debug.Assert((rm & 1) == 0); + + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + uint q = rd & 1; + + if (q == 0) + { + // Writing to the lower half would clear the higher bits, we don't want that, so use a temp register and move the element. + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + action(tempRegister.Operand, rmOperand, size, q); + + InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + action(rdOperand, rmOperand, size, q); + } + } + + public static void EmitVectorBinary(CodeGenContext context, uint rd, uint rn, uint rm, Action action) + { + Debug.Assert(((rd | rn | rm) & 1) == 0); + + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + action(rdOperand, rnOperand, rmOperand); + } + + public static void EmitVectorBinary(CodeGenContext context, uint rd, uint rn, uint rm, uint q, Action action) + { + if (q == 0) + { + using ScopedRegister rnReg = MoveScalarToSide(context, rn, false); + using ScopedRegister rmReg = MoveScalarToSide(context, rm, false); + + using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rnReg, rmReg); + + action(tempRegister.Operand, rnReg.Operand, rmReg.Operand, q); + + InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + action(rdOperand, rnOperand, rmOperand, q); + } + } + + public static void EmitVectorBinary( + CodeGenContext context, + uint rd, + uint rn, + uint rm, + uint size, + uint q, + Action action, + Action actionScalar) + { + Debug.Assert(size <= 3); + + if (q == 0) + { + using ScopedRegister rnReg = MoveScalarToSide(context, rn, false); + using ScopedRegister rmReg = MoveScalarToSide(context, rm, false); + + using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rnReg, rmReg); + + if (size == 3) + { + actionScalar(tempRegister.Operand, rnReg.Operand, rmReg.Operand, size); + } + else + { + action(tempRegister.Operand, rnReg.Operand, rmReg.Operand, size, q); + } + + InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + action(rdOperand, rnOperand, rmOperand, size, q); + } + } + + public static void EmitVectorBinaryRd(CodeGenContext context, uint rd, uint rm, uint size, uint q, Action action) + { + Debug.Assert(size < 3); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + MoveScalarToSide(context, tempRegister.Operand, rd, false); + + using ScopedRegister rmReg = MoveScalarToSide(context, rm, false); + + action(tempRegister.Operand, rmReg.Operand, size, q); + + InsertResult(context, tempRegister.Operand, rd, false); + } + + public static void EmitVectorBinaryShift( + CodeGenContext context, + uint rd, + uint rm, + uint shift, + uint size, + uint q, + bool isShl, + Action action, + Action actionScalar) + { + (uint immb, uint immh) = GetImmbImmhForShift(shift, size, isShl); + + if (q == 0) + { + using ScopedRegister rmReg = MoveScalarToSide(context, rm, false); + + using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rmReg); + + if (size == 3) + { + actionScalar(tempRegister.Operand, rmReg.Operand, immb, immh); + } + else + { + action(tempRegister.Operand, rmReg.Operand, immb, immh, q); + } + + InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + action(rdOperand, rmOperand, immb, immh, q); + } + } + + public static void EmitVectorBinaryLong(CodeGenContext context, uint rd, uint rn, uint rm, uint size, Action action) + { + Debug.Assert((rd & 1) == 0); + + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + + if ((rn & 1) == (rm & 1)) + { + // Both inputs are on the same side of the vector, so we can use the variant that selects the half. + + Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + uint q = rn & 1; + + action(rdOperand, rnOperand, rmOperand, size, q); + } + else + { + // Inputs are on different sides of the vector, we have to move them. + + using ScopedRegister rnReg = MoveScalarToSide(context, rn, false); + using ScopedRegister rmReg = MoveScalarToSide(context, rm, false); + + action(rdOperand, rnReg.Operand, rmReg.Operand, size, 0); + } + } + + public static void EmitVectorBinaryLongShift( + CodeGenContext context, + uint rd, + uint rn, + uint shift, + uint size, + bool isShl, + Action action) + { + (uint immb, uint immh) = GetImmbImmhForShift(shift, size, isShl); + + Debug.Assert((rd & 1) == 0); + + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1)); + + uint q = rn & 1; + + action(rdOperand, rnOperand, immb, immh, q); + } + + public static void EmitVectorBinaryLongByScalar( + CodeGenContext context, + uint rd, + uint rn, + uint rm, + uint size, + Action action) + { + Debug.Assert((rd & 1) == 0); + + (uint h, uint l, uint m) = GetIndexForReg(ref rm, size); + + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + uint q = rn & 1; + + action(rdOperand, rnOperand, h, rmOperand, m, l, size, q); + } + + public static void EmitVectorBinaryNarrow( + CodeGenContext context, + uint rd, + uint rn, + uint rm, + uint size, + Action action) + { + Debug.Assert((rn & 1) == 0); + Debug.Assert((rm & 1) == 0); + + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + uint q = rd & 1; + + if (q == 0) + { + // Writing to the lower half would clear the higher bits, we don't want that, so use a temp register and move the element. + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + action(tempRegister.Operand, rnOperand, rmOperand, size, q); + + InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + action(rdOperand, rnOperand, rmOperand, size, q); + } + } + + public static void EmitVectorBinaryNarrowShift( + CodeGenContext context, + uint rd, + uint rm, + uint shift, + uint size, + bool isShl, + Action action) + { + (uint immb, uint immh) = GetImmbImmhForShift(shift, size, isShl); + + Debug.Assert((rm & 1) == 0); + + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + uint q = rd & 1; + + if (q == 0) + { + // Writing to the lower half would clear the higher bits, we don't want that, so use a temp register and move the element. + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + action(tempRegister.Operand, rmOperand, immb, immh, q); + + InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + action(rdOperand, rmOperand, immb, immh, q); + } + } + + public static void EmitVectorBinaryWide(CodeGenContext context, uint rd, uint rn, uint rm, uint size, Action action) + { + Debug.Assert(((rd | rn) & 1) == 0); + + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + uint q = rm & 1; + + action(rdOperand, rnOperand, rmOperand, size, q); + } + + public static void EmitVectorBinaryByScalar( + CodeGenContext context, + uint rd, + uint rn, + uint rm, + uint size, + uint q, + Action action) + { + EmitVectorByScalarCore(context, rd, rn, rm, size, q, action, isTernary: false); + } + + public static void EmitVectorTernaryRd(CodeGenContext context, uint rd, uint rn, uint rm, uint q, Action action) + { + if (q == 0) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + MoveScalarToSide(context, tempRegister.Operand, rd, false); + + using ScopedRegister rnReg = MoveScalarToSide(context, rn, false); + using ScopedRegister rmReg = MoveScalarToSide(context, rm, false); + + action(tempRegister.Operand, rnReg.Operand, rmReg.Operand, q); + + InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + action(rdOperand, rnOperand, rmOperand, q); + } + } + + public static void EmitVectorTernaryRd(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q, Action action) + { + if (q == 0) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + MoveScalarToSide(context, tempRegister.Operand, rd, false); + + using ScopedRegister rnReg = MoveScalarToSide(context, rn, false); + using ScopedRegister rmReg = MoveScalarToSide(context, rm, false); + + action(tempRegister.Operand, rnReg.Operand, rmReg.Operand, size, q); + + InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + action(rdOperand, rnOperand, rmOperand, size, q); + } + } + + public static void EmitVectorTernaryRdLong(CodeGenContext context, uint rd, uint rn, uint rm, uint size, Action action) + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + + if ((rn & 1) == (rm & 1)) + { + // Both inputs are on the same side of the vector, so we can use the variant that selects the half. + + Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + uint q = rn & 1; + + action(rdOperand, rnOperand, rmOperand, size, q); + } + else + { + // Inputs are on different sides of the vector, we have to move them. + + using ScopedRegister rnReg = MoveScalarToSide(context, rn, false); + using ScopedRegister rmReg = MoveScalarToSide(context, rm, false); + + action(rdOperand, rnReg.Operand, rmReg.Operand, size, 0); + } + } + + public static void EmitVectorTernaryRdLongByScalar( + CodeGenContext context, + uint rd, + uint rn, + uint rm, + uint size, + Action action) + { + (uint h, uint l, uint m) = GetIndexForReg(ref rm, size); + + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + uint q = rn & 1; + + action(rdOperand, rnOperand, h, rmOperand, m, l, size, q); + } + + public static void EmitVectorTernaryRdShift( + CodeGenContext context, + uint rd, + uint rm, + uint shift, + uint size, + uint q, + bool isShl, + Action action, + Action actionScalar) + { + (uint immb, uint immh) = GetImmbImmhForShift(shift, size, isShl); + + if (q == 0) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + MoveScalarToSide(context, tempRegister.Operand, rd, false); + + using ScopedRegister rmReg = MoveScalarToSide(context, rm, false); + + if (size == 3) + { + actionScalar(tempRegister.Operand, rmReg.Operand, immb, immh); + } + else + { + action(tempRegister.Operand, rmReg.Operand, immb, immh, q); + } + + InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + action(rdOperand, rmOperand, immb, immh, q); + } + } + + public static void EmitVectorTernaryRdByScalar( + CodeGenContext context, + uint rd, + uint rn, + uint rm, + uint size, + uint q, + Action action) + { + EmitVectorByScalarCore(context, rd, rn, rm, size, q, action, isTernary: true); + } + + private static void EmitVectorByScalarCore( + CodeGenContext context, + uint rd, + uint rn, + uint rm, + uint size, + uint q, + Action action, + bool isTernary) + { + (uint h, uint l, uint m) = GetIndexForReg(ref rm, size); + + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + if (q == 0) + { + if (isTernary) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + MoveScalarToSide(context, tempRegister.Operand, rd, false); + + using ScopedRegister rnReg = MoveScalarToSide(context, rn, false); + + action(tempRegister.Operand, rnReg.Operand, h, rmOperand, m, l, size, q); + + InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + using ScopedRegister rnReg = MoveScalarToSide(context, rn, false); + + using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rnReg); + + action(tempRegister.Operand, rnReg.Operand, h, rmOperand, m, l, size, q); + + InsertResult(context, tempRegister.Operand, rd, false); + } + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1)); + + action(rdOperand, rnOperand, h, rmOperand, m, l, size, q); + } + } + + public static void EmitVectorUnaryF( + CodeGenContext context, + uint rd, + uint rm, + uint sz, + uint q, + Action action, + Action actionHalf) + { + Debug.Assert(sz == 0 || sz == 1); + + if (q == 0) + { + using ScopedRegister rmReg = MoveScalarToSide(context, rm, false); + + using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rmReg); + + if (sz == 1) + { + actionHalf(tempRegister.Operand, rmReg.Operand, q); + } + else + { + action(tempRegister.Operand, rmReg.Operand, 0, q); + } + + InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + if (sz == 1) + { + actionHalf(rdOperand, rmOperand, q); + } + else + { + action(rdOperand, rmOperand, 0, q); + } + } + } + + public static void EmitVectorUnaryAnyF( + CodeGenContext context, + uint rd, + uint rm, + uint size, + uint q, + Action action, + Action actionHalf) + { + Debug.Assert(size == 1 || size == 2 || size == 3); + Debug.Assert(size != 3 || q == 1); + + if (q == 0) + { + using ScopedRegister rmReg = MoveScalarToSide(context, rm, false); + + using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rmReg); + + if (size == 1) + { + actionHalf(tempRegister.Operand, rmReg.Operand, q); + } + else + { + action(tempRegister.Operand, rmReg.Operand, size ^ 2u, q); + } + + InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + if (size == 1) + { + actionHalf(rdOperand, rmOperand, q); + } + else + { + action(rdOperand, rmOperand, size ^ 2u, q); + } + } + } + + public static void EmitVectorUnaryFixedAnyF( + CodeGenContext context, + uint rd, + uint rm, + uint fbits, + uint size, + uint q, + Action action) + { + Debug.Assert(size == 1 || size == 2 || size == 3); + Debug.Assert(size != 3 || q == 1); + + (uint immb, uint immh) = GetImmbImmh(fbits, size); + + if (q == 0) + { + using ScopedRegister rmReg = MoveScalarToSide(context, rm, false); + using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rmReg); + + action(tempRegister.Operand, rmReg.Operand, immb, immh, q); + + InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + action(rdOperand, rmOperand, immb, immh, q); + } + } + + public static void EmitVectorBinaryF( + CodeGenContext context, + uint rd, + uint rn, + uint rm, + uint sz, + uint q, + Action action, + Action actionHalf) + { + Debug.Assert(sz == 0 || sz == 1); + + if (q == 0) + { + using ScopedRegister rnReg = MoveScalarToSide(context, rn, false); + using ScopedRegister rmReg = MoveScalarToSide(context, rm, false); + + using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rnReg, rmReg); + + if (sz == 1) + { + actionHalf(tempRegister.Operand, rnReg.Operand, rmReg.Operand, q); + } + else + { + action(tempRegister.Operand, rnReg.Operand, rmReg.Operand, 0, q); + } + + InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + if (sz == 1) + { + actionHalf(rdOperand, rnOperand, rmOperand, q); + } + else + { + action(rdOperand, rnOperand, rmOperand, 0, q); + } + } + } + + public static void EmitVectorBinaryByScalarAnyF( + CodeGenContext context, + uint rd, + uint rn, + uint rm, + uint size, + uint q, + Action action, + Action actionHalf) + { + EmitVectorByScalarAnyFCore(context, rd, rn, rm, size, q, action, actionHalf, isTernary: false); + } + + public static void EmitVectorTernaryRdF( + CodeGenContext context, + uint rd, + uint rn, + uint rm, + uint sz, + uint q, + Action action, + Action actionHalf) + { + Debug.Assert(sz == 0 || sz == 1); + + if (q == 0) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + MoveScalarToSide(context, tempRegister.Operand, rd, false); + + using ScopedRegister rnReg = MoveScalarToSide(context, rn, false); + using ScopedRegister rmReg = MoveScalarToSide(context, rm, false); + + if (sz == 1) + { + actionHalf(tempRegister.Operand, rnReg.Operand, rmReg.Operand, q); + } + else + { + action(tempRegister.Operand, rnReg.Operand, rmReg.Operand, 0, q); + } + + InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + if (sz == 1) + { + actionHalf(rdOperand, rnOperand, rmOperand, q); + } + else + { + action(rdOperand, rnOperand, rmOperand, 0, q); + } + } + } + + public static void EmitVectorTernaryMulNegRdF( + CodeGenContext context, + uint rd, + uint rn, + uint rm, + uint sz, + uint q, + bool negProduct) + { + Debug.Assert(sz == 0 || sz == 1); + + if (q == 0) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + MoveScalarToSide(context, tempRegister.Operand, rd, false); + + using ScopedRegister rnReg = MoveScalarToSide(context, rn, false); + using ScopedRegister rmReg = MoveScalarToSide(context, rm, false); + + EmitMulNegVector(context, tempRegister.Operand, rnReg.Operand, rmReg.Operand, sz, q, negProduct); + + InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + EmitMulNegVector(context, rdOperand, rnOperand, rmOperand, sz, q, negProduct); + } + } + + private static void EmitMulNegVector( + CodeGenContext context, + Operand rd, + Operand rn, + Operand rm, + uint sz, + uint q, + bool negProduct) + { + using ScopedRegister productRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + if (sz == 1) + { + context.Arm64Assembler.FmulVecHalf(productRegister.Operand, rn, rm, q); + + if (negProduct) + { + context.Arm64Assembler.FnegHalf(productRegister.Operand, productRegister.Operand, q); + } + + context.Arm64Assembler.FaddHalf(rd, rd, productRegister.Operand, q); + } + else + { + context.Arm64Assembler.FmulVecSingleAndDouble(productRegister.Operand, rn, rm, 0, q); + + if (negProduct) + { + context.Arm64Assembler.FnegSingleAndDouble(productRegister.Operand, productRegister.Operand, 0, q); + } + + context.Arm64Assembler.FaddSingleAndDouble(rd, rd, productRegister.Operand, 0, q); + } + } + + public static void EmitVectorTernaryRdByScalarAnyF( + CodeGenContext context, + uint rd, + uint rn, + uint rm, + uint size, + uint q, + Action action, + Action actionHalf) + { + EmitVectorByScalarAnyFCore(context, rd, rn, rm, size, q, action, actionHalf, isTernary: true); + } + + private static void EmitVectorByScalarAnyFCore( + CodeGenContext context, + uint rd, + uint rn, + uint rm, + uint size, + uint q, + Action action, + Action actionHalf, + bool isTernary) + { + (uint h, uint l, uint m) = GetIndexForReg(ref rm, size); + + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + if (q == 0) + { + if (isTernary) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + MoveScalarToSide(context, tempRegister.Operand, rd, false); + + using ScopedRegister rnReg = MoveScalarToSide(context, rn, false); + + if (size == 1) + { + actionHalf(tempRegister.Operand, rnReg.Operand, h, rmOperand, m, l, q); + } + else + { + action(tempRegister.Operand, rnReg.Operand, h, rmOperand, m, l, 0, q); + } + + InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + using ScopedRegister rnReg = MoveScalarToSide(context, rn, false); + + using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rnReg); + + if (size == 1) + { + actionHalf(tempRegister.Operand, rnReg.Operand, h, rmOperand, m, l, q); + } + else + { + action(tempRegister.Operand, rnReg.Operand, h, rmOperand, m, l, 0, q); + } + + InsertResult(context, tempRegister.Operand, rd, false); + } + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1)); + + if (size == 1) + { + actionHalf(rdOperand, rnOperand, h, rmOperand, m, l, q); + } + else + { + action(rdOperand, rnOperand, h, rmOperand, m, l, 0, q); + } + } + } + + public static void EmitVectorTernaryMulNegRdByScalarAnyF( + CodeGenContext context, + uint rd, + uint rn, + uint rm, + uint size, + uint q, + bool negProduct) + { + (uint h, uint l, uint m) = GetIndexForReg(ref rm, size); + + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + if (q == 0) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + MoveScalarToSide(context, tempRegister.Operand, rd, false); + + using ScopedRegister rnReg = MoveScalarToSide(context, rn, false); + + EmitMulNegVectorByScalar(context, tempRegister.Operand, rnReg.Operand, rmOperand, h, l, m, size, q, negProduct); + + InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1)); + + EmitMulNegVectorByScalar(context, rdOperand, rnOperand, rmOperand, h, l, m, size, q, negProduct); + } + } + + private static void EmitMulNegVectorByScalar( + CodeGenContext context, + Operand rd, + Operand rn, + Operand rm, + uint h, + uint l, + uint m, + uint sz, + uint q, + bool negProduct) + { + using ScopedRegister productRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + if (sz == 1) + { + context.Arm64Assembler.FmulElt2regElementHalf(productRegister.Operand, rn, h, rm, m, l, q); + + if (negProduct) + { + context.Arm64Assembler.FnegHalf(productRegister.Operand, productRegister.Operand, q); + } + + context.Arm64Assembler.FaddHalf(rd, rd, productRegister.Operand, q); + } + else + { + context.Arm64Assembler.FmulElt2regElementSingleAndDouble(productRegister.Operand, rn, h, rm, m, l, 0, q); + + if (negProduct) + { + context.Arm64Assembler.FnegSingleAndDouble(productRegister.Operand, productRegister.Operand, 0, q); + } + + context.Arm64Assembler.FaddSingleAndDouble(rd, rd, productRegister.Operand, 0, q); + } + } + + private static (uint, uint, uint) GetIndexForReg(ref uint reg, uint size) + { + int shift = (int)(size + 2); + uint index = reg >> shift; + reg &= (1u << shift) - 1; + index |= (reg & 1) << (5 - shift); + + uint h, l, m; + + if (size == 1) + { + Debug.Assert((index >> 3) == 0); + + m = index & 1; + l = (index >> 1) & 1; + h = index >> 2; + } + else + { + Debug.Assert(size == 2); + Debug.Assert((index >> 2) == 0); + + m = 0; + l = index & 1; + h = (index >> 1) & 1; + } + + return (h, l, m); + } + + private static (uint, uint) GetImmbImmh(uint value, uint size) + { + Debug.Assert(value > 0 && value <= (8u << (int)size)); + + uint imm = (8u << (int)size) | ((8u << (int)size) - value); + + Debug.Assert((imm >> 7) == 0); + + uint immb = imm & 7; + uint immh = imm >> 3; + + return (immb, immh); + } + + public static (uint, uint) GetImmbImmhForShift(uint value, uint size, bool isShl) + { + if (isShl) + { + Debug.Assert(value >= 0 && value < (8u << (int)size)); + + uint imm = (8u << (int)size) | (value & (0x3fu >> (int)(3 - size))); + + Debug.Assert((imm >> 7) == 0); + + uint immb = imm & 7; + uint immh = imm >> 3; + + return (immb, immh); + } + else + { + return GetImmbImmh(value, size); + } + } + + public static uint GetSizeFromImm6(uint imm6) + { + if ((imm6 & 0b100000) != 0) + { + return 2; + } + else if ((imm6 & 0b10000) != 0) + { + return 1; + } + else + { + Debug.Assert((imm6 & 0b1000) != 0); + + return 0; + } + } + + public static uint GetSizeFromImm7(uint imm7) + { + if ((imm7 & 0b1000000) != 0) + { + return 3; + } + else if ((imm7 & 0b100000) != 0) + { + return 2; + } + else if ((imm7 & 0b10000) != 0) + { + return 1; + } + else + { + Debug.Assert((imm7 & 0b1000) != 0); + + return 0; + } + } + + public static ScopedRegister PickSimdRegister(RegisterAllocator registerAllocator, ScopedRegister option1) + { + if (option1.IsAllocated) + { + return option1; + } + + return registerAllocator.AllocateTempSimdRegisterScoped(); + } + + public static ScopedRegister PickSimdRegister(RegisterAllocator registerAllocator, ScopedRegister option1, ScopedRegister option2) + { + if (option1.IsAllocated) + { + return option1; + } + else if (option2.IsAllocated) + { + return option2; + } + + return registerAllocator.AllocateTempSimdRegisterScoped(); + } + + public static ScopedRegister PickSimdRegister(RegisterAllocator registerAllocator, ScopedRegister option1, ScopedRegister option2, ScopedRegister option3) + { + if (option1.IsAllocated) + { + return option1; + } + else if (option2.IsAllocated) + { + return option2; + } + else if (option3.IsAllocated) + { + return option3; + } + + return registerAllocator.AllocateTempSimdRegisterScoped(); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonCompare.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonCompare.cs new file mode 100644 index 000000000..8da993854 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonCompare.cs @@ -0,0 +1,126 @@ +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitNeonCompare + { + public static void Vacge(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FacgeV, context.Arm64Assembler.FacgeVH); + } + + public static void Vacgt(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FacgtV, context.Arm64Assembler.FacgtVH); + } + + public static void VceqI(CodeGenContext context, uint rd, uint rm, bool f, uint size, uint q) + { + if (f) + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcmeqZeroV, context.Arm64Assembler.FcmeqZeroVH); + } + else + { + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.CmeqZeroV); + } + } + + public static void VceqR(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, context.Arm64Assembler.CmeqRegV, context.Arm64Assembler.CmeqRegS); + } + + public static void VceqFR(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FcmeqRegV, context.Arm64Assembler.FcmeqRegVH); + } + + public static void VcgeI(CodeGenContext context, uint rd, uint rm, bool f, uint size, uint q) + { + if (f) + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcmgeZeroV, context.Arm64Assembler.FcmgeZeroVH); + } + else + { + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.CmgeZeroV); + } + } + + public static void VcgeR(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary( + context, + rd, + rn, + rm, + size, + q, + u ? context.Arm64Assembler.CmhsV : context.Arm64Assembler.CmgeRegV, + u ? context.Arm64Assembler.CmhsS : context.Arm64Assembler.CmgeRegS); + } + + public static void VcgeFR(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FcmgeRegV, context.Arm64Assembler.FcmgeRegVH); + } + + public static void VcgtI(CodeGenContext context, uint rd, uint rm, bool f, uint size, uint q) + { + if (f) + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcmgtZeroV, context.Arm64Assembler.FcmgtZeroVH); + } + else + { + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.CmgtZeroV); + } + } + + public static void VcgtR(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary( + context, + rd, + rn, + rm, + size, + q, + u ? context.Arm64Assembler.CmhiV : context.Arm64Assembler.CmgtRegV, + u ? context.Arm64Assembler.CmhiS : context.Arm64Assembler.CmgtRegS); + } + + public static void VcgtFR(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q) + { + InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FcmgtRegV, context.Arm64Assembler.FcmgtRegVH); + } + + public static void VcleI(CodeGenContext context, uint rd, uint rm, bool f, uint size, uint q) + { + if (f) + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcmleV, context.Arm64Assembler.FcmleVH); + } + else + { + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.CmleV); + } + } + + public static void VcltI(CodeGenContext context, uint rd, uint rm, bool f, uint size, uint q) + { + if (f) + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcmltV, context.Arm64Assembler.FcmltVH); + } + else + { + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.CmltV); + } + } + + public static void Vtst(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, context.Arm64Assembler.CmtstV, context.Arm64Assembler.CmtstS); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonConvert.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonConvert.cs new file mode 100644 index 000000000..81fce678d --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonConvert.cs @@ -0,0 +1,137 @@ +using System; +using System.Diagnostics; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitNeonConvert + { + public static void Vcvta(CodeGenContext context, uint rd, uint rm, bool op, uint size, uint q) + { + if (op) + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcvtauV, context.Arm64Assembler.FcvtauVH); + } + else + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcvtasV, context.Arm64Assembler.FcvtasVH); + } + } + + public static void Vcvtm(CodeGenContext context, uint rd, uint rm, bool op, uint size, uint q) + { + if (op) + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcvtmuV, context.Arm64Assembler.FcvtmuVH); + } + else + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcvtmsV, context.Arm64Assembler.FcvtmsVH); + } + } + + public static void Vcvtn(CodeGenContext context, uint rd, uint rm, bool op, uint size, uint q) + { + if (op) + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcvtnuV, context.Arm64Assembler.FcvtnuVH); + } + else + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcvtnsV, context.Arm64Assembler.FcvtnsVH); + } + } + + public static void Vcvtp(CodeGenContext context, uint rd, uint rm, bool op, uint size, uint q) + { + if (op) + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcvtpuV, context.Arm64Assembler.FcvtpuVH); + } + else + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcvtpsV, context.Arm64Assembler.FcvtpsVH); + } + } + + public static void VcvtHs(CodeGenContext context, uint rd, uint rm, bool op) + { + bool halfToSingle = op; + if (halfToSingle) + { + // Half to single. + + InstEmitNeonCommon.EmitVectorUnaryLong(context, rd, rm, 0, context.Arm64Assembler.Fcvtl); + } + else + { + // Single to half. + + InstEmitNeonCommon.EmitVectorUnaryNarrow(context, rd, rm, 0, context.Arm64Assembler.Fcvtn); + } + } + + public static void VcvtIs(CodeGenContext context, uint rd, uint rm, uint op, uint size, uint q) + { + Debug.Assert(op >> 2 == 0); + + bool unsigned = (op & 1) != 0; + bool toInteger = (op >> 1) != 0; + + if (toInteger) + { + if (unsigned) + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcvtzuIntV, context.Arm64Assembler.FcvtzuIntVH); + } + else + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcvtzsIntV, context.Arm64Assembler.FcvtzsIntVH); + } + } + else + { + if (unsigned) + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.UcvtfIntV, context.Arm64Assembler.UcvtfIntVH); + } + else + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.ScvtfIntV, context.Arm64Assembler.ScvtfIntVH); + } + } + } + + public static void VcvtXs(CodeGenContext context, uint rd, uint rm, uint imm6, uint op, bool u, uint q) + { + Debug.Assert(op >> 2 == 0); + + bool unsigned = u; + bool toFixed = (op & 1) != 0; + uint size = 1 + (op >> 1); + uint fbits = Math.Clamp(64u - imm6, 1, 8u << (int)size); + + if (toFixed) + { + if (unsigned) + { + InstEmitNeonCommon.EmitVectorUnaryFixedAnyF(context, rd, rm, fbits, size, q, context.Arm64Assembler.FcvtzuFixV); + } + else + { + InstEmitNeonCommon.EmitVectorUnaryFixedAnyF(context, rd, rm, fbits, size, q, context.Arm64Assembler.FcvtzsFixV); + } + } + else + { + if (unsigned) + { + InstEmitNeonCommon.EmitVectorUnaryFixedAnyF(context, rd, rm, fbits, size, q, context.Arm64Assembler.UcvtfFixV); + } + else + { + InstEmitNeonCommon.EmitVectorUnaryFixedAnyF(context, rd, rm, fbits, size, q, context.Arm64Assembler.ScvtfFixV); + } + } + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonCrypto.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonCrypto.cs new file mode 100644 index 000000000..a36ae82c6 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonCrypto.cs @@ -0,0 +1,43 @@ +using System.Diagnostics; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitNeonCrypto + { + public static void Aesd(CodeGenContext context, uint rd, uint rm, uint size) + { + // TODO: Feature check, emulation if not supported. + + Debug.Assert(size == 0); + + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, context.Arm64Assembler.Aesd); + } + + public static void Aese(CodeGenContext context, uint rd, uint rm, uint size) + { + // TODO: Feature check, emulation if not supported. + + Debug.Assert(size == 0); + + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, context.Arm64Assembler.Aese); + } + + public static void Aesimc(CodeGenContext context, uint rd, uint rm, uint size) + { + // TODO: Feature check, emulation if not supported. + + Debug.Assert(size == 0); + + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, context.Arm64Assembler.Aesimc); + } + + public static void Aesmc(CodeGenContext context, uint rd, uint rm, uint size) + { + // TODO: Feature check, emulation if not supported. + + Debug.Assert(size == 0); + + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, context.Arm64Assembler.Aesmc); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonHash.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonHash.cs new file mode 100644 index 000000000..57090ac8f --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonHash.cs @@ -0,0 +1,97 @@ +using System.Diagnostics; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitNeonHash + { + public static void Sha1c(CodeGenContext context, uint rd, uint rn, uint rm, uint q) + { + // TODO: Feature check, emulation if not supported. + + Debug.Assert(q == 1); + + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, context.Arm64Assembler.Sha1c); + } + + public static void Sha1h(CodeGenContext context, uint rd, uint rm, uint size) + { + // TODO: Feature check, emulation if not supported. + + Debug.Assert(size == 2); + + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, context.Arm64Assembler.Sha1h); + } + + public static void Sha1m(CodeGenContext context, uint rd, uint rn, uint rm, uint q) + { + // TODO: Feature check, emulation if not supported. + + Debug.Assert(q == 1); + + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, context.Arm64Assembler.Sha1m); + } + + public static void Sha1p(CodeGenContext context, uint rd, uint rn, uint rm, uint q) + { + // TODO: Feature check, emulation if not supported. + + Debug.Assert(q == 1); + + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, context.Arm64Assembler.Sha1p); + } + + public static void Sha1su0(CodeGenContext context, uint rd, uint rn, uint rm, uint q) + { + // TODO: Feature check, emulation if not supported. + + Debug.Assert(q == 1); + + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, context.Arm64Assembler.Sha1su0); + } + + public static void Sha1su1(CodeGenContext context, uint rd, uint rm, uint size) + { + // TODO: Feature check, emulation if not supported. + + Debug.Assert(size == 2); + + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, context.Arm64Assembler.Sha1su1); + } + + public static void Sha256h(CodeGenContext context, uint rd, uint rn, uint rm, uint q) + { + // TODO: Feature check, emulation if not supported. + + Debug.Assert(q == 1); + + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, context.Arm64Assembler.Sha256h); + } + + public static void Sha256h2(CodeGenContext context, uint rd, uint rn, uint rm, uint q) + { + // TODO: Feature check, emulation if not supported. + + Debug.Assert(q == 1); + + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, context.Arm64Assembler.Sha256h2); + } + + public static void Sha256su0(CodeGenContext context, uint rd, uint rm, uint size) + { + // TODO: Feature check, emulation if not supported. + + Debug.Assert(size == 2); + + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, context.Arm64Assembler.Sha256su0); + } + + public static void Sha256su1(CodeGenContext context, uint rd, uint rn, uint rm, uint q) + { + // TODO: Feature check, emulation if not supported. + + Debug.Assert(q == 1); + + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, context.Arm64Assembler.Sha256su1); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonLogical.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonLogical.cs new file mode 100644 index 000000000..af2e54cc8 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonLogical.cs @@ -0,0 +1,79 @@ +using Ryujinx.Cpu.LightningJit.CodeGen; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitNeonLogical + { + public static void VandR(CodeGenContext context, uint rd, uint rn, uint rm, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, q, context.Arm64Assembler.And); + } + + public static void VbicI(CodeGenContext context, uint rd, uint cmode, uint imm8, uint q) + { + EmitMovi(context, rd, cmode, imm8, 1, q); + } + + public static void VbicR(CodeGenContext context, uint rd, uint rn, uint rm, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, q, context.Arm64Assembler.BicReg); + } + + public static void VbifR(CodeGenContext context, uint rd, uint rn, uint rm, uint q) + { + InstEmitNeonCommon.EmitVectorTernaryRd(context, rd, rn, rm, q, context.Arm64Assembler.Bif); + } + + public static void VbitR(CodeGenContext context, uint rd, uint rn, uint rm, uint q) + { + InstEmitNeonCommon.EmitVectorTernaryRd(context, rd, rn, rm, q, context.Arm64Assembler.Bit); + } + + public static void VbslR(CodeGenContext context, uint rd, uint rn, uint rm, uint q) + { + InstEmitNeonCommon.EmitVectorTernaryRd(context, rd, rn, rm, q, context.Arm64Assembler.Bsl); + } + + public static void VeorR(CodeGenContext context, uint rd, uint rn, uint rm, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, q, context.Arm64Assembler.Eor); + } + + public static void VornR(CodeGenContext context, uint rd, uint rn, uint rm, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, q, context.Arm64Assembler.Orn); + } + + public static void VorrI(CodeGenContext context, uint rd, uint cmode, uint imm8, uint q) + { + EmitMovi(context, rd, cmode, imm8, 0, q); + } + + public static void VorrR(CodeGenContext context, uint rd, uint rn, uint rm, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, q, context.Arm64Assembler.OrrReg); + } + + private static void EmitMovi(CodeGenContext context, uint rd, uint cmode, uint imm8, uint op, uint q) + { + (uint a, uint b, uint c, uint d, uint e, uint f, uint g, uint h) = InstEmitNeonMove.Split(imm8); + + if (q == 0) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + InstEmitNeonCommon.MoveScalarToSide(context, tempRegister.Operand, rd, false); + + context.Arm64Assembler.Movi(tempRegister.Operand, h, g, f, e, d, cmode, c, b, a, op, q); + + InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + + context.Arm64Assembler.Movi(rdOperand, h, g, f, e, d, cmode, c, b, a, op, q); + } + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonMemory.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonMemory.cs new file mode 100644 index 000000000..e77dc0a29 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonMemory.cs @@ -0,0 +1,797 @@ +using Ryujinx.Cpu.LightningJit.CodeGen; +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; +using System; +using System.Diagnostics; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitNeonMemory + { + public static void Vld11(CodeGenContext context, uint rd, uint rn, uint rm, uint indexAlign, uint size) + { + uint index = indexAlign >> ((int)size + 1); + + EmitMemory1234InstructionCore(context, rn, rm, 1 << (int)size, (address) => + { + EmitMemoryLoad1234SingleInstruction(context, address, rd, index, size, 1, 1, context.Arm64Assembler.Ld1SnglAsNoPostIndex); + }); + } + + public static void Vld1A(CodeGenContext context, uint rd, uint rn, uint rm, uint a, uint t, uint size) + { + EmitMemory1234InstructionCore(context, rn, rm, 1 << (int)size, (address) => + { + EmitMemoryLoad1SingleReplicateInstruction(context, address, rd, size, t + 1, 1, context.Arm64Assembler.Ld1rAsNoPostIndex); + }); + } + + public static void Vld1M(CodeGenContext context, uint rd, uint rn, uint rm, uint registersCount, uint align, uint size) + { + EmitMemory1234InstructionCore(context, rn, rm, 8 * (int)registersCount, (address) => + { + EmitMemoryLoad1234MultipleInstruction(context, address, rd, size, registersCount, 1, context.Arm64Assembler.Ld1MultAsNoPostIndex); + }); + } + + public static void Vld21(CodeGenContext context, uint rd, uint rn, uint rm, uint indexAlign, uint size) + { + uint index = indexAlign >> ((int)size + 1); + uint step = size > 0 && (indexAlign & (1u << (int)size)) != 0 ? 2u : 1u; + + EmitMemory1234InstructionCore(context, rn, rm, 2 * (1 << (int)size), (address) => + { + EmitMemoryLoad1234SingleInstruction(context, address, rd, index, size, 2, step, context.Arm64Assembler.Ld2SnglAsNoPostIndex); + }); + } + + public static void Vld2A(CodeGenContext context, uint rd, uint rn, uint rm, uint a, uint t, uint size) + { + EmitMemory1234InstructionCore(context, rn, rm, 2 * (1 << (int)size), (address) => + { + EmitMemoryLoad234SingleReplicateInstruction(context, address, rd, size, 2, t + 1, context.Arm64Assembler.Ld2rAsNoPostIndex); + }); + } + + public static void Vld2M(CodeGenContext context, uint rd, uint rn, uint rm, uint type, uint align, uint size) + { + uint step = (type & 1) + 1; + + EmitMemory1234InstructionCore(context, rn, rm, 16, (address) => + { + EmitMemoryLoad1234MultipleInstruction(context, address, rd, size, 2, step, context.Arm64Assembler.Ld2MultAsNoPostIndex); + }); + } + + public static void Vld2M(CodeGenContext context, uint rd, uint rn, uint rm, uint align, uint size) + { + EmitMemory1234InstructionCore(context, rn, rm, 32, (address) => + { + EmitMemoryLoad1234Multiple2x2Instruction(context, address, rd, size, context.Arm64Assembler.Ld2MultAsNoPostIndex); + }); + } + + public static void Vld31(CodeGenContext context, uint rd, uint rn, uint rm, uint indexAlign, uint size) + { + uint index = indexAlign >> ((int)size + 1); + uint step = size > 0 && (indexAlign & (1u << (int)size)) != 0 ? 2u : 1u; + + EmitMemory1234InstructionCore(context, rn, rm, 3 * (1 << (int)size), (address) => + { + EmitMemoryLoad1234SingleInstruction(context, address, rd, index, size, 3, step, context.Arm64Assembler.Ld3SnglAsNoPostIndex); + }); + } + + public static void Vld3A(CodeGenContext context, uint rd, uint rn, uint rm, uint a, uint t, uint size) + { + EmitMemory1234InstructionCore(context, rn, rm, 3 * (1 << (int)size), (address) => + { + EmitMemoryLoad234SingleReplicateInstruction(context, address, rd, size, 3, t + 1, context.Arm64Assembler.Ld3rAsNoPostIndex); + }); + } + + public static void Vld3M(CodeGenContext context, uint rd, uint rn, uint rm, uint type, uint align, uint size) + { + uint step = (type & 1) + 1; + + EmitMemory1234InstructionCore(context, rn, rm, 24, (address) => + { + EmitMemoryLoad1234MultipleInstruction(context, address, rd, size, 3, step, context.Arm64Assembler.Ld3MultAsNoPostIndex); + }); + } + + public static void Vld41(CodeGenContext context, uint rd, uint rn, uint rm, uint indexAlign, uint size) + { + uint index = indexAlign >> ((int)size + 1); + uint step = size > 0 && (indexAlign & (1u << (int)size)) != 0 ? 2u : 1u; + + EmitMemory1234InstructionCore(context, rn, rm, 4 * (1 << (int)size), (address) => + { + EmitMemoryLoad1234SingleInstruction(context, address, rd, index, size, 4, step, context.Arm64Assembler.Ld4SnglAsNoPostIndex); + }); + } + + public static void Vld4A(CodeGenContext context, uint rd, uint rn, uint rm, uint a, uint t, uint size) + { + EmitMemory1234InstructionCore(context, rn, rm, 4 * (1 << (int)size), (address) => + { + EmitMemoryLoad234SingleReplicateInstruction(context, address, rd, size, 4, t + 1, context.Arm64Assembler.Ld4rAsNoPostIndex); + }); + } + + public static void Vld4M(CodeGenContext context, uint rd, uint rn, uint rm, uint type, uint align, uint size) + { + uint step = (type & 1) + 1; + + EmitMemory1234InstructionCore(context, rn, rm, 32, (address) => + { + EmitMemoryLoad1234MultipleInstruction(context, address, rd, size, 4, step, context.Arm64Assembler.Ld4MultAsNoPostIndex); + }); + } + + public static void Vldm(CodeGenContext context, uint rd, uint rn, uint registerCount, bool u, bool w, bool singleRegs) + { + EmitMemoryMultipleInstruction(context, rd, rn, registerCount, u, w, singleRegs, isStore: false); + } + + public static void Vldr(CodeGenContext context, uint rd, uint rn, uint imm8, bool u, uint size) + { + EmitMemoryInstruction(context, rd, rn, imm8, u, size, isStore: false); + } + + public static void Vst11(CodeGenContext context, uint rd, uint rn, uint rm, uint indexAlign, uint size) + { + uint index = indexAlign >> ((int)size + 1); + + EmitMemory1234InstructionCore(context, rn, rm, 1 << (int)size, (address) => + { + EmitMemoryStore1234SingleInstruction(context, address, rd, index, size, 1, 1, context.Arm64Assembler.St1SnglAsNoPostIndex); + }); + } + + public static void Vst1M(CodeGenContext context, uint rd, uint rn, uint rm, uint registersCount, uint align, uint size) + { + EmitMemory1234InstructionCore(context, rn, rm, 8 * (int)registersCount, (address) => + { + EmitMemoryStore1234MultipleInstruction(context, address, rd, size, registersCount, 1, context.Arm64Assembler.St1MultAsNoPostIndex); + }); + } + + public static void Vst21(CodeGenContext context, uint rd, uint rn, uint rm, uint indexAlign, uint size) + { + uint index = indexAlign >> ((int)size + 1); + uint step = size > 0 && (indexAlign & (1u << (int)size)) != 0 ? 2u : 1u; + + EmitMemory1234InstructionCore(context, rn, rm, 2 * (1 << (int)size), (address) => + { + EmitMemoryStore1234SingleInstruction(context, address, rd, index, size, 2, step, context.Arm64Assembler.St2SnglAsNoPostIndex); + }); + } + + public static void Vst2M(CodeGenContext context, uint rd, uint rn, uint rm, uint type, uint align, uint size) + { + uint step = (type & 1) + 1; + + EmitMemory1234InstructionCore(context, rn, rm, 16, (address) => + { + EmitMemoryStore1234MultipleInstruction(context, address, rd, size, 2, step, context.Arm64Assembler.St2MultAsNoPostIndex); + }); + } + + public static void Vst2M(CodeGenContext context, uint rd, uint rn, uint rm, uint align, uint size) + { + EmitMemory1234InstructionCore(context, rn, rm, 32, (address) => + { + EmitMemoryStore1234Multiple2x2Instruction(context, address, rd, size, context.Arm64Assembler.St2MultAsNoPostIndex); + }); + } + + public static void Vst31(CodeGenContext context, uint rd, uint rn, uint rm, uint indexAlign, uint size) + { + uint index = indexAlign >> ((int)size + 1); + uint step = size > 0 && (indexAlign & (1u << (int)size)) != 0 ? 2u : 1u; + + EmitMemory1234InstructionCore(context, rn, rm, 3 * (1 << (int)size), (address) => + { + EmitMemoryStore1234SingleInstruction(context, address, rd, index, size, 3, step, context.Arm64Assembler.St3SnglAsNoPostIndex); + }); + } + + public static void Vst3M(CodeGenContext context, uint rd, uint rn, uint rm, uint type, uint align, uint size) + { + uint step = (type & 1) + 1; + + EmitMemory1234InstructionCore(context, rn, rm, 24, (address) => + { + EmitMemoryStore1234MultipleInstruction(context, address, rd, size, 3, step, context.Arm64Assembler.St3MultAsNoPostIndex); + }); + } + + public static void Vst41(CodeGenContext context, uint rd, uint rn, uint rm, uint indexAlign, uint size) + { + uint index = indexAlign >> ((int)size + 1); + uint step = size > 0 && (indexAlign & (1u << (int)size)) != 0 ? 2u : 1u; + + EmitMemory1234InstructionCore(context, rn, rm, 4 * (1 << (int)size), (address) => + { + EmitMemoryStore1234SingleInstruction(context, address, rd, index, size, 4, step, context.Arm64Assembler.St4SnglAsNoPostIndex); + }); + } + + public static void Vst4M(CodeGenContext context, uint rd, uint rn, uint rm, uint type, uint align, uint size) + { + uint step = (type & 1) + 1; + + EmitMemory1234InstructionCore(context, rn, rm, 32, (address) => + { + EmitMemoryStore1234MultipleInstruction(context, address, rd, size, 4, step, context.Arm64Assembler.St4MultAsNoPostIndex); + }); + } + + public static void Vstm(CodeGenContext context, uint rd, uint rn, uint registerCount, bool u, bool w, bool singleRegs) + { + EmitMemoryMultipleInstruction(context, rd, rn, registerCount, u, w, singleRegs, isStore: true); + } + + public static void Vstr(CodeGenContext context, uint rd, uint rn, uint imm8, bool u, uint size) + { + EmitMemoryInstruction(context, rd, rn, imm8, u, size, isStore: true); + } + + private static void EmitMemoryMultipleInstruction( + CodeGenContext context, + uint rd, + uint rn, + uint registerCount, + bool add, + bool wBack, + bool singleRegs, + bool isStore) + { + Operand baseAddress = InstEmitCommon.GetInputGpr(context, rn); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand offset = InstEmitCommon.Const((int)registerCount * (singleRegs ? 4 : 8)); + + if (!add) + { + if (wBack) + { + InstEmitMemory.WriteAddShiftOffset(context.Arm64Assembler, baseAddress, baseAddress, offset, false, ArmShiftType.Lsl, 0); + InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, baseAddress); + } + else + { + InstEmitMemory.WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, baseAddress, offset, false, ArmShiftType.Lsl, 0); + InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand); + } + } + else + { + InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, baseAddress); + } + + EmitMemoryMultipleInstructionCore(context, tempRegister.Operand, rd, registerCount, singleRegs, isStore); + + if (add && wBack) + { + context.Arm64Assembler.Add(baseAddress, baseAddress, offset); + } + } + + private static void EmitMemoryMultipleInstructionCore(CodeGenContext context, Operand baseAddress, uint rd, uint registerCount, bool singleRegs, bool isStore) + { + int offs = 0; + uint r = rd; + uint upperBound = Math.Min(rd + registerCount, 32u); + uint regMask = singleRegs ? 3u : 1u; + + // Read/write misaligned elements first. + + for (; (r & regMask) != 0 && r < upperBound; r++) + { + EmitMemoryInstruction(context, baseAddress, r, offs, singleRegs, isStore); + + offs += singleRegs ? 4 : 8; + } + + // Read/write aligned, full vectors. + + while (upperBound - r >= (singleRegs ? 4 : 2)) + { + int qIndex = (int)(r >> (singleRegs ? 2 : 1)); + + Operand rtOperand = context.RegisterAllocator.RemapSimdRegister(qIndex); + + if (upperBound - r >= (singleRegs ? 8 : 4) && (offs & 0xf) == 0) + { + Operand rt2Operand = context.RegisterAllocator.RemapSimdRegister(qIndex + 1); + + if (isStore) + { + context.Arm64Assembler.StpRiUn(rtOperand, rt2Operand, baseAddress, offs); + } + else + { + context.Arm64Assembler.LdpRiUn(rtOperand, rt2Operand, baseAddress, offs); + } + + r += singleRegs ? 8u : 4u; + offs += 32; + } + else + { + if ((offs & 0xf) == 0) + { + if (isStore) + { + context.Arm64Assembler.StrRiUn(rtOperand, baseAddress, offs); + } + else + { + context.Arm64Assembler.LdrRiUn(rtOperand, baseAddress, offs); + } + } + else + { + if (isStore) + { + context.Arm64Assembler.Stur(rtOperand, baseAddress, offs); + } + else + { + context.Arm64Assembler.Ldur(rtOperand, baseAddress, offs); + } + } + + r += singleRegs ? 4u : 2u; + offs += 16; + } + } + + // Read/write last misaligned elements. + + for (; r < upperBound; r++) + { + EmitMemoryInstruction(context, baseAddress, r, offs, singleRegs, isStore); + + offs += singleRegs ? 4 : 8; + } + } + + private static void EmitMemoryInstruction(CodeGenContext context, Operand baseAddress, uint r, int offs, bool singleRegs, bool isStore) + { + if (isStore) + { + using ScopedRegister tempRegister = InstEmitNeonCommon.MoveScalarToSide(context, r, singleRegs); + + context.Arm64Assembler.StrRiUn(tempRegister.Operand, baseAddress, offs); + } + else + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempFpRegisterScoped(singleRegs); + + context.Arm64Assembler.LdrRiUn(tempRegister.Operand, baseAddress, offs); + + InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, r, singleRegs); + } + } + + private static void EmitMemoryInstruction(CodeGenContext context, uint rd, uint rn, uint imm8, bool add, uint size, bool isStore) + { + bool singleRegs = size != 3; + int offs = (int)imm8; + + if (size == 1) + { + offs <<= 1; + } + else + { + offs <<= 2; + } + + using ScopedRegister address = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + if (rn == RegisterUtils.PcRegister) + { + if (!add) + { + offs = -offs; + } + + context.Arm64Assembler.Mov(address.Operand, (context.Pc & ~3u) + (uint)offs); + + InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, address.Operand, address.Operand); + + offs = 0; + } + else + { + Operand rnOperand = context.RegisterAllocator.RemapGprRegister((int)rn); + + if (InstEmitMemory.CanFoldOffset(context.MemoryManagerType, add ? offs : -offs, (int)size, true, out _)) + { + InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, address.Operand, rnOperand); + + if (!add) + { + offs = -offs; + } + } + else + { + InstEmitMemory.WriteAddShiftOffset(context.Arm64Assembler, address.Operand, rnOperand, InstEmitCommon.Const(offs), add, ArmShiftType.Lsl, 0); + InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, address.Operand, address.Operand); + + offs = 0; + } + } + + if ((size == 3 && (offs & 7) != 0) || offs < 0) + { + if (isStore) + { + using ScopedRegister tempRegister = InstEmitNeonCommon.MoveScalarToSide(context, rd, singleRegs); + + context.Arm64Assembler.Stur(tempRegister.Operand, address.Operand, offs, size); + } + else + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempFpRegisterScoped(singleRegs); + + context.Arm64Assembler.Ldur(tempRegister.Operand, address.Operand, offs, size); + + InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, singleRegs); + } + } + else + { + if (isStore) + { + using ScopedRegister tempRegister = InstEmitNeonCommon.MoveScalarToSide(context, rd, singleRegs); + + context.Arm64Assembler.StrRiUn(tempRegister.Operand, address.Operand, offs, size); + } + else + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempFpRegisterScoped(singleRegs); + + context.Arm64Assembler.LdrRiUn(tempRegister.Operand, address.Operand, offs, size); + + InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, singleRegs); + } + } + } + + private static void EmitMemory1234InstructionCore(CodeGenContext context, uint rn, uint rm, int bytes, Action callback) + { + bool wBack = rm != RegisterUtils.PcRegister; + bool registerIndex = rm != RegisterUtils.PcRegister && rm != RegisterUtils.SpRegister; + + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + + using ScopedRegister address = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, address.Operand, rnOperand); + + callback(address.Operand); + + if (wBack) + { + if (registerIndex) + { + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + context.Arm64Assembler.Add(rnOperand, rnOperand, rmOperand); + } + else + { + context.Arm64Assembler.Add(rnOperand, rnOperand, InstEmitCommon.Const(bytes)); + } + } + } + + private static void EmitMemoryLoad1234SingleInstruction( + CodeGenContext context, + Operand baseAddress, + uint rd, + uint index, + uint size, + uint registerCount, + uint step, + Action action) + { + ScopedRegister[] tempRegisters = AllocateSequentialRegisters(context, (int)registerCount); + + MoveDoublewordsToQuadwordsLower(context, rd, registerCount, step, tempRegisters); + + action(tempRegisters[0].Operand, baseAddress, index, size); + + MoveQuadwordsLowerToDoublewords(context, rd, registerCount, step, tempRegisters); + + FreeSequentialRegisters(tempRegisters); + } + + private static void EmitMemoryLoad1SingleReplicateInstruction( + CodeGenContext context, + Operand baseAddress, + uint rd, + uint size, + uint registerCount, + uint step, + Action action) + { + if ((rd & 1) == 0 && registerCount == 2) + { + action(context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)), baseAddress, size, 1); + } + else + { + uint vecsCount = (registerCount + 1) >> 1; + + ScopedRegister[] tempRegisters = AllocateSequentialRegisters(context, (int)vecsCount); + + action(tempRegisters[0].Operand, baseAddress, size, registerCount > 1 ? 1u : 0u); + + MoveQuadwordsToDoublewords(context, rd, registerCount, step, tempRegisters); + + FreeSequentialRegisters(tempRegisters); + } + } + + private static void EmitMemoryLoad234SingleReplicateInstruction( + CodeGenContext context, + Operand baseAddress, + uint rd, + uint size, + uint registerCount, + uint step, + Action action) + { + ScopedRegister[] tempRegisters = AllocateSequentialRegisters(context, (int)registerCount); + + action(tempRegisters[0].Operand, baseAddress, size, 0u); + + MoveQuadwordsLowerToDoublewords(context, rd, registerCount, step, tempRegisters); + + FreeSequentialRegisters(tempRegisters); + } + + private static void EmitMemoryLoad1234MultipleInstruction( + CodeGenContext context, + Operand baseAddress, + uint rd, + uint size, + uint registerCount, + uint step, + Action action) + { + ScopedRegister[] tempRegisters = AllocateSequentialRegisters(context, (int)registerCount); + + action(tempRegisters[0].Operand, baseAddress, size, 0); + + MoveQuadwordsLowerToDoublewords(context, rd, registerCount, step, tempRegisters); + + FreeSequentialRegisters(tempRegisters); + } + + private static void EmitMemoryLoad1234MultipleInstruction( + CodeGenContext context, + Operand baseAddress, + uint rd, + uint size, + uint registerCount, + uint step, + Action action) + { + ScopedRegister[] tempRegisters = AllocateSequentialRegisters(context, (int)registerCount); + + action(tempRegisters[0].Operand, baseAddress, registerCount, size, 0); + + MoveQuadwordsLowerToDoublewords(context, rd, registerCount, step, tempRegisters); + + FreeSequentialRegisters(tempRegisters); + } + + private static void EmitMemoryLoad1234Multiple2x2Instruction( + CodeGenContext context, + Operand baseAddress, + uint rd, + uint size, + Action action) + { + if ((rd & 1) == 0) + { + action(context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1), 2), baseAddress, size, 1); + } + else + { + ScopedRegister[] tempRegisters = AllocateSequentialRegisters(context, 2); + + action(tempRegisters[0].Operand, baseAddress, size, 1); + + MoveQuadwordsToDoublewords2x2(context, rd, tempRegisters); + + FreeSequentialRegisters(tempRegisters); + } + } + + private static void EmitMemoryStore1234SingleInstruction( + CodeGenContext context, + Operand baseAddress, + uint rd, + uint index, + uint size, + uint registerCount, + uint step, + Action action) + { + ScopedRegister[] tempRegisters = AllocateSequentialRegisters(context, (int)registerCount); + + MoveDoublewordsToQuadwordsLower(context, rd, registerCount, step, tempRegisters); + + action(tempRegisters[0].Operand, baseAddress, index, size); + + FreeSequentialRegisters(tempRegisters); + } + + private static void EmitMemoryStore1234MultipleInstruction( + CodeGenContext context, + Operand baseAddress, + uint rd, + uint size, + uint registerCount, + uint step, + Action action) + { + ScopedRegister[] tempRegisters = AllocateSequentialRegisters(context, (int)registerCount); + + MoveDoublewordsToQuadwordsLower(context, rd, registerCount, step, tempRegisters); + + action(tempRegisters[0].Operand, baseAddress, size, 0); + + FreeSequentialRegisters(tempRegisters); + } + + private static void EmitMemoryStore1234MultipleInstruction( + CodeGenContext context, + Operand baseAddress, + uint rd, + uint size, + uint registerCount, + uint step, + Action action) + { + ScopedRegister[] tempRegisters = AllocateSequentialRegisters(context, (int)registerCount); + + MoveDoublewordsToQuadwordsLower(context, rd, registerCount, step, tempRegisters); + + action(tempRegisters[0].Operand, baseAddress, registerCount, size, 0); + + FreeSequentialRegisters(tempRegisters); + } + + private static void EmitMemoryStore1234Multiple2x2Instruction( + CodeGenContext context, + Operand baseAddress, + uint rd, + uint size, + Action action) + { + if ((rd & 1) == 0) + { + action(context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1), 2), baseAddress, size, 1); + } + else + { + ScopedRegister[] tempRegisters = AllocateSequentialRegisters(context, 2); + + MoveDoublewordsToQuadwords2x2(context, rd, tempRegisters); + + action(tempRegisters[0].Operand, baseAddress, size, 1); + + FreeSequentialRegisters(tempRegisters); + } + } + + private static ScopedRegister[] AllocateSequentialRegisters(CodeGenContext context, int count) + { + ScopedRegister[] registers = new ScopedRegister[count]; + + for (int index = 0; index < count; index++) + { + registers[index] = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + } + + AssertSequentialRegisters(registers); + + return registers; + } + + private static void FreeSequentialRegisters(ReadOnlySpan registers) + { + for (int index = 0; index < registers.Length; index++) + { + registers[index].Dispose(); + } + } + + [Conditional("DEBUG")] + private static void AssertSequentialRegisters(ReadOnlySpan registers) + { + for (int index = 1; index < registers.Length; index++) + { + Debug.Assert(registers[index].Operand.GetRegister().Index == registers[0].Operand.GetRegister().Index + index); + } + } + + private static void MoveQuadwordsLowerToDoublewords(CodeGenContext context, uint rd, uint registerCount, uint step, ReadOnlySpan registers) + { + for (int index = 0; index < registerCount; index++) + { + uint r = rd + (uint)index * step; + + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(r >> 1)); + uint imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(r & 1u, false); + context.Arm64Assembler.InsElt(rdOperand, registers[index].Operand, 0, imm5); + } + } + + private static void MoveDoublewordsToQuadwordsLower(CodeGenContext context, uint rd, uint registerCount, uint step, ReadOnlySpan registers) + { + for (int index = 0; index < registerCount; index++) + { + uint r = rd + (uint)index * step; + + InstEmitNeonCommon.MoveScalarToSide(context, registers[index].Operand, r, false); + } + } + + private static void MoveDoublewordsToQuadwords2x2(CodeGenContext context, uint rd, ReadOnlySpan registers) + { + for (int index = 0; index < 2; index++) + { + uint r = rd + (uint)index * 2; + uint r2 = r + 1; + + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(r >> 1)); + uint imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(0, false); + context.Arm64Assembler.InsElt(registers[index].Operand, rdOperand, (r & 1u) << 3, imm5); + + rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(r2 >> 1)); + imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(1, false); + context.Arm64Assembler.InsElt(registers[index].Operand, rdOperand, (r2 & 1u) << 3, imm5); + } + } + + private static void MoveQuadwordsToDoublewords(CodeGenContext context, uint rd, uint registerCount, uint step, ReadOnlySpan registers) + { + for (int index = 0; index < registerCount; index++) + { + uint r = rd + (uint)index * step; + + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(r >> 1)); + uint imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(r & 1u, false); + context.Arm64Assembler.InsElt(rdOperand, registers[index >> 1].Operand, ((uint)index & 1u) << 3, imm5); + } + } + + private static void MoveQuadwordsToDoublewords2x2(CodeGenContext context, uint rd, ReadOnlySpan registers) + { + for (int index = 0; index < 2; index++) + { + uint r = rd + (uint)index * 2; + uint r2 = r + 1; + + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(r >> 1)); + uint imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(r & 1u, false); + context.Arm64Assembler.InsElt(rdOperand, registers[index].Operand, 0, imm5); + + rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(r2 >> 1)); + imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(r2 & 1u, false); + context.Arm64Assembler.InsElt(rdOperand, registers[index].Operand, 1u << 3, imm5); + } + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonMove.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonMove.cs new file mode 100644 index 000000000..08a0673aa --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonMove.cs @@ -0,0 +1,665 @@ +using Ryujinx.Cpu.LightningJit.CodeGen; +using System; +using System.Diagnostics; +using System.Numerics; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitNeonMove + { + public static void VdupR(CodeGenContext context, uint rd, uint rt, uint b, uint e, uint q) + { + uint size = 2 - (e | (b << 1)); + + Debug.Assert(size < 3); + + Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt); + + uint imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(0, size); + + if (q == 0) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + context.Arm64Assembler.DupGen(tempRegister.Operand, rtOperand, imm5, q); + + InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + Debug.Assert((rd & 1) == 0); + + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + + context.Arm64Assembler.DupGen(rdOperand, rtOperand, imm5, q); + } + } + + public static void VdupS(CodeGenContext context, uint rd, uint rm, uint imm4, uint q) + { + uint size = (uint)BitOperations.TrailingZeroCount(imm4); + + Debug.Assert(size < 3); + + uint index = imm4 >> (int)(size + 1); + + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + uint imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(index | ((rm & 1) << (int)(3 - size)), size); + + if (q == 0) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + context.Arm64Assembler.DupEltVectorFromElement(tempRegister.Operand, rmOperand, imm5, q); + + InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + Debug.Assert((rd & 1) == 0); + + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + + context.Arm64Assembler.DupEltVectorFromElement(rdOperand, rmOperand, imm5, q); + } + } + + public static void Vext(CodeGenContext context, uint rd, uint rn, uint rm, uint imm4, uint q) + { + if (q == 0) + { + using ScopedRegister rnReg = InstEmitNeonCommon.MoveScalarToSide(context, rn, false); + using ScopedRegister rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, false); + + using ScopedRegister tempRegister = InstEmitNeonCommon.PickSimdRegister(context.RegisterAllocator, rnReg, rmReg); + + context.Arm64Assembler.Ext(tempRegister.Operand, rnReg.Operand, imm4, rmReg.Operand, q); + + InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + Debug.Assert(((rd | rn | rm) & 1) == 0); + + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + context.Arm64Assembler.Ext(rdOperand, rnOperand, imm4, rmOperand, q); + } + } + + public static void Vmovl(CodeGenContext context, uint rd, uint rm, bool u, uint imm3h) + { + uint size = (uint)BitOperations.TrailingZeroCount(imm3h); + Debug.Assert(size < 3); + + InstEmitNeonCommon.EmitVectorBinaryLongShift( + context, + rd, + rm, + 0, + size, + isShl: true, + u ? context.Arm64Assembler.Ushll : context.Arm64Assembler.Sshll); + } + + public static void Vmovn(CodeGenContext context, uint rd, uint rm, uint size) + { + Debug.Assert(size < 3); + + InstEmitNeonCommon.EmitVectorUnaryNarrow(context, rd, rm, size, context.Arm64Assembler.Xtn); + } + + public static void Vmovx(CodeGenContext context, uint rd, uint rm) + { + InstEmitNeonCommon.EmitScalarBinaryShift(context, rd, rm, 16, 2, isShl: false, context.Arm64Assembler.UshrS); + } + + public static void VmovD(CodeGenContext context, uint rt, uint rt2, uint rm, bool op) + { + Operand rmReg = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + uint top = rm & 1; + uint ftype = top + 1; + + if (op) + { + Operand rtOperand = InstEmitCommon.GetOutputGpr(context, rt); + Operand rt2Operand = InstEmitCommon.GetOutputGpr(context, rt2); + + Operand rtOperand64 = new(OperandKind.Register, OperandType.I64, rtOperand.Value); + Operand rt2Operand64 = new(OperandKind.Register, OperandType.I64, rt2Operand.Value); + + context.Arm64Assembler.FmovFloatGen(rtOperand64, rmReg, ftype, 1, 0, top); + + context.Arm64Assembler.Lsr(rt2Operand64, rtOperand64, InstEmitCommon.Const(32)); + context.Arm64Assembler.Mov(rtOperand, rtOperand); // Zero-extend. + } + else + { + Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt); + Operand rt2Operand = InstEmitCommon.GetInputGpr(context, rt2); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand tempRegister64 = new(OperandKind.Register, OperandType.I64, tempRegister.Operand.Value); + + context.Arm64Assembler.Lsl(tempRegister64, rt2Operand, InstEmitCommon.Const(32)); + context.Arm64Assembler.Orr(tempRegister64, tempRegister64, rtOperand); + + if (top == 0) + { + // Doing FMOV on Rm directly would clear the high bits if we are moving to the bottom. + + using ScopedRegister tempRegister2 = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + context.Arm64Assembler.FmovFloatGen(tempRegister2.Operand, tempRegister64, ftype, 1, 1, top); + + InstEmitNeonCommon.InsertResult(context, tempRegister2.Operand, rm, false); + } + else + { + context.Arm64Assembler.FmovFloatGen(rmReg, tempRegister64, ftype, 1, 1, top); + } + } + } + + public static void VmovH(CodeGenContext context, uint rt, uint rn, bool op) + { + if (op) + { + Operand rtOperand = InstEmitCommon.GetOutputGpr(context, rt); + + using ScopedRegister tempRegister = InstEmitNeonCommon.MoveScalarToSide(context, rn, true); + + context.Arm64Assembler.FmovFloatGen(rtOperand, tempRegister.Operand, 3, 0, 0, 0); + } + else + { + Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + context.Arm64Assembler.FmovFloatGen(tempRegister.Operand, rtOperand, 3, 0, 1, 0); + + InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rn, true); + } + } + + public static void VmovI(CodeGenContext context, uint rd, uint op, uint cmode, uint imm8, uint q) + { + (uint a, uint b, uint c, uint d, uint e, uint f, uint g, uint h) = Split(imm8); + + if (q == 0) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + context.Arm64Assembler.Movi(tempRegister.Operand, h, g, f, e, d, cmode, c, b, a, op, q); + + InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + + context.Arm64Assembler.Movi(rdOperand, h, g, f, e, d, cmode, c, b, a, op, q); + } + } + + public static void VmovFI(CodeGenContext context, uint rd, uint imm8, uint size) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + context.Arm64Assembler.FmovFloatImm(tempRegister.Operand, imm8, size ^ 2u); + + InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, size != 3); + } + + public static void VmovR(CodeGenContext context, uint rd, uint rm, uint size) + { + bool singleRegister = size == 2; + + int shift = singleRegister ? 2 : 1; + uint mask = singleRegister ? 3u : 1u; + uint dstElt = rd & mask; + uint srcElt = rm & mask; + + uint imm4 = srcElt << (singleRegister ? 2 : 3); + uint imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(dstElt, singleRegister); + + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> shift)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> shift)); + + context.Arm64Assembler.InsElt(rdOperand, rmOperand, imm4, imm5); + } + + public static void VmovRs(CodeGenContext context, uint rd, uint rt, uint opc1, uint opc2) + { + uint index; + uint size; + + if ((opc1 & 2u) != 0) + { + index = opc2 | ((opc1 & 1u) << 2); + size = 0; + } + else if ((opc2 & 1u) != 0) + { + index = (opc2 >> 1) | ((opc1 & 1u) << 1); + size = 1; + } + else + { + Debug.Assert(opc1 == 0 || opc1 == 1); + Debug.Assert(opc2 == 0); + + index = opc1 & 1u; + size = 2; + } + + index |= (rd & 1u) << (int)(3 - size); + + Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt); + + Operand rdReg = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + + context.Arm64Assembler.InsGen(rdReg, rtOperand, InstEmitNeonCommon.GetImm5ForElementIndex(index, size)); + } + + public static void VmovS(CodeGenContext context, uint rt, uint rn, bool op) + { + if (op) + { + Operand rtOperand = InstEmitCommon.GetOutputGpr(context, rt); + + using ScopedRegister tempRegister = InstEmitNeonCommon.MoveScalarToSide(context, rn, true); + + context.Arm64Assembler.FmovFloatGen(rtOperand, tempRegister.Operand, 0, 0, 0, 0); + } + else + { + Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + context.Arm64Assembler.FmovFloatGen(tempRegister.Operand, rtOperand, 0, 0, 1, 0); + + InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rn, true); + } + } + + public static void VmovSr(CodeGenContext context, uint rt, uint rn, bool u, uint opc1, uint opc2) + { + uint index; + uint size; + + if ((opc1 & 2u) != 0) + { + index = opc2 | ((opc1 & 1u) << 2); + size = 0; + } + else if ((opc2 & 1u) != 0) + { + index = (opc2 >> 1) | ((opc1 & 1u) << 1); + size = 1; + } + else + { + Debug.Assert(opc1 == 0 || opc1 == 1); + Debug.Assert(opc2 == 0); + Debug.Assert(!u); + + index = opc1 & 1u; + size = 2; + } + + index |= (rn & 1u) << (int)(3 - size); + + Operand rtOperand = InstEmitCommon.GetOutputGpr(context, rt); + + Operand rnReg = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1)); + + if (u || size > 1) + { + context.Arm64Assembler.Umov(rtOperand, rnReg, (int)index, (int)size); + } + else + { + context.Arm64Assembler.Smov(rtOperand, rnReg, (int)index, (int)size); + } + } + + public static void VmovSs(CodeGenContext context, uint rt, uint rt2, uint rm, bool op) + { + if ((rm & 1) == 0) + { + // If we are moving an aligned pair of single-precision registers, + // we can just move a single double-precision register. + + VmovD(context, rt, rt2, rm >> 1, op); + + return; + } + + if (op) + { + Operand rtOperand = InstEmitCommon.GetOutputGpr(context, rt); + Operand rt2Operand = InstEmitCommon.GetOutputGpr(context, rt2); + + using ScopedRegister rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, true); + using ScopedRegister rmReg2 = InstEmitNeonCommon.MoveScalarToSide(context, rm + 1, true); + + context.Arm64Assembler.FmovFloatGen(rtOperand, rmReg.Operand, 0, 0, 0, 0); + context.Arm64Assembler.FmovFloatGen(rt2Operand, rmReg2.Operand, 0, 0, 0, 0); + } + else + { + Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt); + Operand rt2Operand = InstEmitCommon.GetInputGpr(context, rt2); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + context.Arm64Assembler.FmovFloatGen(tempRegister.Operand, rtOperand, 0, 0, 1, 0); + InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rm, true); + + context.Arm64Assembler.FmovFloatGen(tempRegister.Operand, rt2Operand, 0, 0, 1, 0); + InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rm + 1, true); + } + } + + public static void VmvnI(CodeGenContext context, uint rd, uint cmode, uint imm8, uint q) + { + (uint a, uint b, uint c, uint d, uint e, uint f, uint g, uint h) = Split(imm8); + + if (q == 0) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + context.Arm64Assembler.Mvni(tempRegister.Operand, h, g, f, e, d, cmode, c, b, a, q); + + InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, false); + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + + context.Arm64Assembler.Mvni(rdOperand, h, g, f, e, d, cmode, c, b, a, q); + } + } + + public static void VmvnR(CodeGenContext context, uint rd, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, q, context.Arm64Assembler.Not); + } + + public static void Vswp(CodeGenContext context, uint rd, uint rm, uint q) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + if (q == 0) + { + InstEmitNeonCommon.MoveScalarToSide(context, tempRegister.Operand, rd, false); + using ScopedRegister rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, false); + + InstEmitNeonCommon.InsertResult(context, rmReg.Operand, rd, false); + InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rm, false); + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + context.Arm64Assembler.Orr(tempRegister.Operand, rdOperand, rdOperand); // Temp = Rd + context.Arm64Assembler.Orr(rdOperand, rmOperand, rmOperand); // Rd = Rm + context.Arm64Assembler.Orr(rmOperand, tempRegister.Operand, tempRegister.Operand); // Rm = Temp + } + } + + public static void Vtbl(CodeGenContext context, uint rd, uint rn, uint rm, bool op, uint len) + { + // On AArch64, TBL/TBX works with 128-bit vectors, while on AArch32 it works with 64-bit vectors. + // We must combine the 64-bit vectors into a larger 128-bit one in some cases. + + // TODO: Peephole optimization to combine adjacent TBL instructions? + + Debug.Assert(len <= 3); + + bool isTbl = !op; + + len = Math.Min(len, 31 - rn); + + bool rangeMismatch = !isTbl && (len & 1) == 0; + + using ScopedRegister indicesReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, false, rangeMismatch); + + if (rangeMismatch) + { + // Force any index >= 8 * regs to be the maximum value, since on AArch64 we are working with a full vector, + // and the out of range value is 16 * regs, not 8 * regs. + + Debug.Assert(indicesReg.IsAllocated); + + using ScopedRegister tempRegister2 = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + if (len == 0) + { + (uint immb, uint immh) = InstEmitNeonCommon.GetImmbImmhForShift(3, 0, isShl: false); + + context.Arm64Assembler.UshrV(tempRegister2.Operand, indicesReg.Operand, immb, immh, 0); + context.Arm64Assembler.CmeqZeroV(tempRegister2.Operand, tempRegister2.Operand, 0, 0); + context.Arm64Assembler.Orn(indicesReg.Operand, indicesReg.Operand, tempRegister2.Operand, 0); + } + else + { + (uint a, uint b, uint c, uint d, uint e, uint f, uint g, uint h) = Split(8u * (len + 1)); + + context.Arm64Assembler.Movi(tempRegister2.Operand, h, g, f, e, d, 0xe, c, b, a, 0, 0); + context.Arm64Assembler.CmgeRegV(tempRegister2.Operand, indicesReg.Operand, tempRegister2.Operand, 0, 0); + context.Arm64Assembler.OrrReg(indicesReg.Operand, indicesReg.Operand, tempRegister2.Operand, 0); + } + } + + ScopedRegister tableReg1 = default; + ScopedRegister tableReg2 = default; + + switch (len) + { + case 0: + tableReg1 = MoveHalfToSideZeroUpper(context, rn); + break; + case 1: + tableReg1 = MoveDoublewords(context, rn, rn + 1); + break; + case 2: + tableReg1 = MoveDoublewords(context, rn, rn + 1, isOdd: true); + tableReg2 = MoveHalfToSideZeroUpper(context, rn + 2); + break; + case 3: + tableReg1 = MoveDoublewords(context, rn, rn + 1); + tableReg2 = MoveDoublewords(context, rn + 2, rn + 3); + break; + } + + // TBL works with consecutive registers, it is assumed that two consecutive calls to the register allocator + // will return consecutive registers. + + Debug.Assert(len < 2 || tableReg1.Operand.GetRegister().Index + 1 == tableReg2.Operand.GetRegister().Index); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + if (isTbl) + { + context.Arm64Assembler.Tbl(tempRegister.Operand, tableReg1.Operand, len >> 1, indicesReg.Operand, 0); + } + else + { + InstEmitNeonCommon.MoveScalarToSide(context, tempRegister.Operand, rd, false); + + context.Arm64Assembler.Tbx(tempRegister.Operand, tableReg1.Operand, len >> 1, indicesReg.Operand, 0); + } + + InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, false); + + tableReg1.Dispose(); + + if (len > 1) + { + tableReg2.Dispose(); + } + } + + public static void Vtrn(CodeGenContext context, uint rd, uint rm, uint size, uint q) + { + EmitVectorBinaryInterleavedTrn(context, rd, rm, size, q, context.Arm64Assembler.Trn1, context.Arm64Assembler.Trn2); + } + + public static void Vuzp(CodeGenContext context, uint rd, uint rm, uint size, uint q) + { + EmitVectorBinaryInterleaved(context, rd, rm, size, q, context.Arm64Assembler.Uzp1, context.Arm64Assembler.Uzp2); + } + + public static void Vzip(CodeGenContext context, uint rd, uint rm, uint size, uint q) + { + EmitVectorBinaryInterleaved(context, rd, rm, size, q, context.Arm64Assembler.Zip1, context.Arm64Assembler.Zip2); + } + + public static (uint, uint, uint, uint, uint, uint, uint, uint) Split(uint imm8) + { + uint a = (imm8 >> 7) & 1; + uint b = (imm8 >> 6) & 1; + uint c = (imm8 >> 5) & 1; + uint d = (imm8 >> 4) & 1; + uint e = (imm8 >> 3) & 1; + uint f = (imm8 >> 2) & 1; + uint g = (imm8 >> 1) & 1; + uint h = imm8 & 1; + + return (a, b, c, d, e, f, g, h); + } + + private static ScopedRegister MoveHalfToSideZeroUpper(CodeGenContext context, uint srcReg) + { + uint elt = srcReg & 1u; + + Operand source = context.RegisterAllocator.RemapSimdRegister((int)(srcReg >> 1)); + ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempFpRegisterScoped(false); + + uint imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(elt, false); + + context.Arm64Assembler.DupEltScalarFromElement(tempRegister.Operand, source, imm5); + + return tempRegister; + } + + private static ScopedRegister MoveDoublewords(CodeGenContext context, uint lowerReg, uint upperReg, bool isOdd = false) + { + if ((lowerReg & 1) == 0 && upperReg == lowerReg + 1 && !isOdd) + { + return new ScopedRegister(context.RegisterAllocator, context.RegisterAllocator.RemapSimdRegister((int)(lowerReg >> 1)), false); + } + + Operand lowerSrc = context.RegisterAllocator.RemapSimdRegister((int)(lowerReg >> 1)); + Operand upperSrc = context.RegisterAllocator.RemapSimdRegister((int)(upperReg >> 1)); + ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempFpRegisterScoped(false); + + uint imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(lowerReg & 1u, false); + + context.Arm64Assembler.DupEltScalarFromElement(tempRegister.Operand, lowerSrc, imm5); + + imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(1, false); + + context.Arm64Assembler.InsElt(tempRegister.Operand, upperSrc, (upperReg & 1u) << 3, imm5); + + return tempRegister; + } + + private static void EmitVectorBinaryInterleavedTrn( + CodeGenContext context, + uint rd, + uint rm, + uint size, + uint q, + Action action1, + Action action2) + { + if (rd == rm) + { + // The behaviour when the registers are the same is "unpredictable" according to the manual. + + if (q == 0) + { + using ScopedRegister rdReg = InstEmitNeonCommon.MoveScalarToSide(context, rd, false); + using ScopedRegister rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, false); + + using ScopedRegister tempRegister1 = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + using ScopedRegister tempRegister2 = InstEmitNeonCommon.PickSimdRegister(context.RegisterAllocator, rdReg, rmReg); + + action1(tempRegister1.Operand, rdReg.Operand, rmReg.Operand, size, q); + action2(tempRegister2.Operand, rdReg.Operand, tempRegister1.Operand, size, q); + + InstEmitNeonCommon.InsertResult(context, tempRegister2.Operand, rd, false); + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + action1(tempRegister.Operand, rdOperand, rmOperand, size, q); + action2(rmOperand, rdOperand, tempRegister.Operand, size, q); + } + } + else + { + EmitVectorBinaryInterleaved(context, rd, rm, size, q, action1, action2); + } + } + + private static void EmitVectorBinaryInterleaved( + CodeGenContext context, + uint rd, + uint rm, + uint size, + uint q, + Action action1, + Action action2) + { + if (q == 0) + { + using ScopedRegister rdReg = InstEmitNeonCommon.MoveScalarToSide(context, rd, false); + using ScopedRegister rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, false); + + using ScopedRegister tempRegister1 = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + using ScopedRegister tempRegister2 = InstEmitNeonCommon.PickSimdRegister(context.RegisterAllocator, rdReg, rmReg); + + action1(tempRegister1.Operand, rdReg.Operand, rmReg.Operand, size, q); + action2(tempRegister2.Operand, rdReg.Operand, rmReg.Operand, size, q); + + if (rd != rm) + { + InstEmitNeonCommon.InsertResult(context, tempRegister1.Operand, rd, false); + } + + InstEmitNeonCommon.InsertResult(context, tempRegister2.Operand, rm, false); + } + else + { + Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)); + Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1)); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + action1(tempRegister.Operand, rdOperand, rmOperand, size, q); + action2(rmOperand, rdOperand, rmOperand, size, q); + + if (rd != rm) + { + context.Arm64Assembler.OrrReg(rdOperand, tempRegister.Operand, tempRegister.Operand, 1); + } + } + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonRound.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonRound.cs new file mode 100644 index 000000000..3c6ca65d0 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonRound.cs @@ -0,0 +1,105 @@ +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitNeonRound + { + public static void Vraddhn(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitVectorBinaryNarrow(context, rd, rn, rm, size, context.Arm64Assembler.Raddhn); + } + + public static void Vrhadd(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, u ? context.Arm64Assembler.Urhadd : context.Arm64Assembler.Srhadd, null); + } + + public static void Vrshl(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary( + context, + rd, + rm, + rn, + size, + q, + u ? context.Arm64Assembler.UrshlV : context.Arm64Assembler.SrshlV, + u ? context.Arm64Assembler.UrshlS : context.Arm64Assembler.SrshlS); + } + + public static void Vrshr(CodeGenContext context, uint rd, uint rm, bool u, uint l, uint imm6, uint q) + { + uint size = InstEmitNeonCommon.GetSizeFromImm7(imm6 | (l << 6)); + uint shift = InstEmitNeonShift.GetShiftRight(imm6, size); + + InstEmitNeonCommon.EmitVectorBinaryShift( + context, + rd, + rm, + shift, + size, + q, + isShl: false, + u ? context.Arm64Assembler.UrshrV : context.Arm64Assembler.SrshrV, + u ? context.Arm64Assembler.UrshrS : context.Arm64Assembler.SrshrS); + } + + public static void Vrshrn(CodeGenContext context, uint rd, uint rm, uint imm6) + { + uint size = InstEmitNeonCommon.GetSizeFromImm6(imm6); + uint shift = InstEmitNeonShift.GetShiftRight(imm6, size); + + InstEmitNeonCommon.EmitVectorBinaryNarrowShift(context, rd, rm, shift, size, isShl: false, context.Arm64Assembler.Rshrn); + } + + public static void Vrsra(CodeGenContext context, uint rd, uint rm, bool u, uint l, uint imm6, uint q) + { + uint size = InstEmitNeonCommon.GetSizeFromImm7(imm6 | (l << 6)); + uint shift = InstEmitNeonShift.GetShiftRight(imm6, size); + + InstEmitNeonCommon.EmitVectorTernaryRdShift( + context, + rd, + rm, + shift, + size, + q, + isShl: false, + u ? context.Arm64Assembler.UrsraV : context.Arm64Assembler.SrsraV, + u ? context.Arm64Assembler.UrsraS : context.Arm64Assembler.SrsraS); + } + + public static void Vrsubhn(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitVectorBinaryNarrow(context, rd, rn, rm, size, context.Arm64Assembler.Rsubhn); + } + + public static void Vrinta(CodeGenContext context, uint rd, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FrintaSingleAndDouble, context.Arm64Assembler.FrintaHalf); + } + + public static void Vrintm(CodeGenContext context, uint rd, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FrintmSingleAndDouble, context.Arm64Assembler.FrintmHalf); + } + + public static void Vrintn(CodeGenContext context, uint rd, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FrintnSingleAndDouble, context.Arm64Assembler.FrintnHalf); + } + + public static void Vrintp(CodeGenContext context, uint rd, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FrintpSingleAndDouble, context.Arm64Assembler.FrintpHalf); + } + + public static void Vrintx(CodeGenContext context, uint rd, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FrintxSingleAndDouble, context.Arm64Assembler.FrintxHalf); + } + + public static void Vrintz(CodeGenContext context, uint rd, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FrintzSingleAndDouble, context.Arm64Assembler.FrintzHalf); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonSaturate.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonSaturate.cs new file mode 100644 index 000000000..aeab726a3 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonSaturate.cs @@ -0,0 +1,205 @@ +using System.Diagnostics; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitNeonSaturate + { + public static void Vqabs(CodeGenContext context, uint rd, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.SqabsV); + } + + public static void Vqadd(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary( + context, + rd, + rn, + rm, + size, + q, + u ? context.Arm64Assembler.UqaddV : context.Arm64Assembler.SqaddV, + u ? context.Arm64Assembler.UqaddS : context.Arm64Assembler.SqaddS); + } + + public static void Vqdmlal(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitVectorBinaryLong(context, rd, rn, rm, size, context.Arm64Assembler.SqdmlalVecV); + } + + public static void VqdmlalS(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitVectorBinaryLongByScalar(context, rd, rn, rm, size, context.Arm64Assembler.SqdmlalElt2regElement); + } + + public static void Vqdmlsl(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitVectorBinaryLong(context, rd, rn, rm, size, context.Arm64Assembler.SqdmlslVecV); + } + + public static void VqdmlslS(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitVectorBinaryLongByScalar(context, rd, rn, rm, size, context.Arm64Assembler.SqdmlslElt2regElement); + } + + public static void Vqdmulh(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, context.Arm64Assembler.SqdmulhVecV, context.Arm64Assembler.SqdmulhVecS); + } + + public static void VqdmulhS(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinaryByScalar(context, rd, rn, rm, size, q, context.Arm64Assembler.SqdmulhElt2regElement); + } + + public static void Vqdmull(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitVectorBinaryLong(context, rd, rn, rm, size, context.Arm64Assembler.SqdmullVecV); + } + + public static void VqdmullS(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitVectorBinaryLongByScalar(context, rd, rn, rm, size, context.Arm64Assembler.SqdmullElt2regElement); + } + + public static void Vqmovn(CodeGenContext context, uint rd, uint rm, uint op, uint size) + { + if (op == 3) + { + InstEmitNeonCommon.EmitVectorUnaryNarrow(context, rd, rm, size, context.Arm64Assembler.UqxtnV); + } + else + { + InstEmitNeonCommon.EmitVectorUnaryNarrow(context, rd, rm, size, op == 1 ? context.Arm64Assembler.SqxtunV : context.Arm64Assembler.SqxtnV); + } + } + + public static void Vqneg(CodeGenContext context, uint rd, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.SqnegV); + } + + public static void Vqrdmlah(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorTernaryRd(context, rd, rn, rm, size, q, context.Arm64Assembler.SqrdmlahVecV); + } + + public static void VqrdmlahS(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorTernaryRdByScalar(context, rd, rn, rm, size, q, context.Arm64Assembler.SqrdmlahElt2regElement); + } + + public static void Vqrdmlsh(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorTernaryRd(context, rd, rn, rm, size, q, context.Arm64Assembler.SqrdmlshVecV); + } + + public static void VqrdmlshS(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorTernaryRdByScalar(context, rd, rn, rm, size, q, context.Arm64Assembler.SqrdmlshElt2regElement); + } + + public static void Vqrdmulh(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, context.Arm64Assembler.SqrdmulhVecV, context.Arm64Assembler.SqrdmulhVecS); + } + + public static void VqrdmulhS(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinaryByScalar(context, rd, rn, rm, size, q, context.Arm64Assembler.SqrdmulhElt2regElement); + } + + public static void Vqrshl(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rm, rn, size, q, context.Arm64Assembler.SqrshlV, context.Arm64Assembler.SqrshlS); + } + + public static void Vqrshrn(CodeGenContext context, uint rd, uint rm, bool u, uint op, uint imm6) + { + uint size = InstEmitNeonCommon.GetSizeFromImm6(imm6); + uint shift = InstEmitNeonShift.GetShiftRight(imm6, size); + + if (u && op == 0) + { + InstEmitNeonCommon.EmitVectorBinaryNarrowShift(context, rd, rm, shift, size, isShl: false, context.Arm64Assembler.SqrshrunV); + } + else if (!u && op == 1) + { + InstEmitNeonCommon.EmitVectorBinaryNarrowShift(context, rd, rm, shift, size, isShl: false, context.Arm64Assembler.SqrshrnV); + } + else + { + Debug.Assert(u && op == 1); // !u && op == 0 is the encoding for another instruction. + + InstEmitNeonCommon.EmitVectorBinaryNarrowShift(context, rd, rm, shift, size, isShl: false, context.Arm64Assembler.UqrshrnV); + } + } + + public static void VqshlI(CodeGenContext context, uint rd, uint rm, bool u, uint op, uint l, uint imm6, uint q) + { + uint size = InstEmitNeonCommon.GetSizeFromImm7(imm6 | (l << 6)); + uint shift = InstEmitNeonShift.GetShiftLeft(imm6, size); + + if (u && op == 0) + { + InstEmitNeonCommon.EmitVectorBinaryShift(context, rd, rm, shift, size, q, isShl: true, context.Arm64Assembler.SqshluV, context.Arm64Assembler.SqshluS); + } + else if (!u && op == 1) + { + InstEmitNeonCommon.EmitVectorBinaryShift(context, rd, rm, shift, size, q, isShl: true, context.Arm64Assembler.SqshlImmV, context.Arm64Assembler.SqshlImmS); + } + else + { + Debug.Assert(u && op == 1); // !u && op == 0 is the encoding for another instruction. + + InstEmitNeonCommon.EmitVectorBinaryShift(context, rd, rm, shift, size, q, isShl: true, context.Arm64Assembler.UqshlImmV, context.Arm64Assembler.UqshlImmS); + } + } + + public static void VqshlR(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q) + { + if (u) + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rm, rn, size, q, context.Arm64Assembler.UqshlRegV, context.Arm64Assembler.UqshlRegS); + } + else + { + InstEmitNeonCommon.EmitVectorBinary(context, rd, rm, rn, size, q, context.Arm64Assembler.SqshlRegV, context.Arm64Assembler.SqshlRegS); + } + } + + public static void Vqshrn(CodeGenContext context, uint rd, uint rm, bool u, uint op, uint imm6) + { + uint size = InstEmitNeonCommon.GetSizeFromImm6(imm6); + uint shift = InstEmitNeonShift.GetShiftRight(imm6, size); + + if (u && op == 0) + { + InstEmitNeonCommon.EmitVectorBinaryNarrowShift(context, rd, rm, shift, size, isShl: false, context.Arm64Assembler.SqshrunV); + } + else if (!u && op == 1) + { + InstEmitNeonCommon.EmitVectorBinaryNarrowShift(context, rd, rm, shift, size, isShl: false, context.Arm64Assembler.SqshrnV); + } + else + { + Debug.Assert(u && op == 1); // !u && op == 0 is the encoding for another instruction. + + InstEmitNeonCommon.EmitVectorBinaryNarrowShift(context, rd, rm, shift, size, isShl: false, context.Arm64Assembler.UqshrnV); + } + } + + public static void Vqsub(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary( + context, + rd, + rn, + rm, + size, + q, + u ? context.Arm64Assembler.UqsubV : context.Arm64Assembler.SqsubV, + u ? context.Arm64Assembler.UqsubS : context.Arm64Assembler.SqsubS); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonShift.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonShift.cs new file mode 100644 index 000000000..9f8d0bdef --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonShift.cs @@ -0,0 +1,123 @@ +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitNeonShift + { + public static void Vshll(CodeGenContext context, uint rd, uint rm, uint imm6, bool u) + { + uint size = InstEmitNeonCommon.GetSizeFromImm7(imm6); + uint shift = GetShiftLeft(imm6, size); + + InstEmitNeonCommon.EmitVectorBinaryLongShift(context, rd, rm, shift, size, isShl: true, u ? context.Arm64Assembler.Ushll : context.Arm64Assembler.Sshll); + } + + public static void Vshll2(CodeGenContext context, uint rd, uint rm, uint size) + { + // Shift can't be encoded, so shift by value - 1 first, then first again by 1. + // Doesn't matter if we do a signed or unsigned shift in this case since all sign bits will be shifted out. + + uint shift = 8u << (int)size; + + InstEmitNeonCommon.EmitVectorBinaryLongShift(context, rd, rm, shift - 1, size, isShl: true, context.Arm64Assembler.Sshll); + InstEmitNeonCommon.EmitVectorBinaryLongShift(context, rd, rd, 1, size, isShl: true, context.Arm64Assembler.Sshll); + } + + public static void VshlI(CodeGenContext context, uint rd, uint rm, uint l, uint imm6, uint q) + { + uint size = InstEmitNeonCommon.GetSizeFromImm7(imm6 | (l << 6)); + uint shift = GetShiftLeft(imm6, size); + + InstEmitNeonCommon.EmitVectorBinaryShift(context, rd, rm, shift, size, q, isShl: true, context.Arm64Assembler.ShlV, context.Arm64Assembler.ShlS); + } + + public static void VshlR(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q) + { + InstEmitNeonCommon.EmitVectorBinary( + context, + rd, + rm, + rn, + size, + q, + u ? context.Arm64Assembler.UshlV : context.Arm64Assembler.SshlV, + u ? context.Arm64Assembler.UshlS : context.Arm64Assembler.SshlS); + } + + public static void Vshr(CodeGenContext context, uint rd, uint rm, bool u, uint l, uint imm6, uint q) + { + uint size = InstEmitNeonCommon.GetSizeFromImm7(imm6 | (l << 6)); + uint shift = GetShiftRight(imm6, size); + + InstEmitNeonCommon.EmitVectorBinaryShift( + context, + rd, + rm, + shift, + size, + q, + isShl: false, + u ? context.Arm64Assembler.UshrV : context.Arm64Assembler.SshrV, + u ? context.Arm64Assembler.UshrS : context.Arm64Assembler.SshrS); + } + + public static void Vshrn(CodeGenContext context, uint rd, uint rm, uint imm6) + { + uint size = InstEmitNeonCommon.GetSizeFromImm6(imm6); + uint shift = GetShiftRight(imm6, size); + + InstEmitNeonCommon.EmitVectorBinaryNarrowShift(context, rd, rm, shift, size, isShl: false, context.Arm64Assembler.Shrn); + } + + public static void Vsli(CodeGenContext context, uint rd, uint rm, uint l, uint imm6, uint q) + { + uint size = InstEmitNeonCommon.GetSizeFromImm7(imm6 | (l << 6)); + uint shift = GetShiftLeft(imm6, size); + + InstEmitNeonCommon.EmitVectorBinaryShift( + context, + rd, + rm, + shift, + size, + q, + isShl: true, + context.Arm64Assembler.SliV, + context.Arm64Assembler.SliS); + } + + public static void Vsra(CodeGenContext context, uint rd, uint rm, bool u, uint l, uint imm6, uint q) + { + uint size = InstEmitNeonCommon.GetSizeFromImm7(imm6 | (l << 6)); + uint shift = GetShiftRight(imm6, size); + + InstEmitNeonCommon.EmitVectorTernaryRdShift( + context, + rd, + rm, + shift, + size, + q, + isShl: false, + u ? context.Arm64Assembler.UsraV : context.Arm64Assembler.SsraV, + u ? context.Arm64Assembler.UsraS : context.Arm64Assembler.SsraS); + } + + public static void Vsri(CodeGenContext context, uint rd, uint rm, uint l, uint imm6, uint q) + { + uint size = InstEmitNeonCommon.GetSizeFromImm7(imm6 | (l << 6)); + uint shift = GetShiftRight(imm6, size); + + InstEmitNeonCommon.EmitVectorBinaryShift(context, rd, rm, shift, size, q, isShl: false, context.Arm64Assembler.SriV, context.Arm64Assembler.SriS); + } + + public static uint GetShiftLeft(uint imm6, uint size) + { + return size < 3 ? imm6 - (8u << (int)size) : imm6; + } + + public static uint GetShiftRight(uint imm6, uint size) + { + return (size == 3 ? 64u : (16u << (int)size)) - imm6; + ; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonSystem.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonSystem.cs new file mode 100644 index 000000000..8c7bf91d5 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonSystem.cs @@ -0,0 +1,77 @@ +using Ryujinx.Cpu.LightningJit.CodeGen; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitNeonSystem + { + public static void Vmrs(CodeGenContext context, uint rt, uint reg) + { + if (context.ConsumeSkipNextInstruction()) + { + // This case means that we managed to combine a VCMP and VMRS instruction, + // so we have nothing to do here as FCMP/FCMPE already set PSTATE.NZCV. + context.SetNzcvModified(); + + return; + } + + if (reg == 1) + { + // FPSCR + + Operand ctx = InstEmitSystem.Register(context.RegisterAllocator.FixedContextRegister); + + if (rt == RegisterUtils.PcRegister) + { + using ScopedRegister fpsrRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.LdrRiUn(fpsrRegister.Operand, ctx, NativeContextOffsets.FpFlagsBaseOffset); + context.Arm64Assembler.Lsr(fpsrRegister.Operand, fpsrRegister.Operand, InstEmitCommon.Const(28)); + + InstEmitCommon.RestoreNzcvFlags(context, fpsrRegister.Operand); + + context.SetNzcvModified(); + } + else + { + // FPSCR is a combination of the FPCR and FPSR registers. + // We also need to set the FPSR NZCV bits that no longer exist on AArch64. + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand rtOperand = InstEmitCommon.GetOutputGpr(context, rt); + + context.Arm64Assembler.MrsFpsr(rtOperand); + context.Arm64Assembler.MrsFpcr(tempRegister.Operand); + context.Arm64Assembler.Orr(rtOperand, rtOperand, tempRegister.Operand); + context.Arm64Assembler.LdrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FpFlagsBaseOffset); + context.Arm64Assembler.Bfc(tempRegister.Operand, 0, 28); + context.Arm64Assembler.Orr(rtOperand, rtOperand, tempRegister.Operand); + } + } + else + { + Operand rtOperand = InstEmitCommon.GetOutputGpr(context, rt); + + context.Arm64Assembler.Mov(rtOperand, 0u); + } + } + + public static void Vmsr(CodeGenContext context, uint rt, uint reg) + { + if (reg == 1) + { + // FPSCR + + // TODO: Do not set bits related to features that are not supported (like FP16)? + + Operand ctx = InstEmitSystem.Register(context.RegisterAllocator.FixedContextRegister); + Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt); + + context.Arm64Assembler.MsrFpcr(rtOperand); + context.Arm64Assembler.MsrFpsr(rtOperand); + context.Arm64Assembler.StrRiUn(rtOperand, ctx, NativeContextOffsets.FpFlagsBaseOffset); + } + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitSaturate.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitSaturate.cs new file mode 100644 index 000000000..e2354f448 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitSaturate.cs @@ -0,0 +1,452 @@ +using Ryujinx.Cpu.LightningJit.CodeGen; +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; +using System.Diagnostics; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitSaturate + { + public static void Qadd(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitAddSubSaturate(context, rd, rn, rm, doubling: false, add: true); + } + + public static void Qadd16(CodeGenContext context, uint rd, uint rn, uint rm) + { + InstEmitCommon.EmitSigned16BitPair(context, rd, rn, rm, (d, n, m) => + { + context.Arm64Assembler.Add(d, n, m); + EmitSaturateRange(context, d, d, 16, unsigned: false, setQ: false); + }); + } + + public static void Qadd8(CodeGenContext context, uint rd, uint rn, uint rm) + { + InstEmitCommon.EmitSigned8BitPair(context, rd, rn, rm, (d, n, m) => + { + context.Arm64Assembler.Add(d, n, m); + EmitSaturateRange(context, d, d, 8, unsigned: false, setQ: false); + }); + } + + public static void Qasx(CodeGenContext context, uint rd, uint rn, uint rm) + { + InstEmitCommon.EmitSigned16BitXPair(context, rd, rn, rm, (d, n, m, e) => + { + if (e == 0) + { + context.Arm64Assembler.Sub(d, n, m); + } + else + { + context.Arm64Assembler.Add(d, n, m); + } + + EmitSaturateRange(context, d, d, 16, unsigned: false, setQ: false); + }); + } + + public static void Qdadd(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitAddSubSaturate(context, rd, rn, rm, doubling: true, add: true); + } + + public static void Qdsub(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitAddSubSaturate(context, rd, rn, rm, doubling: true, add: false); + } + + public static void Qsax(CodeGenContext context, uint rd, uint rn, uint rm) + { + InstEmitCommon.EmitSigned16BitXPair(context, rd, rn, rm, (d, n, m, e) => + { + if (e == 0) + { + context.Arm64Assembler.Add(d, n, m); + } + else + { + context.Arm64Assembler.Sub(d, n, m); + } + + EmitSaturateRange(context, d, d, 16, unsigned: false, setQ: false); + }); + } + + public static void Qsub(CodeGenContext context, uint rd, uint rn, uint rm) + { + EmitAddSubSaturate(context, rd, rn, rm, doubling: false, add: false); + } + + public static void Qsub16(CodeGenContext context, uint rd, uint rn, uint rm) + { + InstEmitCommon.EmitSigned16BitPair(context, rd, rn, rm, (d, n, m) => + { + context.Arm64Assembler.Sub(d, n, m); + EmitSaturateRange(context, d, d, 16, unsigned: false, setQ: false); + }); + } + + public static void Qsub8(CodeGenContext context, uint rd, uint rn, uint rm) + { + InstEmitCommon.EmitSigned8BitPair(context, rd, rn, rm, (d, n, m) => + { + context.Arm64Assembler.Sub(d, n, m); + EmitSaturateRange(context, d, d, 8, unsigned: false, setQ: false); + }); + } + + public static void Ssat(CodeGenContext context, uint rd, uint imm, uint rn, bool sh, uint shift) + { + EmitSaturate(context, rd, imm + 1, rn, sh, shift, unsigned: false); + } + + public static void Ssat16(CodeGenContext context, uint rd, uint imm, uint rn) + { + InstEmitCommon.EmitSigned16BitPair(context, rd, rn, (d, n) => + { + EmitSaturateRange(context, d, n, imm + 1, unsigned: false); + }); + } + + public static void Uqadd16(CodeGenContext context, uint rd, uint rn, uint rm) + { + InstEmitCommon.EmitUnsigned16BitPair(context, rd, rn, rm, (d, n, m) => + { + context.Arm64Assembler.Add(d, n, m); + EmitSaturateUnsignedRange(context, d, 16); + }); + } + + public static void Uqadd8(CodeGenContext context, uint rd, uint rn, uint rm) + { + InstEmitCommon.EmitUnsigned8BitPair(context, rd, rn, rm, (d, n, m) => + { + context.Arm64Assembler.Add(d, n, m); + EmitSaturateUnsignedRange(context, d, 8); + }); + } + + public static void Uqasx(CodeGenContext context, uint rd, uint rn, uint rm) + { + InstEmitCommon.EmitUnsigned16BitXPair(context, rd, rn, rm, (d, n, m, e) => + { + if (e == 0) + { + context.Arm64Assembler.Sub(d, n, m); + } + else + { + context.Arm64Assembler.Add(d, n, m); + } + + EmitSaturateUnsignedRange(context, d, 16); + }); + } + + public static void Uqsax(CodeGenContext context, uint rd, uint rn, uint rm) + { + InstEmitCommon.EmitUnsigned16BitXPair(context, rd, rn, rm, (d, n, m, e) => + { + if (e == 0) + { + context.Arm64Assembler.Add(d, n, m); + } + else + { + context.Arm64Assembler.Sub(d, n, m); + } + + EmitSaturateUnsignedRange(context, d, 16); + }); + } + + public static void Uqsub16(CodeGenContext context, uint rd, uint rn, uint rm) + { + InstEmitCommon.EmitSigned16BitPair(context, rd, rn, rm, (d, n, m) => + { + context.Arm64Assembler.Sub(d, n, m); + EmitSaturateUnsignedRange(context, d, 16); + }); + } + + public static void Uqsub8(CodeGenContext context, uint rd, uint rn, uint rm) + { + InstEmitCommon.EmitSigned8BitPair(context, rd, rn, rm, (d, n, m) => + { + context.Arm64Assembler.Sub(d, n, m); + EmitSaturateUnsignedRange(context, d, 8); + }); + } + + public static void Usat(CodeGenContext context, uint rd, uint imm, uint rn, bool sh, uint shift) + { + EmitSaturate(context, rd, imm, rn, sh, shift, unsigned: true); + } + + public static void Usat16(CodeGenContext context, uint rd, uint imm, uint rn) + { + InstEmitCommon.EmitSigned16BitPair(context, rd, rn, (d, n) => + { + EmitSaturateRange(context, d, n, imm, unsigned: true); + }); + } + + private static void EmitAddSubSaturate(CodeGenContext context, uint rd, uint rn, uint rm, bool doubling, bool add) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm); + + using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand tempN64 = new(OperandKind.Register, OperandType.I64, tempN.Operand.Value); + Operand tempM64 = new(OperandKind.Register, OperandType.I64, tempM.Operand.Value); + + context.Arm64Assembler.Sxtw(tempN64, rnOperand); + context.Arm64Assembler.Sxtw(tempM64, rmOperand); + + if (doubling) + { + context.Arm64Assembler.Lsl(tempN64, tempN64, InstEmitCommon.Const(1)); + + EmitSaturateLongToInt(context, tempN64, tempN64); + } + + if (add) + { + context.Arm64Assembler.Add(tempN64, tempN64, tempM64); + } + else + { + context.Arm64Assembler.Sub(tempN64, tempN64, tempM64); + } + + EmitSaturateLongToInt(context, rdOperand, tempN64); + } + + private static void EmitSaturate(CodeGenContext context, uint rd, uint imm, uint rn, bool sh, uint shift, bool unsigned) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + + if (sh && shift == 0) + { + shift = 31; + } + + if (shift != 0) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + if (sh) + { + context.Arm64Assembler.Asr(tempRegister.Operand, rnOperand, InstEmitCommon.Const((int)shift)); + } + else + { + context.Arm64Assembler.Lsl(tempRegister.Operand, rnOperand, InstEmitCommon.Const((int)shift)); + } + + EmitSaturateRange(context, rdOperand, tempRegister.Operand, imm, unsigned); + } + else + { + EmitSaturateRange(context, rdOperand, rnOperand, imm, unsigned); + } + } + + private static void EmitSaturateRange(CodeGenContext context, Operand result, Operand value, uint saturateTo, bool unsigned, bool setQ = true) + { + Debug.Assert(saturateTo <= 32); + Debug.Assert(!unsigned || saturateTo < 32); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + ScopedRegister tempValue = default; + + bool resultValueOverlap = result.Value == value.Value; + + if (!unsigned && saturateTo == 32) + { + // No saturation possible for this case. + + if (!resultValueOverlap) + { + context.Arm64Assembler.Mov(result, value); + } + + return; + } + else if (saturateTo == 0) + { + // Result is always zero if we saturate 0 bits. + + context.Arm64Assembler.Mov(result, 0u); + + return; + } + + if (resultValueOverlap) + { + tempValue = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.Mov(tempValue.Operand, value); + value = tempValue.Operand; + } + + if (unsigned) + { + // Negative values always saturate (to zero). + // So we must always ignore the sign bit when masking, so that the truncated value will differ from the original one. + + context.Arm64Assembler.And(result, value, InstEmitCommon.Const((int)(uint.MaxValue >> (32 - (int)saturateTo)))); + } + else + { + context.Arm64Assembler.Sbfx(result, value, 0, (int)saturateTo); + } + + context.Arm64Assembler.Sub(tempRegister.Operand, value, result); + + int branchIndex = context.CodeWriter.InstructionPointer; + + // If the result is 0, the values are equal and we don't need saturation. + context.Arm64Assembler.Cbz(tempRegister.Operand, 0); + + // Saturate and set Q flag. + if (unsigned) + { + if (saturateTo == 31) + { + // Only saturation case possible when going from 32 bits signed to 32 or 31 bits unsigned + // is when the signed input is negative, as all positive values are representable on a 31 bits range. + + context.Arm64Assembler.Mov(result, 0u); + } + else + { + context.Arm64Assembler.Asr(result, value, InstEmitCommon.Const(31)); + context.Arm64Assembler.Mvn(result, result); + context.Arm64Assembler.Lsr(result, result, InstEmitCommon.Const(32 - (int)saturateTo)); + } + } + else + { + if (saturateTo == 1) + { + context.Arm64Assembler.Asr(result, value, InstEmitCommon.Const(31)); + } + else + { + context.Arm64Assembler.Mov(result, uint.MaxValue >> (33 - (int)saturateTo)); + context.Arm64Assembler.Eor(result, result, value, ArmShiftType.Asr, 31); + } + } + + if (setQ) + { + SetQFlag(context); + } + + int delta = context.CodeWriter.InstructionPointer - branchIndex; + context.CodeWriter.WriteInstructionAt(branchIndex, context.CodeWriter.ReadInstructionAt(branchIndex) | (uint)((delta & 0x7ffff) << 5)); + + if (resultValueOverlap) + { + tempValue.Dispose(); + } + } + + private static void EmitSaturateUnsignedRange(CodeGenContext context, Operand value, uint saturateTo) + { + Debug.Assert(saturateTo <= 32); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + if (saturateTo == 32) + { + // No saturation possible for this case. + + return; + } + else if (saturateTo == 0) + { + // Result is always zero if we saturate 0 bits. + + context.Arm64Assembler.Mov(value, 0u); + + return; + } + + context.Arm64Assembler.Lsr(tempRegister.Operand, value, InstEmitCommon.Const(32 - (int)saturateTo)); + + int branchIndex = context.CodeWriter.InstructionPointer; + + // If the result is 0, the values are equal and we don't need saturation. + context.Arm64Assembler.Cbz(tempRegister.Operand, 0); + + // Saturate. + context.Arm64Assembler.Mov(value, uint.MaxValue >> (32 - (int)saturateTo)); + + int delta = context.CodeWriter.InstructionPointer - branchIndex; + context.CodeWriter.WriteInstructionAt(branchIndex, context.CodeWriter.ReadInstructionAt(branchIndex) | (uint)((delta & 0x7ffff) << 5)); + } + + private static void EmitSaturateLongToInt(CodeGenContext context, Operand result, Operand value) + { + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + ScopedRegister tempValue = default; + + bool resultValueOverlap = result.Value == value.Value; + + if (resultValueOverlap) + { + tempValue = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand tempValue64 = new(OperandKind.Register, OperandType.I64, tempValue.Operand.Value); + + context.Arm64Assembler.Mov(tempValue64, value); + value = tempValue64; + } + + Operand temp64 = new(OperandKind.Register, OperandType.I64, tempRegister.Operand.Value); + Operand result64 = new(OperandKind.Register, OperandType.I64, result.Value); + + context.Arm64Assembler.Sxtw(result64, value); + context.Arm64Assembler.Sub(temp64, value, result64); + + int branchIndex = context.CodeWriter.InstructionPointer; + + // If the result is 0, the values are equal and we don't need saturation. + context.Arm64Assembler.Cbz(temp64, 0); + + // Saturate and set Q flag. + context.Arm64Assembler.Mov(result, uint.MaxValue >> 1); + context.Arm64Assembler.Eor(result64, result64, value, ArmShiftType.Asr, 63); + + SetQFlag(context); + + int delta = context.CodeWriter.InstructionPointer - branchIndex; + context.CodeWriter.WriteInstructionAt(branchIndex, context.CodeWriter.ReadInstructionAt(branchIndex) | (uint)((delta & 0x7ffff) << 5)); + + context.Arm64Assembler.Mov(result, result); // Zero-extend. + + if (resultValueOverlap) + { + tempValue.Dispose(); + } + } + + public static void SetQFlag(CodeGenContext context) + { + Operand ctx = InstEmitSystem.Register(context.RegisterAllocator.FixedContextRegister); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.LdrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset); + context.Arm64Assembler.Orr(tempRegister.Operand, tempRegister.Operand, InstEmitCommon.Const(1 << 27)); + context.Arm64Assembler.StrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitSystem.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitSystem.cs new file mode 100644 index 000000000..be0976fd3 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitSystem.cs @@ -0,0 +1,648 @@ +using Ryujinx.Cpu.LightningJit.CodeGen; +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; +using System; +using System.Diagnostics; +using System.Numerics; +using System.Runtime.InteropServices; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitSystem + { + private delegate void SoftwareInterruptHandler(ulong address, int imm); + private delegate ulong Get64(); + private delegate bool GetBool(); + + private const int SpIndex = 31; + + public static void Bkpt(CodeGenContext context, uint imm) + { + context.AddPendingBkpt(imm); + + context.Arm64Assembler.B(0); + } + + public static void Cps(CodeGenContext context, uint imod, uint m, uint a, uint i, uint f, uint mode) + { + // NOP in user mode. + } + + public static void Dbg(CodeGenContext context, uint option) + { + // NOP in ARMv8. + } + + public static void Hlt(CodeGenContext context, uint imm) + { + } + + public static void Mcr(CodeGenContext context, uint encoding, uint coproc, uint opc1, uint rt, uint crn, uint crm, uint opc2) + { + if (coproc != 15 || opc1 != 0) + { + Udf(context, encoding, 0); + + return; + } + + Operand ctx = Register(context.RegisterAllocator.FixedContextRegister); + Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt); + + switch (crn) + { + case 13: // Process and Thread Info. + if (crm == 0) + { + switch (opc2) + { + case 2: + context.Arm64Assembler.StrRiUn(rtOperand, ctx, NativeContextOffsets.TpidrEl0Offset); + return; + } + } + break; + } + } + + public static void Mcrr(CodeGenContext context, uint encoding, uint coproc, uint opc1, uint rt, uint crm) + { + if (coproc != 15 || opc1 != 0) + { + Udf(context, encoding, 0); + + return; + } + + // We don't have any system register that needs to be modified using a 64-bit value. + } + + public static void Mrc(CodeGenContext context, uint encoding, uint coproc, uint opc1, uint rt, uint crn, uint crm, uint opc2) + { + if (coproc != 15 || opc1 != 0) + { + Udf(context, encoding, 0); + + return; + } + + Operand ctx = Register(context.RegisterAllocator.FixedContextRegister); + Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt); + bool hasValue = false; + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + Operand dest = rt == RegisterUtils.PcRegister ? tempRegister.Operand : rtOperand; + + switch (crn) + { + case 13: // Process and Thread Info. + if (crm == 0) + { + switch (opc2) + { + case 2: + context.Arm64Assembler.LdrRiUn(dest, ctx, NativeContextOffsets.TpidrEl0Offset); + hasValue = true; + break; + case 3: + context.Arm64Assembler.LdrRiUn(dest, ctx, NativeContextOffsets.TpidrroEl0Offset); + hasValue = true; + break; + } + } + break; + } + + if (rt == RegisterUtils.PcRegister) + { + context.Arm64Assembler.MsrNzcv(dest); + context.SetNzcvModified(); + } + else if (!hasValue) + { + context.Arm64Assembler.Mov(dest, 0u); + } + } + + public static void Mrrc(CodeGenContext context, uint encoding, uint coproc, uint opc1, uint rt, uint rt2, uint crm) + { + if (coproc != 15) + { + Udf(context, encoding, 0); + + return; + } + + switch (crm) + { + case 14: + switch (opc1) + { + case 0: + context.AddPendingReadCntpct(rt, rt2); + context.Arm64Assembler.B(0); + return; + } + break; + } + + // Unsupported system register. + context.Arm64Assembler.Mov(InstEmitCommon.GetOutputGpr(context, rt), 0u); + context.Arm64Assembler.Mov(InstEmitCommon.GetOutputGpr(context, rt2), 0u); + } + + public static void Mrs(CodeGenContext context, uint rd, bool r) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + + if (r) + { + // Reads SPSR, unpredictable in user mode. + + context.Arm64Assembler.Mov(rdOperand, 0u); + } + else + { + Operand ctx = Register(context.RegisterAllocator.FixedContextRegister); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.LdrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset); + + // Copy GE flags to destination register. + context.Arm64Assembler.Ubfx(rdOperand, tempRegister.Operand, 16, 4); + + // Insert Q flag. + context.Arm64Assembler.And(tempRegister.Operand, tempRegister.Operand, InstEmitCommon.Const(1 << 27)); + context.Arm64Assembler.Orr(rdOperand, rdOperand, tempRegister.Operand); + + // Insert NZCV flags. + context.Arm64Assembler.MrsNzcv(tempRegister.Operand); + context.Arm64Assembler.Orr(rdOperand, rdOperand, tempRegister.Operand); + + // All other flags can't be accessed in user mode or have "unknown" values. + } + } + + public static void MrsBr(CodeGenContext context, uint rd, uint m1, bool r) + { + Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd); + + // Reads banked register, unpredictable in user mode. + + context.Arm64Assembler.Mov(rdOperand, 0u); + } + + public static void MsrBr(CodeGenContext context, uint rn, uint m1, bool r) + { + // Writes banked register, unpredictable in user mode. + } + + public static void MsrI(CodeGenContext context, uint imm, uint mask, bool r) + { + if (r) + { + // Writes SPSR, unpredictable in user mode. + } + else + { + Operand ctx = Register(context.RegisterAllocator.FixedContextRegister); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempRegister2 = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.LdrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset); + + if ((mask & 2) != 0) + { + // Endian flag. + + context.Arm64Assembler.Mov(tempRegister2.Operand, (imm >> 9) & 1); + context.Arm64Assembler.Bfi(tempRegister.Operand, tempRegister2.Operand, 9, 1); + } + + if ((mask & 4) != 0) + { + // GE flags. + + context.Arm64Assembler.Mov(tempRegister2.Operand, (imm >> 16) & 0xf); + context.Arm64Assembler.Bfi(tempRegister.Operand, tempRegister2.Operand, 16, 4); + } + + if ((mask & 8) != 0) + { + // NZCVQ flags. + + context.Arm64Assembler.Mov(tempRegister2.Operand, (imm >> 27) & 0x1f); + context.Arm64Assembler.Bfi(tempRegister.Operand, tempRegister2.Operand, 27, 5); + context.Arm64Assembler.Mov(tempRegister2.Operand, (imm >> 28) & 0xf); + InstEmitCommon.RestoreNzcvFlags(context, tempRegister2.Operand); + context.SetNzcvModified(); + } + } + } + + public static void MsrR(CodeGenContext context, uint rn, uint mask, bool r) + { + Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn); + + if (r) + { + // Writes SPSR, unpredictable in user mode. + } + else + { + Operand ctx = Register(context.RegisterAllocator.FixedContextRegister); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister tempRegister2 = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.LdrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset); + + if ((mask & 2) != 0) + { + // Endian flag. + + context.Arm64Assembler.Lsr(tempRegister2.Operand, rnOperand, InstEmitCommon.Const(9)); + context.Arm64Assembler.Bfi(tempRegister.Operand, tempRegister2.Operand, 9, 1); + } + + if ((mask & 4) != 0) + { + // GE flags. + + context.Arm64Assembler.Lsr(tempRegister2.Operand, rnOperand, InstEmitCommon.Const(16)); + context.Arm64Assembler.Bfi(tempRegister.Operand, tempRegister2.Operand, 16, 4); + } + + if ((mask & 8) != 0) + { + // NZCVQ flags. + + context.Arm64Assembler.Lsr(tempRegister2.Operand, rnOperand, InstEmitCommon.Const(27)); + context.Arm64Assembler.Bfi(tempRegister.Operand, tempRegister2.Operand, 27, 5); + context.Arm64Assembler.Lsr(tempRegister2.Operand, rnOperand, InstEmitCommon.Const(28)); + InstEmitCommon.RestoreNzcvFlags(context, tempRegister2.Operand); + context.SetNzcvModified(); + } + } + } + + public static void Setend(CodeGenContext context, bool e) + { + Operand ctx = Register(context.RegisterAllocator.FixedContextRegister); + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + context.Arm64Assembler.LdrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset); + + if (e) + { + context.Arm64Assembler.Orr(tempRegister.Operand, tempRegister.Operand, InstEmitCommon.Const(1 << 9)); + } + else + { + context.Arm64Assembler.Bfc(tempRegister.Operand, 9, 1); + } + + context.Arm64Assembler.StrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset); + } + + public static void Svc(CodeGenContext context, uint imm) + { + context.AddPendingSvc(imm); + context.Arm64Assembler.B(0); + } + + public static void Udf(CodeGenContext context, uint encoding, uint imm) + { + context.AddPendingUdf(encoding); + context.Arm64Assembler.B(0); + } + + public static void PrivilegedInstruction(CodeGenContext context, uint encoding) + { + Udf(context, encoding, 0); + } + + private static IntPtr GetBkptHandlerPtr() + { + return Marshal.GetFunctionPointerForDelegate(NativeInterface.Break); + } + + private static IntPtr GetSvcHandlerPtr() + { + return Marshal.GetFunctionPointerForDelegate(NativeInterface.SupervisorCall); + } + + private static IntPtr GetUdfHandlerPtr() + { + return Marshal.GetFunctionPointerForDelegate(NativeInterface.Undefined); + } + + private static IntPtr GetCntpctEl0Ptr() + { + return Marshal.GetFunctionPointerForDelegate(NativeInterface.GetCntpctEl0); + } + + private static IntPtr CheckSynchronizationPtr() + { + return Marshal.GetFunctionPointerForDelegate(NativeInterface.CheckSynchronization); + } + + public static bool NeedsCall(InstName name) + { + // All instructions that might do a host call should be included here. + // That is required to reserve space on the stack for caller saved registers. + + switch (name) + { + case InstName.Mcr: + case InstName.Mrc: + case InstName.Mrrc: + case InstName.Svc: + case InstName.Udf: + return true; + } + + return false; + } + + public static void WriteBkpt(CodeWriter writer, RegisterAllocator regAlloc, TailMerger tailMerger, int spillBaseOffset, uint pc, uint imm) + { + Assembler asm = new(writer); + + WriteCall(ref asm, regAlloc, GetBkptHandlerPtr(), skipContext: true, spillBaseOffset, null, pc, imm); + WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, skipContext: true, spillBaseOffset); + } + + public static void WriteSvc(CodeWriter writer, RegisterAllocator regAlloc, TailMerger tailMerger, int spillBaseOffset, uint pc, uint svcId) + { + Assembler asm = new(writer); + + WriteCall(ref asm, regAlloc, GetSvcHandlerPtr(), skipContext: true, spillBaseOffset, null, pc, svcId); + WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, skipContext: true, spillBaseOffset); + } + + public static void WriteUdf(CodeWriter writer, RegisterAllocator regAlloc, TailMerger tailMerger, int spillBaseOffset, uint pc, uint imm) + { + Assembler asm = new(writer); + + WriteCall(ref asm, regAlloc, GetUdfHandlerPtr(), skipContext: true, spillBaseOffset, null, pc, imm); + WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, skipContext: true, spillBaseOffset); + } + + public static void WriteReadCntpct(CodeWriter writer, RegisterAllocator regAlloc, int spillBaseOffset, int rt, int rt2) + { + Assembler asm = new(writer); + + uint resultMask = (1u << rt) | (1u << rt2); + int tempRegister = 0; + + while ((resultMask & (1u << tempRegister)) != 0 && tempRegister < 32) + { + tempRegister++; + } + + Debug.Assert(tempRegister < 32); + + WriteSpill(ref asm, regAlloc, resultMask, skipContext: false, spillBaseOffset, tempRegister); + + Operand rn = Register(tempRegister); + + asm.Mov(rn, (ulong)GetCntpctEl0Ptr()); + asm.Blr(rn); + + if (rt != rt2) + { + asm.Lsr(Register(rt2), Register(0), InstEmitCommon.Const(32)); + } + + asm.Mov(Register(rt, OperandType.I32), Register(0, OperandType.I32)); // Zero-extend. + + WriteFill(ref asm, regAlloc, resultMask, skipContext: false, spillBaseOffset, tempRegister); + } + + public static void WriteSyncPoint(CodeWriter writer, RegisterAllocator regAlloc, TailMerger tailMerger, int spillBaseOffset) + { + Assembler asm = new(writer); + + WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, skipContext: false, spillBaseOffset); + } + + private static void WriteSyncPoint(CodeWriter writer, ref Assembler asm, RegisterAllocator regAlloc, TailMerger tailMerger, bool skipContext, int spillBaseOffset) + { + int tempRegister = regAlloc.AllocateTempGprRegister(); + + Operand rt = Register(tempRegister, OperandType.I32); + + asm.LdrRiUn(rt, Register(regAlloc.FixedContextRegister), NativeContextOffsets.CounterOffset); + + int branchIndex = writer.InstructionPointer; + asm.Cbnz(rt, 0); + + WriteSpill(ref asm, regAlloc, 1u << tempRegister, skipContext, spillBaseOffset, tempRegister); + + Operand rn = Register(tempRegister == 0 ? 1 : 0); + + asm.Mov(rn, (ulong)CheckSynchronizationPtr()); + asm.Blr(rn); + + tailMerger.AddConditionalZeroReturn(writer, asm, Register(0, OperandType.I32)); + + WriteFill(ref asm, regAlloc, 1u << tempRegister, skipContext, spillBaseOffset, tempRegister); + + asm.LdrRiUn(rt, Register(regAlloc.FixedContextRegister), NativeContextOffsets.CounterOffset); + + uint branchInst = writer.ReadInstructionAt(branchIndex); + writer.WriteInstructionAt(branchIndex, branchInst | (((uint)(writer.InstructionPointer - branchIndex) & 0x7ffff) << 5)); + + asm.Sub(rt, rt, new Operand(OperandKind.Constant, OperandType.I32, 1)); + asm.StrRiUn(rt, Register(regAlloc.FixedContextRegister), NativeContextOffsets.CounterOffset); + + regAlloc.FreeTempGprRegister(tempRegister); + } + + private static void WriteCall( + ref Assembler asm, + RegisterAllocator regAlloc, + IntPtr funcPtr, + bool skipContext, + int spillBaseOffset, + int? resultRegister, + params ulong[] callArgs) + { + uint resultMask = 0u; + + if (resultRegister.HasValue) + { + resultMask = 1u << resultRegister.Value; + } + + int tempRegister = callArgs.Length; + + if (resultRegister.HasValue && tempRegister == resultRegister.Value) + { + tempRegister++; + } + + WriteSpill(ref asm, regAlloc, resultMask, skipContext, spillBaseOffset, tempRegister); + + // We only support up to 7 arguments right now. + // ABI defines the first 8 integer arguments to be passed on registers X0-X7. + // We need at least one register to put the function address on, so that reduces the number of + // registers we can use for that by one. + + Debug.Assert(callArgs.Length < 8); + + for (int index = 0; index < callArgs.Length; index++) + { + asm.Mov(Register(index), callArgs[index]); + } + + Operand rn = Register(tempRegister); + + asm.Mov(rn, (ulong)funcPtr); + asm.Blr(rn); + + if (resultRegister.HasValue && resultRegister.Value != 0) + { + asm.Mov(Register(resultRegister.Value), Register(0)); + } + + WriteFill(ref asm, regAlloc, resultMask, skipContext, spillBaseOffset, tempRegister); + } + + private static void WriteSpill(ref Assembler asm, RegisterAllocator regAlloc, uint exceptMask, bool skipContext, int spillOffset, int tempRegister) + { + WriteSpillOrFill(ref asm, regAlloc, skipContext, exceptMask, spillOffset, tempRegister, spill: true); + } + + private static void WriteFill(ref Assembler asm, RegisterAllocator regAlloc, uint exceptMask, bool skipContext, int spillOffset, int tempRegister) + { + WriteSpillOrFill(ref asm, regAlloc, skipContext, exceptMask, spillOffset, tempRegister, spill: false); + } + + private static void WriteSpillOrFill( + ref Assembler asm, + RegisterAllocator regAlloc, + bool skipContext, + uint exceptMask, + int spillOffset, + int tempRegister, + bool spill) + { + uint gprMask = regAlloc.UsedGprsMask & ~(AbiConstants.GprCalleeSavedRegsMask | exceptMask); + + if (skipContext) + { + gprMask &= ~Compiler.UsableGprsMask; + } + + if (!spill) + { + // We must reload the status register before reloading the GPRs, + // since we might otherwise trash one of them by using it as temp register. + + Operand rt = Register(tempRegister, OperandType.I32); + + asm.LdrRiUn(rt, Register(SpIndex), spillOffset + BitOperations.PopCount(gprMask) * 8); + asm.MsrNzcv(rt); + } + + while (gprMask != 0) + { + int reg = BitOperations.TrailingZeroCount(gprMask); + + if (reg < 31 && (gprMask & (2u << reg)) != 0 && spillOffset < RegisterSaveRestore.Encodable9BitsOffsetLimit) + { + if (spill) + { + asm.StpRiUn(Register(reg), Register(reg + 1), Register(SpIndex), spillOffset); + } + else + { + asm.LdpRiUn(Register(reg), Register(reg + 1), Register(SpIndex), spillOffset); + } + + gprMask &= ~(3u << reg); + spillOffset += 16; + } + else + { + if (spill) + { + asm.StrRiUn(Register(reg), Register(SpIndex), spillOffset); + } + else + { + asm.LdrRiUn(Register(reg), Register(SpIndex), spillOffset); + } + + gprMask &= ~(1u << reg); + spillOffset += 8; + } + } + + if (spill) + { + Operand rt = Register(tempRegister, OperandType.I32); + + asm.MrsNzcv(rt); + asm.StrRiUn(rt, Register(SpIndex), spillOffset); + } + + spillOffset += 8; + + if ((spillOffset & 8) != 0) + { + spillOffset += 8; + } + + uint fpSimdMask = regAlloc.UsedFpSimdMask; + + if (skipContext) + { + fpSimdMask &= ~Compiler.UsableFpSimdMask; + } + + while (fpSimdMask != 0) + { + int reg = BitOperations.TrailingZeroCount(fpSimdMask); + + if (reg < 31 && (fpSimdMask & (2u << reg)) != 0 && spillOffset < RegisterSaveRestore.Encodable9BitsOffsetLimit) + { + if (spill) + { + asm.StpRiUn(Register(reg, OperandType.V128), Register(reg + 1, OperandType.V128), Register(SpIndex), spillOffset); + } + else + { + asm.LdpRiUn(Register(reg, OperandType.V128), Register(reg + 1, OperandType.V128), Register(SpIndex), spillOffset); + } + + fpSimdMask &= ~(3u << reg); + spillOffset += 32; + } + else + { + if (spill) + { + asm.StrRiUn(Register(reg, OperandType.V128), Register(SpIndex), spillOffset); + } + else + { + asm.LdrRiUn(Register(reg, OperandType.V128), Register(SpIndex), spillOffset); + } + + fpSimdMask &= ~(1u << reg); + spillOffset += 16; + } + } + } + + public static Operand Register(int register, OperandType type = OperandType.I64) + { + return new Operand(register, RegisterType.Integer, type); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpArithmetic.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpArithmetic.cs new file mode 100644 index 000000000..efb2fc6b4 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpArithmetic.cs @@ -0,0 +1,95 @@ +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitVfpArithmetic + { + public static void VabsF(CodeGenContext context, uint rd, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FabsFloat); + } + + public static void VaddF(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarBinaryF(context, rd, rn, rm, size, context.Arm64Assembler.FaddFloat); + } + + public static void VdivF(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarBinaryF(context, rd, rn, rm, size, context.Arm64Assembler.FdivFloat); + } + + public static void VfmaF(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarTernaryRdF(context, rd, rn, rm, size, context.Arm64Assembler.FmaddFloat); + } + + public static void VfmsF(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarTernaryRdF(context, rd, rn, rm, size, context.Arm64Assembler.FmsubFloat); + } + + public static void VfnmaF(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarTernaryRdF(context, rd, rn, rm, size, context.Arm64Assembler.FnmaddFloat); + } + + public static void VfnmsF(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarTernaryRdF(context, rd, rn, rm, size, context.Arm64Assembler.FnmsubFloat); + } + + public static void Vmaxnm(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarBinaryF(context, rd, rn, rm, size, context.Arm64Assembler.FmaxnmFloat); + } + + public static void Vminnm(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarBinaryF(context, rd, rn, rm, size, context.Arm64Assembler.FminnmFloat); + } + + public static void VmlaF(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarTernaryMulNegRdF(context, rd, rn, rm, size, negD: false, negProduct: false); + } + + public static void VmlsF(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarTernaryMulNegRdF(context, rd, rn, rm, size, negD: false, negProduct: true); + } + + public static void VmulF(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarBinaryF(context, rd, rn, rm, size, context.Arm64Assembler.FmulFloat); + } + + public static void VnegF(CodeGenContext context, uint rd, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FnegFloat); + } + + public static void VnmlaF(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarTernaryMulNegRdF(context, rd, rn, rm, size, negD: true, negProduct: true); + } + + public static void VnmlsF(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarTernaryMulNegRdF(context, rd, rn, rm, size, negD: true, negProduct: false); + } + + public static void VnmulF(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarBinaryF(context, rd, rn, rm, size, context.Arm64Assembler.FnmulFloat); + } + + public static void VsqrtF(CodeGenContext context, uint rd, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FsqrtFloat); + } + + public static void VsubF(CodeGenContext context, uint rd, uint rn, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarBinaryF(context, rd, rn, rm, size, context.Arm64Assembler.FsubFloat); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpCompare.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpCompare.cs new file mode 100644 index 000000000..f5f306099 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpCompare.cs @@ -0,0 +1,133 @@ +using Ryujinx.Cpu.LightningJit.CodeGen; +using System; +using System.Diagnostics; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitVfpCompare + { + public static void VcmpI(CodeGenContext context, uint cond, uint rd, uint size) + { + EmitVcmpVcmpe(context, cond, rd, 0, size, zero: true, e: false); + } + + public static void VcmpR(CodeGenContext context, uint cond, uint rd, uint rm, uint size) + { + EmitVcmpVcmpe(context, cond, rd, rm, size, zero: false, e: false); + } + + public static void VcmpeI(CodeGenContext context, uint cond, uint rd, uint size) + { + EmitVcmpVcmpe(context, cond, rd, 0, size, zero: true, e: true); + } + + public static void VcmpeR(CodeGenContext context, uint cond, uint rd, uint rm, uint size) + { + EmitVcmpVcmpe(context, cond, rd, rm, size, zero: false, e: true); + } + + private static void EmitVcmpVcmpe(CodeGenContext context, uint cond, uint rd, uint rm, uint size, bool zero, bool e) + { + Debug.Assert(size == 1 || size == 2 || size == 3); + + bool singleRegs = size != 3; + uint ftype = size ^ 2u; + uint opc = zero ? 1u : 0u; + + using ScopedRegister rdReg = InstEmitNeonCommon.MoveScalarToSide(context, rd, singleRegs); + ScopedRegister rmReg; + Operand rmOrZero; + + if (zero) + { + rmReg = default; + rmOrZero = new Operand(0, RegisterType.Vector, OperandType.V128); + } + else + { + rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, singleRegs); + rmOrZero = rmReg.Operand; + } + + using ScopedRegister oldFlags = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + bool canPeepholeOptimize = CanFuseVcmpVmrs(context, cond); + if (!canPeepholeOptimize) + { + InstEmitCommon.GetCurrentFlags(context, oldFlags.Operand); + } + + if (e) + { + context.Arm64Assembler.FcmpeFloat(rdReg.Operand, rmOrZero, opc, ftype); + } + else + { + context.Arm64Assembler.FcmpFloat(rdReg.Operand, rmOrZero, opc, ftype); + } + + // Save result flags from the FCMP operation on FPSCR register, then restore the old flags if needed. + + WriteUpdateFpsrNzcv(context); + + if (!canPeepholeOptimize) + { + InstEmitCommon.RestoreNzcvFlags(context, oldFlags.Operand); + } + + if (!zero) + { + rmReg.Dispose(); + } + } + + private static void WriteUpdateFpsrNzcv(CodeGenContext context) + { + using ScopedRegister fpsrRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); + + Operand ctx = InstEmitSystem.Register(context.RegisterAllocator.FixedContextRegister); + + context.Arm64Assembler.LdrRiUn(fpsrRegister.Operand, ctx, NativeContextOffsets.FpFlagsBaseOffset); + + InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand); + + context.Arm64Assembler.Bfi(fpsrRegister.Operand, flagsRegister.Operand, 28, 4); + context.Arm64Assembler.StrRiUn(fpsrRegister.Operand, ctx, NativeContextOffsets.FpFlagsBaseOffset); + } + + private static bool CanFuseVcmpVmrs(CodeGenContext context, uint vcmpCond) + { + // Conditions might be different for the VCMP and VMRS instructions if they are inside a IT block, + // we don't bother to check right now, so just always skip if inside an IT block. + if (context.InITBlock) + { + return false; + } + + InstInfo nextInfo = context.PeekNextInstruction(); + + // We're looking for a VMRS instructions. + if (nextInfo.Name != InstName.Vmrs) + { + return false; + } + + // Conditions must match. + if (vcmpCond != (nextInfo.Encoding >> 28)) + { + return false; + } + + // Reg must be 1, Rt must be PC indicating VMRS to PSTATE.NZCV. + if (((nextInfo.Encoding >> 16) & 0xf) != 1 || ((nextInfo.Encoding >> 12) & 0xf) != RegisterUtils.PcRegister) + { + return false; + } + + context.SetSkipNextInstruction(); + + return true; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpConvert.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpConvert.cs new file mode 100644 index 000000000..8e4886950 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpConvert.cs @@ -0,0 +1,305 @@ +using System; +using System.Diagnostics; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitVfpConvert + { + public static void Vcvta(CodeGenContext context, uint rd, uint rm, bool op, uint size) + { + if (size == 3) + { + // F64 -> S32/U32 conversion on SIMD is not supported, so we convert it to a GPR, then insert it back into the SIMD register. + + if (op) + { + InstEmitNeonCommon.EmitScalarUnaryToGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.FcvtasFloat); + } + else + { + InstEmitNeonCommon.EmitScalarUnaryToGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.FcvtauFloat); + } + } + else if (op) + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FcvtasS, context.Arm64Assembler.FcvtasSH); + } + else + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FcvtauS, context.Arm64Assembler.FcvtauSH); + } + } + + public static void Vcvtb(CodeGenContext context, uint rd, uint rm, uint sz, uint op) + { + EmitVcvtbVcvtt(context, rd, rm, sz, op, top: false); + } + + public static void Vcvtm(CodeGenContext context, uint rd, uint rm, bool op, uint size) + { + if (size == 3) + { + // F64 -> S32/U32 conversion on SIMD is not supported, so we convert it to a GPR, then insert it back into the SIMD register. + + if (op) + { + InstEmitNeonCommon.EmitScalarUnaryToGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.FcvtmsFloat); + } + else + { + InstEmitNeonCommon.EmitScalarUnaryToGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.FcvtmuFloat); + } + } + else if (op) + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FcvtmsS, context.Arm64Assembler.FcvtmsSH); + } + else + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FcvtmuS, context.Arm64Assembler.FcvtmuSH); + } + } + + public static void Vcvtn(CodeGenContext context, uint rd, uint rm, bool op, uint size) + { + if (size == 3) + { + // F64 -> S32/U32 conversion on SIMD is not supported, so we convert it to a GPR, then insert it back into the SIMD register. + + if (op) + { + InstEmitNeonCommon.EmitScalarUnaryToGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.FcvtnsFloat); + } + else + { + InstEmitNeonCommon.EmitScalarUnaryToGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.FcvtnuFloat); + } + } + else if (op) + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FcvtnsS, context.Arm64Assembler.FcvtnsSH); + } + else + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FcvtnuS, context.Arm64Assembler.FcvtnuSH); + } + } + + public static void Vcvtp(CodeGenContext context, uint rd, uint rm, bool op, uint size) + { + if (size == 3) + { + // F64 -> S32/U32 conversion on SIMD is not supported, so we convert it to a GPR, then insert it back into the SIMD register. + + if (op) + { + InstEmitNeonCommon.EmitScalarUnaryToGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.FcvtpsFloat); + } + else + { + InstEmitNeonCommon.EmitScalarUnaryToGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.FcvtpuFloat); + } + } + else if (op) + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FcvtpsS, context.Arm64Assembler.FcvtpsSH); + } + else + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FcvtpuS, context.Arm64Assembler.FcvtpuSH); + } + } + + public static void VcvtDs(CodeGenContext context, uint rd, uint rm, uint size) + { + bool doubleToSingle = size == 3; + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + if (doubleToSingle) + { + // Double to single. + + using ScopedRegister rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, false); + + context.Arm64Assembler.FcvtFloat(tempRegister.Operand, rmReg.Operand, 0, 1); + + InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, true); + } + else + { + // Single to double. + + using ScopedRegister rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, true); + + context.Arm64Assembler.FcvtFloat(tempRegister.Operand, rmReg.Operand, 1, 0); + + InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, false); + } + } + + public static void VcvtIv(CodeGenContext context, uint rd, uint rm, bool unsigned, uint size) + { + if (size == 3) + { + // F64 -> S32/U32 conversion on SIMD is not supported, so we convert it to a GPR, then insert it back into the SIMD register. + + if (unsigned) + { + InstEmitNeonCommon.EmitScalarUnaryToGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.FcvtzuFloatInt); + } + else + { + InstEmitNeonCommon.EmitScalarUnaryToGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.FcvtzsFloatInt); + } + } + else + { + if (unsigned) + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FcvtzuIntS, context.Arm64Assembler.FcvtzuIntSH); + } + else + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FcvtzsIntS, context.Arm64Assembler.FcvtzsIntSH); + } + } + } + + public static void VcvtVi(CodeGenContext context, uint rd, uint rm, bool unsigned, uint size) + { + if (size == 3) + { + // S32/U32 -> F64 conversion on SIMD is not supported, so we convert it to a GPR, then insert it back into the SIMD register. + + if (unsigned) + { + InstEmitNeonCommon.EmitScalarUnaryFromGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.UcvtfFloatInt); + } + else + { + InstEmitNeonCommon.EmitScalarUnaryFromGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.ScvtfFloatInt); + } + } + else + { + if (unsigned) + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.UcvtfIntS, context.Arm64Assembler.UcvtfIntSH); + } + else + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.ScvtfIntS, context.Arm64Assembler.ScvtfIntSH); + } + } + } + + public static void VcvtXv(CodeGenContext context, uint rd, uint imm5, bool sx, uint sf, uint op, bool u) + { + Debug.Assert(op >> 1 == 0); + + bool unsigned = u; + bool toFixed = op == 1; + uint size = sf; + uint fbits = Math.Clamp((sx ? 32u : 16u) - imm5, 1, 8u << (int)size); + + if (toFixed) + { + if (unsigned) + { + InstEmitNeonCommon.EmitScalarUnaryFixedF(context, rd, rd, fbits, size, is16Bit: false, context.Arm64Assembler.FcvtzuFixS); + } + else + { + InstEmitNeonCommon.EmitScalarUnaryFixedF(context, rd, rd, fbits, size, is16Bit: false, context.Arm64Assembler.FcvtzsFixS); + } + } + else + { + if (unsigned) + { + InstEmitNeonCommon.EmitScalarUnaryFixedF(context, rd, rd, fbits, size, is16Bit: !sx, context.Arm64Assembler.UcvtfFixS); + } + else + { + InstEmitNeonCommon.EmitScalarUnaryFixedF(context, rd, rd, fbits, size, is16Bit: !sx, context.Arm64Assembler.ScvtfFixS); + } + } + } + + public static void VcvtrIv(CodeGenContext context, uint rd, uint rm, uint op, uint size) + { + bool unsigned = (op & 1) == 0; + + Debug.Assert(size == 1 || size == 2 || size == 3); + + bool singleRegs = size != 3; + + using ScopedRegister rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, singleRegs); + + using ScopedRegister tempRegister = InstEmitNeonCommon.PickSimdRegister(context.RegisterAllocator, rmReg); + + // Round using the FPCR rounding mode first, since the FCVTZ instructions will use the round to zero mode. + context.Arm64Assembler.FrintiFloat(tempRegister.Operand, rmReg.Operand, size ^ 2u); + + if (unsigned) + { + if (size == 1) + { + context.Arm64Assembler.FcvtzuIntSH(tempRegister.Operand, tempRegister.Operand); + } + else + { + context.Arm64Assembler.FcvtzuIntS(tempRegister.Operand, tempRegister.Operand, size & 1); + } + } + else + { + if (size == 1) + { + context.Arm64Assembler.FcvtzsIntSH(tempRegister.Operand, tempRegister.Operand); + } + else + { + context.Arm64Assembler.FcvtzsIntS(tempRegister.Operand, tempRegister.Operand, size & 1); + } + } + + InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, singleRegs); + } + + public static void Vcvtt(CodeGenContext context, uint rd, uint rm, uint sz, uint op) + { + EmitVcvtbVcvtt(context, rd, rm, sz, op, top: true); + } + + public static void EmitVcvtbVcvtt(CodeGenContext context, uint rd, uint rm, uint sz, uint op, bool top) + { + bool usesDouble = sz == 1; + bool convertFromHalf = op == 0; + + using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped(); + + if (convertFromHalf) + { + // Half to single/double. + + using ScopedRegister rmReg = InstEmitNeonCommon.Move16BitScalarToSide(context, rm, top); + + context.Arm64Assembler.FcvtFloat(tempRegister.Operand, rmReg.Operand, usesDouble ? 1u : 0u, 3u); + + InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, !usesDouble); + } + else + { + // Single/double to half. + + using ScopedRegister rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, !usesDouble); + + context.Arm64Assembler.FcvtFloat(tempRegister.Operand, rmReg.Operand, 3u, usesDouble ? 1u : 0u); + + InstEmitNeonCommon.Insert16BitResult(context, tempRegister.Operand, rd, top); + } + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpMove.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpMove.cs new file mode 100644 index 000000000..5c1eefacf --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpMove.cs @@ -0,0 +1,22 @@ +using Ryujinx.Cpu.LightningJit.CodeGen; + +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitVfpMove + { + public static void Vsel(CodeGenContext context, uint rd, uint rn, uint rm, uint cc, uint size) + { + bool singleRegs = size != 3; + uint cond = (cc << 2) | ((cc & 2) ^ ((cc << 1) & 2)); + + using ScopedRegister rnReg = InstEmitNeonCommon.MoveScalarToSide(context, rn, singleRegs); + using ScopedRegister rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, singleRegs); + + using ScopedRegister tempRegister = InstEmitNeonCommon.PickSimdRegister(context.RegisterAllocator, rnReg, rmReg); + + context.Arm64Assembler.FcselFloat(tempRegister.Operand, rnReg.Operand, cond, rmReg.Operand, size ^ 2u); + + InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, singleRegs); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpRound.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpRound.cs new file mode 100644 index 000000000..2826fa642 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpRound.cs @@ -0,0 +1,40 @@ +namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 +{ + static class InstEmitVfpRound + { + public static void Vrinta(CodeGenContext context, uint rd, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FrintaFloat); + } + + public static void Vrintm(CodeGenContext context, uint rd, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FrintmFloat); + } + + public static void Vrintn(CodeGenContext context, uint rd, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FrintnFloat); + } + + public static void Vrintp(CodeGenContext context, uint rd, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FrintpFloat); + } + + public static void Vrintr(CodeGenContext context, uint rd, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FrintiFloat); + } + + public static void Vrintx(CodeGenContext context, uint rd, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FrintxFloat); + } + + public static void Vrintz(CodeGenContext context, uint rd, uint rm, uint size) + { + InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FrintzFloat); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/A64Compiler.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/A64Compiler.cs new file mode 100644 index 000000000..b46ae3b0c --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm64/A64Compiler.cs @@ -0,0 +1,29 @@ +using ARMeilleure.Common; +using ARMeilleure.Memory; +using Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64; +using System; +using System.Runtime.InteropServices; + +namespace Ryujinx.Cpu.LightningJit.Arm64 +{ + static class A64Compiler + { + public static CompiledFunction Compile( + CpuPreset cpuPreset, + IMemoryManager memoryManager, + ulong address, + AddressTable funcTable, + IntPtr dispatchStubPtr, + Architecture targetArch) + { + if (targetArch == Architecture.Arm64) + { + return Compiler.Compile(cpuPreset, memoryManager, address, funcTable, dispatchStubPtr); + } + else + { + throw new PlatformNotSupportedException(); + } + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/Block.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/Block.cs new file mode 100644 index 000000000..188630a1c --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm64/Block.cs @@ -0,0 +1,138 @@ +using Ryujinx.Cpu.LightningJit.Graph; +using System.Collections.Generic; +using System.Diagnostics; + +namespace Ryujinx.Cpu.LightningJit.Arm64 +{ + class Block : IBlock + { + public int Index { get; private set; } + + private readonly List _predecessors; + private readonly List _successors; + + public int PredecessorsCount => _predecessors.Count; + public int SuccessorsCount => _successors.Count; + + public readonly ulong Address; + public readonly ulong EndAddress; + public readonly List Instructions; + public readonly bool EndsWithBranch; + public readonly bool IsTruncated; + public readonly bool IsLoopEnd; + + public Block(ulong address, ulong endAddress, List instructions, bool endsWithBranch, bool isTruncated, bool isLoopEnd) + { + Debug.Assert((int)((endAddress - address) / 4) == instructions.Count); + + _predecessors = new(); + _successors = new(); + Address = address; + EndAddress = endAddress; + Instructions = instructions; + EndsWithBranch = endsWithBranch; + IsTruncated = isTruncated; + IsLoopEnd = isLoopEnd; + } + + public (Block, Block) SplitAtAddress(ulong address) + { + int splitIndex = (int)((address - Address) / 4); + int splitCount = Instructions.Count - splitIndex; + + // Technically those are valid, but we don't want to create empty blocks. + Debug.Assert(splitIndex != 0); + Debug.Assert(splitCount != 0); + + Block leftBlock = new( + Address, + address, + Instructions.GetRange(0, splitIndex), + false, + false, + false); + + Block rightBlock = new( + address, + EndAddress, + Instructions.GetRange(splitIndex, splitCount), + EndsWithBranch, + IsTruncated, + IsLoopEnd); + + return (leftBlock, rightBlock); + } + + public void Number(int index) + { + Index = index; + } + + public void AddSuccessor(Block block) + { + if (!_successors.Contains(block)) + { + _successors.Add(block); + } + } + + public void AddPredecessor(Block block) + { + if (!_predecessors.Contains(block)) + { + _predecessors.Add(block); + } + } + + public IBlock GetSuccessor(int index) + { + return _successors[index]; + } + + public IBlock GetPredecessor(int index) + { + return _predecessors[index]; + } + + public RegisterUse ComputeUseMasks() + { + if (Instructions.Count == 0) + { + return new(0u, 0u, 0u, 0u, 0u, 0u); + } + + RegisterUse use = Instructions[0].RegisterUse; + + for (int index = 1; index < Instructions.Count; index++) + { + RegisterUse currentUse = Instructions[index].RegisterUse; + + use = new(use.Read | (currentUse.Read & ~use.Write), use.Write | currentUse.Write); + } + + return use; + } + + public bool EndsWithContextLoad() + { + return !IsTruncated && EndsWithContextStoreAndLoad(); + } + + public bool EndsWithContextStore() + { + return EndsWithContextStoreAndLoad(); + } + + private bool EndsWithContextStoreAndLoad() + { + if (Instructions.Count == 0) + { + return false; + } + + InstName lastInstructionName = Instructions[^1].Name; + + return lastInstructionName.IsCall() || lastInstructionName.IsException(); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/ImmUtils.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/ImmUtils.cs new file mode 100644 index 000000000..8a12756b9 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm64/ImmUtils.cs @@ -0,0 +1,20 @@ +namespace Ryujinx.Cpu.LightningJit.Arm64 +{ + static class ImmUtils + { + public static int ExtractSImm14Times4(uint encoding) + { + return ((int)(encoding >> 5) << 18) >> 16; + } + + public static int ExtractSImm19Times4(uint encoding) + { + return ((int)(encoding >> 5) << 13) >> 11; + } + + public static int ExtractSImm26Times4(uint encoding) + { + return (int)(encoding << 6) >> 4; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/InstFlags.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/InstFlags.cs new file mode 100644 index 000000000..5a6c3eb04 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm64/InstFlags.cs @@ -0,0 +1,108 @@ +using System; + +namespace Ryujinx.Cpu.LightningJit.Arm64 +{ + [Flags] + enum InstFlags + { + None = 0, + Rd = 1 << 0, + RdSP = Rd | (1 << 1), + ReadRd = 1 << 2, + Rt = 1 << 3, + RtSeq = Rt | (1 << 4), + ReadRt = 1 << 5, + Rt2 = 1 << 6, + Rn = 1 << 7, + RnSeq = Rn | (1 << 8), + RnSP = Rn | (1 << 9), + Rm = 1 << 10, + Rs = 1 << 11, + Ra = 1 << 12, + Nzcv = 1 << 13, + C = 1 << 14, + S = 1 << 15, + Qc = 1 << 16, + FpSimd = 1 << 17, + FpSimdFromGpr = FpSimd | (1 << 18), + FpSimdToGpr = FpSimd | (1 << 19), + FpSimdFromToGpr = FpSimdFromGpr | FpSimdToGpr, + Memory = 1 << 20, + MemWBack = 1 << 21, + + RdFpSimd = Rd | FpSimd, + RdReadRd = Rd | ReadRd, + RdReadRdRn = Rd | ReadRd | Rn, + RdReadRdRnFpSimd = Rd | ReadRd | Rn | FpSimd, + RdReadRdRnFpSimdFromGpr = Rd | ReadRd | Rn | FpSimdFromGpr, + RdReadRdRnQcFpSimd = Rd | ReadRd | Rn | Qc | FpSimd, + RdReadRdRnRmFpSimd = Rd | ReadRd | Rn | Rm | FpSimd, + RdReadRdRnRmQcFpSimd = Rd | ReadRd | Rn | Rm | Qc | FpSimd, + RdRn = Rd | Rn, + RdRnFpSimd = Rd | Rn | FpSimd, + RdRnFpSimdFromGpr = Rd | Rn | FpSimdFromGpr, + RdRnFpSimdToGpr = Rd | Rn | FpSimdToGpr, + RdRnQcFpSimd = Rd | Rn | Qc | FpSimd, + RdRnRm = Rd | Rn | Rm, + RdRnRmC = Rd | Rn | Rm | C, + RdRnRmCS = Rd | Rn | Rm | C | S, + RdRnRmFpSimd = Rd | Rn | Rm | FpSimd, + RdRnRmNzcv = Rd | Rn | Rm | Nzcv, + RdRnRmNzcvFpSimd = Rd | Rn | Rm | Nzcv | FpSimd, + RdRnRmQcFpSimd = Rd | Rn | Rm | Qc | FpSimd, + RdRnRmRa = Rd | Rn | Rm | Ra, + RdRnRmRaFpSimd = Rd | Rn | Rm | Ra | FpSimd, + RdRnRmS = Rd | Rn | Rm | S, + RdRnRsS = Rd | Rn | Rs | S, + RdRnS = Rd | Rn | S, + RdRnSeqRmFpSimd = Rd | RnSeq | Rm | FpSimd, + RdRnSFpSimd = Rd | Rn | S | FpSimd, + RdRnSFpSimdFromToGpr = Rd | Rn | S | FpSimdFromToGpr, + RdRnSP = Rd | RnSP, + RdRnSPRmS = Rd | RnSP | Rm | S, + RdRnSPS = Rd | RnSP | S, + RdSPRn = RdSP | Rn, + RdSPRnSP = RdSP | RnSP, + RdSPRnSPRm = RdSP | RnSP | Rm, + RnC = Rn | C, + RnNzcvS = Rn | Nzcv | S, + RnRm = Rn | Rm, + RnRmNzcvS = Rn | Rm | Nzcv | S, + RnRmNzcvSFpSimd = Rn | Rm | Nzcv | S | FpSimd, + RnRmSFpSimd = Rn | Rm | S | FpSimd, + RnSPRm = RnSP | Rm, + RtFpSimd = Rt | FpSimd, + RtReadRt = Rt | ReadRt, + RtReadRtRnSP = Rt | ReadRt | RnSP, + RtReadRtRnSPFpSimd = Rt | ReadRt | RnSP | FpSimd, + RtReadRtRnSPFpSimdMemWBack = Rt | ReadRt | RnSP | FpSimd | MemWBack, + RtReadRtRnSPMemWBack = Rt | ReadRt | RnSP | MemWBack, + RtReadRtRnSPRm = Rt | ReadRt | RnSP | Rm, + RtReadRtRnSPRmFpSimd = Rt | ReadRt | RnSP | Rm | FpSimd, + RtReadRtRnSPRmFpSimdMemWBack = Rt | ReadRt | RnSP | Rm | FpSimd | MemWBack, + RtReadRtRnSPRs = Rt | ReadRt | RnSP | Rs, + RtReadRtRnSPRsS = Rt | ReadRt | RnSP | Rs | S, + RtReadRtRt2RnSP = Rt | ReadRt | Rt2 | RnSP, + RtReadRtRt2RnSPFpSimd = Rt | ReadRt | Rt2 | RnSP | FpSimd, + RtReadRtRt2RnSPFpSimdMemWBack = Rt | ReadRt | Rt2 | RnSP | FpSimd | MemWBack, + RtReadRtRt2RnSPMemWBack = Rt | ReadRt | Rt2 | RnSP | MemWBack, + RtReadRtRt2RnSPRs = Rt | ReadRt | Rt2 | RnSP | Rs, + RtReadRtRt2RnSPS = Rt | ReadRt | Rt2 | RnSP | S, + RtRnSP = Rt | RnSP, + RtRnSPFpSimd = Rt | RnSP | FpSimd, + RtRnSPFpSimdMemWBack = Rt | RnSP | FpSimd | MemWBack, + RtRnSPMemWBack = Rt | RnSP | MemWBack, + RtRnSPRm = Rt | RnSP | Rm, + RtRnSPRmFpSimd = Rt | RnSP | Rm | FpSimd, + RtRnSPRmFpSimdMemWBack = Rt | RnSP | Rm | FpSimd | MemWBack, + RtRnSPRs = Rt | RnSP | Rs, + RtRt2RnSP = Rt | Rt2 | RnSP, + RtRt2RnSPFpSimd = Rt | Rt2 | RnSP | FpSimd, + RtRt2RnSPFpSimdMemWBack = Rt | Rt2 | RnSP | FpSimd | MemWBack, + RtRt2RnSPMemWBack = Rt | Rt2 | RnSP | MemWBack, + RtSeqReadRtRnSPFpSimd = RtSeq | ReadRt | RnSP | FpSimd, + RtSeqReadRtRnSPRmFpSimdMemWBack = RtSeq | ReadRt | RnSP | Rm | FpSimd | MemWBack, + RtSeqRnSPFpSimd = RtSeq | RnSP | FpSimd, + RtSeqRnSPRmFpSimdMemWBack = RtSeq | RnSP | Rm | FpSimd | MemWBack, + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/InstInfo.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/InstInfo.cs new file mode 100644 index 000000000..031a36577 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm64/InstInfo.cs @@ -0,0 +1,22 @@ +using Ryujinx.Cpu.LightningJit.Graph; + +namespace Ryujinx.Cpu.LightningJit.Arm64 +{ + readonly struct InstInfo + { + public readonly uint Encoding; + public readonly InstName Name; + public readonly InstFlags Flags; + public readonly AddressForm AddressForm; + public readonly RegisterUse RegisterUse; + + public InstInfo(uint encoding, InstName name, InstFlags flags, AddressForm addressForm, in RegisterUse registerUse) + { + Encoding = encoding; + Name = name; + Flags = flags; + AddressForm = addressForm; + RegisterUse = registerUse; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/InstName.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/InstName.cs new file mode 100644 index 000000000..58d78ae6e --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm64/InstName.cs @@ -0,0 +1,1134 @@ +namespace Ryujinx.Cpu.LightningJit.Arm64 +{ + enum InstName + { + Abs, + AbsAdvsimdS, + AbsAdvsimdV, + Adc, + Adcs, + AddAddsubExt, + AddAddsubImm, + AddAddsubShift, + AddAdvsimdS, + AddAdvsimdV, + Addg, + AddhnAdvsimd, + AddpAdvsimdPair, + AddpAdvsimdVec, + AddsAddsubExt, + AddsAddsubImm, + AddsAddsubShift, + AddvAdvsimd, + Adr, + Adrp, + AesdAdvsimd, + AeseAdvsimd, + AesimcAdvsimd, + AesmcAdvsimd, + AndAdvsimd, + AndLogImm, + AndLogShift, + AndsLogImm, + AndsLogShift, + Asrv, + Autda, + Autdb, + AutiaGeneral, + AutiaSystem, + AutibGeneral, + AutibSystem, + Axflag, + BcaxAdvsimd, + BcCond, + BCond, + BfcvtFloat, + BfcvtnAdvsimd, + BfdotAdvsimdElt, + BfdotAdvsimdVec, + Bfm, + BfmlalAdvsimdElt, + BfmlalAdvsimdVec, + BfmmlaAdvsimd, + BicAdvsimdImm, + BicAdvsimdReg, + BicLogShift, + Bics, + BifAdvsimd, + BitAdvsimd, + Bl, + Blr, + Blra, + Br, + Bra, + Brk, + BslAdvsimd, + Bti, + BUncond, + Cas, + Casb, + Cash, + Casp, + Cbnz, + Cbz, + CcmnImm, + CcmnReg, + CcmpImm, + CcmpReg, + Cfinv, + Chkfeat, + Clrbhb, + Clrex, + ClsAdvsimd, + ClsInt, + ClzAdvsimd, + ClzInt, + CmeqAdvsimdRegS, + CmeqAdvsimdRegV, + CmeqAdvsimdZeroS, + CmeqAdvsimdZeroV, + CmgeAdvsimdRegS, + CmgeAdvsimdRegV, + CmgeAdvsimdZeroS, + CmgeAdvsimdZeroV, + CmgtAdvsimdRegS, + CmgtAdvsimdRegV, + CmgtAdvsimdZeroS, + CmgtAdvsimdZeroV, + CmhiAdvsimdS, + CmhiAdvsimdV, + CmhsAdvsimdS, + CmhsAdvsimdV, + CmleAdvsimdS, + CmleAdvsimdV, + CmltAdvsimdS, + CmltAdvsimdV, + CmtstAdvsimdS, + CmtstAdvsimdV, + Cnt, + CntAdvsimd, + Cpyfp, + Cpyfpn, + Cpyfprn, + Cpyfprt, + Cpyfprtn, + Cpyfprtrn, + Cpyfprtwn, + Cpyfpt, + Cpyfptn, + Cpyfptrn, + Cpyfptwn, + Cpyfpwn, + Cpyfpwt, + Cpyfpwtn, + Cpyfpwtrn, + Cpyfpwtwn, + Cpyp, + Cpypn, + Cpyprn, + Cpyprt, + Cpyprtn, + Cpyprtrn, + Cpyprtwn, + Cpypt, + Cpyptn, + Cpyptrn, + Cpyptwn, + Cpypwn, + Cpypwt, + Cpypwtn, + Cpypwtrn, + Cpypwtwn, + Crc32, + Crc32c, + Csdb, + Csel, + Csinc, + Csinv, + Csneg, + Ctz, + Dcps1, + Dcps2, + Dcps3, + Dgh, + Dmb, + Drps, + DsbDsbMemory, + DsbDsbNxs, + DupAdvsimdEltScalarFromElement, + DupAdvsimdEltVectorFromElement, + DupAdvsimdGen, + Eon, + Eor3Advsimd, + EorAdvsimd, + EorLogImm, + EorLogShift, + Eret, + Ereta, + Esb, + ExtAdvsimd, + Extr, + FabdAdvsimdS, + FabdAdvsimdSH, + FabdAdvsimdV, + FabdAdvsimdVH, + FabsAdvsimdHalf, + FabsAdvsimdSingleAndDouble, + FabsFloat, + FacgeAdvsimdS, + FacgeAdvsimdSH, + FacgeAdvsimdV, + FacgeAdvsimdVH, + FacgtAdvsimdS, + FacgtAdvsimdSH, + FacgtAdvsimdV, + FacgtAdvsimdVH, + FaddAdvsimdHalf, + FaddAdvsimdSingleAndDouble, + FaddFloat, + FaddpAdvsimdPairHalf, + FaddpAdvsimdPairSingleAndDouble, + FaddpAdvsimdVecHalf, + FaddpAdvsimdVecSingleAndDouble, + FcaddAdvsimdVec, + FccmpeFloat, + FccmpFloat, + FcmeqAdvsimdRegS, + FcmeqAdvsimdRegSH, + FcmeqAdvsimdRegV, + FcmeqAdvsimdRegVH, + FcmeqAdvsimdZeroS, + FcmeqAdvsimdZeroSH, + FcmeqAdvsimdZeroV, + FcmeqAdvsimdZeroVH, + FcmgeAdvsimdRegS, + FcmgeAdvsimdRegSH, + FcmgeAdvsimdRegV, + FcmgeAdvsimdRegVH, + FcmgeAdvsimdZeroS, + FcmgeAdvsimdZeroSH, + FcmgeAdvsimdZeroV, + FcmgeAdvsimdZeroVH, + FcmgtAdvsimdRegS, + FcmgtAdvsimdRegSH, + FcmgtAdvsimdRegV, + FcmgtAdvsimdRegVH, + FcmgtAdvsimdZeroS, + FcmgtAdvsimdZeroSH, + FcmgtAdvsimdZeroV, + FcmgtAdvsimdZeroVH, + FcmlaAdvsimdElt, + FcmlaAdvsimdVec, + FcmleAdvsimdS, + FcmleAdvsimdSH, + FcmleAdvsimdV, + FcmleAdvsimdVH, + FcmltAdvsimdS, + FcmltAdvsimdSH, + FcmltAdvsimdV, + FcmltAdvsimdVH, + FcmpeFloat, + FcmpFloat, + FcselFloat, + FcvtasAdvsimdS, + FcvtasAdvsimdSH, + FcvtasAdvsimdV, + FcvtasAdvsimdVH, + FcvtasFloat, + FcvtauAdvsimdS, + FcvtauAdvsimdSH, + FcvtauAdvsimdV, + FcvtauAdvsimdVH, + FcvtauFloat, + FcvtFloat, + FcvtlAdvsimd, + FcvtmsAdvsimdS, + FcvtmsAdvsimdSH, + FcvtmsAdvsimdV, + FcvtmsAdvsimdVH, + FcvtmsFloat, + FcvtmuAdvsimdS, + FcvtmuAdvsimdSH, + FcvtmuAdvsimdV, + FcvtmuAdvsimdVH, + FcvtmuFloat, + FcvtnAdvsimd, + FcvtnsAdvsimdS, + FcvtnsAdvsimdSH, + FcvtnsAdvsimdV, + FcvtnsAdvsimdVH, + FcvtnsFloat, + FcvtnuAdvsimdS, + FcvtnuAdvsimdSH, + FcvtnuAdvsimdV, + FcvtnuAdvsimdVH, + FcvtnuFloat, + FcvtpsAdvsimdS, + FcvtpsAdvsimdSH, + FcvtpsAdvsimdV, + FcvtpsAdvsimdVH, + FcvtpsFloat, + FcvtpuAdvsimdS, + FcvtpuAdvsimdSH, + FcvtpuAdvsimdV, + FcvtpuAdvsimdVH, + FcvtpuFloat, + FcvtxnAdvsimdS, + FcvtxnAdvsimdV, + FcvtzsAdvsimdFixS, + FcvtzsAdvsimdFixV, + FcvtzsAdvsimdIntS, + FcvtzsAdvsimdIntSH, + FcvtzsAdvsimdIntV, + FcvtzsAdvsimdIntVH, + FcvtzsFloatFix, + FcvtzsFloatInt, + FcvtzuAdvsimdFixS, + FcvtzuAdvsimdFixV, + FcvtzuAdvsimdIntS, + FcvtzuAdvsimdIntSH, + FcvtzuAdvsimdIntV, + FcvtzuAdvsimdIntVH, + FcvtzuFloatFix, + FcvtzuFloatInt, + FdivAdvsimdHalf, + FdivAdvsimdSingleAndDouble, + FdivFloat, + Fjcvtzs, + FmaddFloat, + FmaxAdvsimdHalf, + FmaxAdvsimdSingleAndDouble, + FmaxFloat, + FmaxnmAdvsimdHalf, + FmaxnmAdvsimdSingleAndDouble, + FmaxnmFloat, + FmaxnmpAdvsimdPairHalf, + FmaxnmpAdvsimdPairSingleAndDouble, + FmaxnmpAdvsimdVecHalf, + FmaxnmpAdvsimdVecSingleAndDouble, + FmaxnmvAdvsimdHalf, + FmaxnmvAdvsimdSingleAndDouble, + FmaxpAdvsimdPairHalf, + FmaxpAdvsimdPairSingleAndDouble, + FmaxpAdvsimdVecHalf, + FmaxpAdvsimdVecSingleAndDouble, + FmaxvAdvsimdHalf, + FmaxvAdvsimdSingleAndDouble, + FminAdvsimdHalf, + FminAdvsimdSingleAndDouble, + FminFloat, + FminnmAdvsimdHalf, + FminnmAdvsimdSingleAndDouble, + FminnmFloat, + FminnmpAdvsimdPairHalf, + FminnmpAdvsimdPairSingleAndDouble, + FminnmpAdvsimdVecHalf, + FminnmpAdvsimdVecSingleAndDouble, + FminnmvAdvsimdHalf, + FminnmvAdvsimdSingleAndDouble, + FminpAdvsimdPairHalf, + FminpAdvsimdPairSingleAndDouble, + FminpAdvsimdVecHalf, + FminpAdvsimdVecSingleAndDouble, + FminvAdvsimdHalf, + FminvAdvsimdSingleAndDouble, + FmlaAdvsimdElt2regElementHalf, + FmlaAdvsimdElt2regElementSingleAndDouble, + FmlaAdvsimdElt2regScalarHalf, + FmlaAdvsimdElt2regScalarSingleAndDouble, + FmlaAdvsimdVecHalf, + FmlaAdvsimdVecSingleAndDouble, + FmlalAdvsimdEltFmlal, + FmlalAdvsimdEltFmlal2, + FmlalAdvsimdVecFmlal, + FmlalAdvsimdVecFmlal2, + FmlsAdvsimdElt2regElementHalf, + FmlsAdvsimdElt2regElementSingleAndDouble, + FmlsAdvsimdElt2regScalarHalf, + FmlsAdvsimdElt2regScalarSingleAndDouble, + FmlsAdvsimdVecHalf, + FmlsAdvsimdVecSingleAndDouble, + FmlslAdvsimdEltFmlsl, + FmlslAdvsimdEltFmlsl2, + FmlslAdvsimdVecFmlsl, + FmlslAdvsimdVecFmlsl2, + FmovAdvsimdPerHalf, + FmovAdvsimdSingleAndDouble, + FmovFloat, + FmovFloatGen, + FmovFloatImm, + FmsubFloat, + FmulAdvsimdElt2regElementHalf, + FmulAdvsimdElt2regElementSingleAndDouble, + FmulAdvsimdElt2regScalarHalf, + FmulAdvsimdElt2regScalarSingleAndDouble, + FmulAdvsimdVecHalf, + FmulAdvsimdVecSingleAndDouble, + FmulFloat, + FmulxAdvsimdElt2regElementHalf, + FmulxAdvsimdElt2regElementSingleAndDouble, + FmulxAdvsimdElt2regScalarHalf, + FmulxAdvsimdElt2regScalarSingleAndDouble, + FmulxAdvsimdVecS, + FmulxAdvsimdVecSH, + FmulxAdvsimdVecV, + FmulxAdvsimdVecVH, + FnegAdvsimdHalf, + FnegAdvsimdSingleAndDouble, + FnegFloat, + FnmaddFloat, + FnmsubFloat, + FnmulFloat, + FrecpeAdvsimdS, + FrecpeAdvsimdSH, + FrecpeAdvsimdV, + FrecpeAdvsimdVH, + FrecpsAdvsimdS, + FrecpsAdvsimdSH, + FrecpsAdvsimdV, + FrecpsAdvsimdVH, + FrecpxAdvsimdHalf, + FrecpxAdvsimdSingleAndDouble, + Frint32xAdvsimd, + Frint32xFloat, + Frint32zAdvsimd, + Frint32zFloat, + Frint64xAdvsimd, + Frint64xFloat, + Frint64zAdvsimd, + Frint64zFloat, + FrintaAdvsimdHalf, + FrintaAdvsimdSingleAndDouble, + FrintaFloat, + FrintiAdvsimdHalf, + FrintiAdvsimdSingleAndDouble, + FrintiFloat, + FrintmAdvsimdHalf, + FrintmAdvsimdSingleAndDouble, + FrintmFloat, + FrintnAdvsimdHalf, + FrintnAdvsimdSingleAndDouble, + FrintnFloat, + FrintpAdvsimdHalf, + FrintpAdvsimdSingleAndDouble, + FrintpFloat, + FrintxAdvsimdHalf, + FrintxAdvsimdSingleAndDouble, + FrintxFloat, + FrintzAdvsimdHalf, + FrintzAdvsimdSingleAndDouble, + FrintzFloat, + FrsqrteAdvsimdS, + FrsqrteAdvsimdSH, + FrsqrteAdvsimdV, + FrsqrteAdvsimdVH, + FrsqrtsAdvsimdS, + FrsqrtsAdvsimdSH, + FrsqrtsAdvsimdV, + FrsqrtsAdvsimdVH, + FsqrtAdvsimdHalf, + FsqrtAdvsimdSingleAndDouble, + FsqrtFloat, + FsubAdvsimdHalf, + FsubAdvsimdSingleAndDouble, + FsubFloat, + Gcsb, + Gcsstr, + Gcssttr, + Gmi, + Hint, + Hlt, + Hvc, + InsAdvsimdElt, + InsAdvsimdGen, + Irg, + Isb, + Ld1AdvsimdMultAsNoPostIndex, + Ld1AdvsimdMultAsPostIndex, + Ld1AdvsimdSnglAsNoPostIndex, + Ld1AdvsimdSnglAsPostIndex, + Ld1rAdvsimdAsNoPostIndex, + Ld1rAdvsimdAsPostIndex, + Ld2AdvsimdMultAsNoPostIndex, + Ld2AdvsimdMultAsPostIndex, + Ld2AdvsimdSnglAsNoPostIndex, + Ld2AdvsimdSnglAsPostIndex, + Ld2rAdvsimdAsNoPostIndex, + Ld2rAdvsimdAsPostIndex, + Ld3AdvsimdMultAsNoPostIndex, + Ld3AdvsimdMultAsPostIndex, + Ld3AdvsimdSnglAsNoPostIndex, + Ld3AdvsimdSnglAsPostIndex, + Ld3rAdvsimdAsNoPostIndex, + Ld3rAdvsimdAsPostIndex, + Ld4AdvsimdMultAsNoPostIndex, + Ld4AdvsimdMultAsPostIndex, + Ld4AdvsimdSnglAsNoPostIndex, + Ld4AdvsimdSnglAsPostIndex, + Ld4rAdvsimdAsNoPostIndex, + Ld4rAdvsimdAsPostIndex, + Ld64b, + Ldadd, + Ldaddb, + Ldaddh, + Ldap1AdvsimdSngl, + Ldaprb, + LdaprBaseRegister, + Ldaprh, + LdaprPostIndexed, + Ldapurb, + LdapurFpsimd, + LdapurGen, + Ldapurh, + Ldapursb, + Ldapursh, + Ldapursw, + Ldar, + Ldarb, + Ldarh, + Ldaxp, + Ldaxr, + Ldaxrb, + Ldaxrh, + Ldclr, + Ldclrb, + Ldclrh, + Ldclrp, + Ldeor, + Ldeorb, + Ldeorh, + Ldg, + Ldgm, + Ldiapp, + Ldlar, + Ldlarb, + Ldlarh, + LdnpFpsimd, + LdnpGen, + LdpFpsimdPostIndexed, + LdpFpsimdPreIndexed, + LdpFpsimdSignedScaledOffset, + LdpGenPostIndexed, + LdpGenPreIndexed, + LdpGenSignedScaledOffset, + LdpswPostIndexed, + LdpswPreIndexed, + LdpswSignedScaledOffset, + Ldra, + LdrbImmPostIndexed, + LdrbImmPreIndexed, + LdrbImmUnsignedScaledOffset, + LdrbReg, + LdrhImmPostIndexed, + LdrhImmPreIndexed, + LdrhImmUnsignedScaledOffset, + LdrhReg, + LdrImmFpsimdPostIndexed, + LdrImmFpsimdPreIndexed, + LdrImmFpsimdUnsignedScaledOffset, + LdrImmGenPostIndexed, + LdrImmGenPreIndexed, + LdrImmGenUnsignedScaledOffset, + LdrLitFpsimd, + LdrLitGen, + LdrRegFpsimd, + LdrRegGen, + LdrsbImmPostIndexed, + LdrsbImmPreIndexed, + LdrsbImmUnsignedScaledOffset, + LdrsbReg, + LdrshImmPostIndexed, + LdrshImmPreIndexed, + LdrshImmUnsignedScaledOffset, + LdrshReg, + LdrswImmPostIndexed, + LdrswImmPreIndexed, + LdrswImmUnsignedScaledOffset, + LdrswLit, + LdrswReg, + Ldset, + Ldsetb, + Ldseth, + Ldsetp, + Ldsmax, + Ldsmaxb, + Ldsmaxh, + Ldsmin, + Ldsminb, + Ldsminh, + Ldtr, + Ldtrb, + Ldtrh, + Ldtrsb, + Ldtrsh, + Ldtrsw, + Ldumax, + Ldumaxb, + Ldumaxh, + Ldumin, + Lduminb, + Lduminh, + Ldurb, + LdurFpsimd, + LdurGen, + Ldurh, + Ldursb, + Ldursh, + Ldursw, + Ldxp, + Ldxr, + Ldxrb, + Ldxrh, + Lslv, + Lsrv, + Madd, + MlaAdvsimdElt, + MlaAdvsimdVec, + MlsAdvsimdElt, + MlsAdvsimdVec, + MoviAdvsimd, + Movk, + Movn, + Movz, + Mrrs, + Mrs, + MsrImm, + Msrr, + MsrReg, + Msub, + MulAdvsimdElt, + MulAdvsimdVec, + MvniAdvsimd, + NegAdvsimdS, + NegAdvsimdV, + Nop, + NotAdvsimd, + OrnAdvsimd, + OrnLogShift, + OrrAdvsimdImm, + OrrAdvsimdReg, + OrrLogImm, + OrrLogShift, + Pacda, + Pacdb, + Pacga, + PaciaGeneral, + PaciaSystem, + PacibGeneral, + PacibSystem, + PmulAdvsimd, + PmullAdvsimd, + PrfmImm, + PrfmLit, + PrfmReg, + Prfum, + Psb, + RaddhnAdvsimd, + Rax1Advsimd, + RbitAdvsimd, + RbitInt, + Rcwcas, + Rcwcasp, + Rcwclr, + Rcwclrp, + Rcwscas, + Rcwscasp, + Rcwsclr, + Rcwsclrp, + Rcwset, + Rcwsetp, + Rcwsset, + Rcwssetp, + Rcwsswp, + Rcwsswpp, + Rcwswp, + Rcwswpp, + Ret, + Reta, + Rev, + Rev16Advsimd, + Rev16Int, + Rev32Advsimd, + Rev32Int, + Rev64Advsimd, + Rmif, + Rorv, + RprfmReg, + RshrnAdvsimd, + RsubhnAdvsimd, + SabaAdvsimd, + SabalAdvsimd, + SabdAdvsimd, + SabdlAdvsimd, + SadalpAdvsimd, + SaddlAdvsimd, + SaddlpAdvsimd, + SaddlvAdvsimd, + SaddwAdvsimd, + Sb, + Sbc, + Sbcs, + Sbfm, + ScvtfAdvsimdFixS, + ScvtfAdvsimdFixV, + ScvtfAdvsimdIntS, + ScvtfAdvsimdIntSH, + ScvtfAdvsimdIntV, + ScvtfAdvsimdIntVH, + ScvtfFloatFix, + ScvtfFloatInt, + Sdiv, + SdotAdvsimdElt, + SdotAdvsimdVec, + Setf, + Setgp, + Setgpn, + Setgpt, + Setgptn, + Setp, + Setpn, + Setpt, + Setptn, + Sev, + Sevl, + Sha1cAdvsimd, + Sha1hAdvsimd, + Sha1mAdvsimd, + Sha1pAdvsimd, + Sha1su0Advsimd, + Sha1su1Advsimd, + Sha256h2Advsimd, + Sha256hAdvsimd, + Sha256su0Advsimd, + Sha256su1Advsimd, + Sha512h2Advsimd, + Sha512hAdvsimd, + Sha512su0Advsimd, + Sha512su1Advsimd, + ShaddAdvsimd, + ShlAdvsimdS, + ShlAdvsimdV, + ShllAdvsimd, + ShrnAdvsimd, + ShsubAdvsimd, + SliAdvsimdS, + SliAdvsimdV, + Sm3partw1Advsimd, + Sm3partw2Advsimd, + Sm3ss1Advsimd, + Sm3tt1aAdvsimd, + Sm3tt1bAdvsimd, + Sm3tt2aAdvsimd, + Sm3tt2bAdvsimd, + Sm4eAdvsimd, + Sm4ekeyAdvsimd, + Smaddl, + SmaxAdvsimd, + SmaxImm, + SmaxpAdvsimd, + SmaxReg, + SmaxvAdvsimd, + Smc, + SminAdvsimd, + SminImm, + SminpAdvsimd, + SminReg, + SminvAdvsimd, + SmlalAdvsimdElt, + SmlalAdvsimdVec, + SmlslAdvsimdElt, + SmlslAdvsimdVec, + SmmlaAdvsimdVec, + SmovAdvsimd, + Smsubl, + Smulh, + SmullAdvsimdElt, + SmullAdvsimdVec, + SqabsAdvsimdS, + SqabsAdvsimdV, + SqaddAdvsimdS, + SqaddAdvsimdV, + SqdmlalAdvsimdElt2regElement, + SqdmlalAdvsimdElt2regScalar, + SqdmlalAdvsimdVecS, + SqdmlalAdvsimdVecV, + SqdmlslAdvsimdElt2regElement, + SqdmlslAdvsimdElt2regScalar, + SqdmlslAdvsimdVecS, + SqdmlslAdvsimdVecV, + SqdmulhAdvsimdElt2regElement, + SqdmulhAdvsimdElt2regScalar, + SqdmulhAdvsimdVecS, + SqdmulhAdvsimdVecV, + SqdmullAdvsimdElt2regElement, + SqdmullAdvsimdElt2regScalar, + SqdmullAdvsimdVecS, + SqdmullAdvsimdVecV, + SqnegAdvsimdS, + SqnegAdvsimdV, + SqrdmlahAdvsimdElt2regElement, + SqrdmlahAdvsimdElt2regScalar, + SqrdmlahAdvsimdVecS, + SqrdmlahAdvsimdVecV, + SqrdmlshAdvsimdElt2regElement, + SqrdmlshAdvsimdElt2regScalar, + SqrdmlshAdvsimdVecS, + SqrdmlshAdvsimdVecV, + SqrdmulhAdvsimdElt2regElement, + SqrdmulhAdvsimdElt2regScalar, + SqrdmulhAdvsimdVecS, + SqrdmulhAdvsimdVecV, + SqrshlAdvsimdS, + SqrshlAdvsimdV, + SqrshrnAdvsimdS, + SqrshrnAdvsimdV, + SqrshrunAdvsimdS, + SqrshrunAdvsimdV, + SqshlAdvsimdImmS, + SqshlAdvsimdImmV, + SqshlAdvsimdRegS, + SqshlAdvsimdRegV, + SqshluAdvsimdS, + SqshluAdvsimdV, + SqshrnAdvsimdS, + SqshrnAdvsimdV, + SqshrunAdvsimdS, + SqshrunAdvsimdV, + SqsubAdvsimdS, + SqsubAdvsimdV, + SqxtnAdvsimdS, + SqxtnAdvsimdV, + SqxtunAdvsimdS, + SqxtunAdvsimdV, + SrhaddAdvsimd, + SriAdvsimdS, + SriAdvsimdV, + SrshlAdvsimdS, + SrshlAdvsimdV, + SrshrAdvsimdS, + SrshrAdvsimdV, + SrsraAdvsimdS, + SrsraAdvsimdV, + SshlAdvsimdS, + SshlAdvsimdV, + SshllAdvsimd, + SshrAdvsimdS, + SshrAdvsimdV, + SsraAdvsimdS, + SsraAdvsimdV, + SsublAdvsimd, + SsubwAdvsimd, + St1AdvsimdMultAsNoPostIndex, + St1AdvsimdMultAsPostIndex, + St1AdvsimdSnglAsNoPostIndex, + St1AdvsimdSnglAsPostIndex, + St2AdvsimdMultAsNoPostIndex, + St2AdvsimdMultAsPostIndex, + St2AdvsimdSnglAsNoPostIndex, + St2AdvsimdSnglAsPostIndex, + St2gPostIndexed, + St2gPreIndexed, + St2gSignedScaledOffset, + St3AdvsimdMultAsNoPostIndex, + St3AdvsimdMultAsPostIndex, + St3AdvsimdSnglAsNoPostIndex, + St3AdvsimdSnglAsPostIndex, + St4AdvsimdMultAsNoPostIndex, + St4AdvsimdMultAsPostIndex, + St4AdvsimdSnglAsNoPostIndex, + St4AdvsimdSnglAsPostIndex, + St64b, + St64bv, + St64bv0, + Stgm, + StgPostIndexed, + StgpPostIndexed, + StgpPreIndexed, + StgPreIndexed, + StgpSignedScaledOffset, + StgSignedScaledOffset, + Stilp, + Stl1AdvsimdSngl, + Stllr, + Stllrb, + Stllrh, + Stlrb, + StlrBaseRegister, + Stlrh, + StlrPreIndexed, + Stlurb, + StlurFpsimd, + StlurGen, + Stlurh, + Stlxp, + Stlxr, + Stlxrb, + Stlxrh, + StnpFpsimd, + StnpGen, + StpFpsimdPostIndexed, + StpFpsimdPreIndexed, + StpFpsimdSignedScaledOffset, + StpGenPostIndexed, + StpGenPreIndexed, + StpGenSignedScaledOffset, + StrbImmPostIndexed, + StrbImmPreIndexed, + StrbImmUnsignedScaledOffset, + StrbReg, + StrhImmPostIndexed, + StrhImmPreIndexed, + StrhImmUnsignedScaledOffset, + StrhReg, + StrImmFpsimdPostIndexed, + StrImmFpsimdPreIndexed, + StrImmFpsimdUnsignedScaledOffset, + StrImmGenPostIndexed, + StrImmGenPreIndexed, + StrImmGenUnsignedScaledOffset, + StrRegFpsimd, + StrRegGen, + Sttr, + Sttrb, + Sttrh, + Sturb, + SturFpsimd, + SturGen, + Sturh, + Stxp, + Stxr, + Stxrb, + Stxrh, + Stz2gPostIndexed, + Stz2gPreIndexed, + Stz2gSignedScaledOffset, + Stzgm, + StzgPostIndexed, + StzgPreIndexed, + StzgSignedScaledOffset, + SubAddsubExt, + SubAddsubImm, + SubAddsubShift, + SubAdvsimdS, + SubAdvsimdV, + Subg, + SubhnAdvsimd, + Subp, + Subps, + SubsAddsubExt, + SubsAddsubImm, + SubsAddsubShift, + SudotAdvsimdElt, + SuqaddAdvsimdS, + SuqaddAdvsimdV, + Svc, + Swp, + Swpb, + Swph, + Swpp, + Sys, + Sysl, + Sysp, + TblAdvsimd, + Tbnz, + TbxAdvsimd, + Tbz, + Tcancel, + Tcommit, + Trn1Advsimd, + Trn2Advsimd, + Tsb, + Tstart, + Ttest, + UabaAdvsimd, + UabalAdvsimd, + UabdAdvsimd, + UabdlAdvsimd, + UadalpAdvsimd, + UaddlAdvsimd, + UaddlpAdvsimd, + UaddlvAdvsimd, + UaddwAdvsimd, + Ubfm, + UcvtfAdvsimdFixS, + UcvtfAdvsimdFixV, + UcvtfAdvsimdIntS, + UcvtfAdvsimdIntSH, + UcvtfAdvsimdIntV, + UcvtfAdvsimdIntVH, + UcvtfFloatFix, + UcvtfFloatInt, + UdfPermUndef, + Udiv, + UdotAdvsimdElt, + UdotAdvsimdVec, + UhaddAdvsimd, + UhsubAdvsimd, + Umaddl, + UmaxAdvsimd, + UmaxImm, + UmaxpAdvsimd, + UmaxReg, + UmaxvAdvsimd, + UminAdvsimd, + UminImm, + UminpAdvsimd, + UminReg, + UminvAdvsimd, + UmlalAdvsimdElt, + UmlalAdvsimdVec, + UmlslAdvsimdElt, + UmlslAdvsimdVec, + UmmlaAdvsimdVec, + UmovAdvsimd, + Umsubl, + Umulh, + UmullAdvsimdElt, + UmullAdvsimdVec, + UqaddAdvsimdS, + UqaddAdvsimdV, + UqrshlAdvsimdS, + UqrshlAdvsimdV, + UqrshrnAdvsimdS, + UqrshrnAdvsimdV, + UqshlAdvsimdImmS, + UqshlAdvsimdImmV, + UqshlAdvsimdRegS, + UqshlAdvsimdRegV, + UqshrnAdvsimdS, + UqshrnAdvsimdV, + UqsubAdvsimdS, + UqsubAdvsimdV, + UqxtnAdvsimdS, + UqxtnAdvsimdV, + UrecpeAdvsimd, + UrhaddAdvsimd, + UrshlAdvsimdS, + UrshlAdvsimdV, + UrshrAdvsimdS, + UrshrAdvsimdV, + UrsqrteAdvsimd, + UrsraAdvsimdS, + UrsraAdvsimdV, + UsdotAdvsimdElt, + UsdotAdvsimdVec, + UshlAdvsimdS, + UshlAdvsimdV, + UshllAdvsimd, + UshrAdvsimdS, + UshrAdvsimdV, + UsmmlaAdvsimdVec, + UsqaddAdvsimdS, + UsqaddAdvsimdV, + UsraAdvsimdS, + UsraAdvsimdV, + UsublAdvsimd, + UsubwAdvsimd, + Uzp1Advsimd, + Uzp2Advsimd, + Wfe, + Wfet, + Wfi, + Wfit, + Xaflag, + XarAdvsimd, + XpacGeneral, + XpacSystem, + XtnAdvsimd, + Yield, + Zip1Advsimd, + Zip2Advsimd, + } + + static class InstNameExtensions + { + public static bool IsCall(this InstName name) + { + return name == InstName.Bl || name == InstName.Blr; + } + + public static bool IsControlFlowOrException(this InstName name) + { + switch (name) + { + case InstName.BUncond: + case InstName.BCond: + case InstName.Bl: + case InstName.Blr: + case InstName.Br: + case InstName.Brk: + case InstName.Cbnz: + case InstName.Cbz: + case InstName.Ret: + case InstName.Tbnz: + case InstName.Tbz: + case InstName.Svc: + case InstName.UdfPermUndef: + return true; + } + + return false; + } + + public static bool IsException(this InstName name) + { + switch (name) + { + case InstName.Brk: + case InstName.Svc: + case InstName.UdfPermUndef: + return true; + } + + return false; + } + + public static bool IsSystem(this InstName name) + { + switch (name) + { + case InstName.Mrs: + case InstName.MsrImm: + case InstName.MsrReg: + return true; + } + + return name.IsException(); + } + + public static bool IsSystemOrCall(this InstName name) + { + switch (name) + { + case InstName.Bl: + case InstName.Blr: + case InstName.Svc: + case InstName.Mrs: + case InstName.MsrImm: + case InstName.MsrReg: + return true; + } + + return false; + } + + public static bool IsPrivileged(this InstName name) + { + switch (name) + { + case InstName.Dcps1: + case InstName.Dcps2: + case InstName.Dcps3: + case InstName.Drps: + case InstName.Eret: + case InstName.Ereta: + case InstName.Hvc: + case InstName.MsrImm: + case InstName.Smc: + return true; + } + + return false; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/MultiBlock.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/MultiBlock.cs new file mode 100644 index 000000000..8ac65059a --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm64/MultiBlock.cs @@ -0,0 +1,64 @@ +using Ryujinx.Cpu.LightningJit.Graph; +using System; +using System.Collections.Generic; + +namespace Ryujinx.Cpu.LightningJit.Arm64 +{ + class MultiBlock : IBlockList + { + public readonly List Blocks; + public readonly RegisterMask[] ReadMasks; + public readonly RegisterMask[] WriteMasks; + public readonly RegisterMask GlobalUseMask; + public readonly bool HasHostCall; + public readonly bool HasMemoryInstruction; + public readonly bool IsTruncated; + + public int Count => Blocks.Count; + + public IBlock this[int index] => Blocks[index]; + + public MultiBlock(List blocks, RegisterMask globalUseMask, bool hasHostCall, bool hasMemoryInstruction) + { + Blocks = blocks; + + (ReadMasks, WriteMasks) = DataFlow.GetGlobalUses(this); + + GlobalUseMask = globalUseMask; + HasHostCall = hasHostCall; + HasMemoryInstruction = hasMemoryInstruction; + IsTruncated = blocks[^1].IsTruncated; + } + + public void PrintDebugInfo() + { + foreach (Block block in Blocks) + { + Console.WriteLine($"bb {block.Index}"); + + List predList = new(); + List succList = new(); + + for (int index = 0; index < block.PredecessorsCount; index++) + { + predList.Add(block.GetPredecessor(index).Index); + } + + for (int index = 0; index < block.SuccessorsCount; index++) + { + succList.Add(block.GetSuccessor(index).Index); + } + + Console.WriteLine($" predecessors: {string.Join(' ', predList)}"); + Console.WriteLine($" successors: {string.Join(' ', succList)}"); + Console.WriteLine($" gpr read mask: 0x{ReadMasks[block.Index].GprMask:X} 0x{block.ComputeUseMasks().Read.GprMask:X}"); + Console.WriteLine($" gpr write mask: 0x{WriteMasks[block.Index].GprMask:X}"); + + for (int index = 0; index < block.Instructions.Count; index++) + { + Console.WriteLine($" {index} 0x{block.Instructions[index].Encoding:X8} {block.Instructions[index].Name}"); + } + } + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/RegisterAllocator.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/RegisterAllocator.cs new file mode 100644 index 000000000..c9a932093 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm64/RegisterAllocator.cs @@ -0,0 +1,154 @@ +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; +using System; +using System.Diagnostics; +using System.Numerics; + +namespace Ryujinx.Cpu.LightningJit.Arm64 +{ + class RegisterAllocator + { + public const int MaxTemps = 1; + public const int MaxTempsInclFixed = MaxTemps + 2; + + private uint _gprMask; + private readonly uint _fpSimdMask; + private readonly uint _pStateMask; + + private uint _tempGprsMask; + + private readonly int[] _registerMap; + + public int FixedContextRegister { get; } + public int FixedPageTableRegister { get; } + + public uint AllGprMask => (_gprMask & ~RegisterUtils.ReservedRegsMask) | _tempGprsMask; + public uint AllFpSimdMask => _fpSimdMask; + public uint AllPStateMask => _pStateMask; + + public RegisterAllocator(uint gprMask, uint fpSimdMask, uint pStateMask, bool hasHostCall) + { + _gprMask = gprMask; + _fpSimdMask = fpSimdMask; + _pStateMask = pStateMask; + + if (hasHostCall) + { + // If the function has calls, we can avoid the need to spill those registers across + // calls by puting them on callee saved registers. + + FixedContextRegister = AllocateAndMarkTempGprRegisterWithPreferencing(); + FixedPageTableRegister = AllocateAndMarkTempGprRegisterWithPreferencing(); + } + else + { + FixedContextRegister = AllocateAndMarkTempGprRegister(); + FixedPageTableRegister = AllocateAndMarkTempGprRegister(); + } + + _tempGprsMask = (1u << FixedContextRegister) | (1u << FixedPageTableRegister); + + _registerMap = new int[32]; + + for (int index = 0; index < _registerMap.Length; index++) + { + _registerMap[index] = index; + } + + BuildRegisterMap(_registerMap); + + Span tempRegisters = stackalloc int[MaxTemps]; + + for (int index = 0; index < tempRegisters.Length; index++) + { + tempRegisters[index] = AllocateAndMarkTempGprRegister(); + } + + for (int index = 0; index < tempRegisters.Length; index++) + { + FreeTempGprRegister(tempRegisters[index]); + } + } + + private void BuildRegisterMap(Span map) + { + uint mask = _gprMask & RegisterUtils.ReservedRegsMask; + + while (mask != 0) + { + int index = BitOperations.TrailingZeroCount(mask); + int remapIndex = AllocateAndMarkTempGprRegister(); + + map[index] = remapIndex; + _tempGprsMask |= 1u << remapIndex; + + mask &= ~(1u << index); + } + } + + public int RemapReservedGprRegister(int index) + { + return _registerMap[index]; + } + + private int AllocateAndMarkTempGprRegister() + { + int index = AllocateTempGprRegister(); + _tempGprsMask |= 1u << index; + + return index; + } + + private int AllocateAndMarkTempGprRegisterWithPreferencing() + { + int index = AllocateTempRegisterWithPreferencing(); + _tempGprsMask |= 1u << index; + + return index; + } + + public int AllocateTempGprRegister() + { + return AllocateTempRegister(ref _gprMask); + } + + public void FreeTempGprRegister(int index) + { + FreeTempRegister(ref _gprMask, index); + } + + private int AllocateTempRegisterWithPreferencing() + { + int firstCalleeSaved = BitOperations.TrailingZeroCount(~_gprMask & AbiConstants.GprCalleeSavedRegsMask); + if (firstCalleeSaved < 32) + { + uint regMask = 1u << firstCalleeSaved; + if ((regMask & RegisterUtils.ReservedRegsMask) == 0) + { + _gprMask |= regMask; + + return firstCalleeSaved; + } + } + + return AllocateTempRegister(ref _gprMask); + } + + private static int AllocateTempRegister(ref uint mask) + { + int index = BitOperations.TrailingZeroCount(~(mask | RegisterUtils.ReservedRegsMask)); + if (index == sizeof(uint) * 8) + { + throw new InvalidOperationException("No free registers."); + } + + mask |= 1u << index; + + return index; + } + + private static void FreeTempRegister(ref uint mask, int index) + { + mask &= ~(1u << index); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/RegisterUtils.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/RegisterUtils.cs new file mode 100644 index 000000000..eb3fc229f --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm64/RegisterUtils.cs @@ -0,0 +1,495 @@ +using System.Diagnostics; + +namespace Ryujinx.Cpu.LightningJit.Arm64 +{ + static class RegisterUtils + { + private const int RdRtBit = 0; + private const int RnBit = 5; + private const int RmRsBit = 16; + private const int RaRt2Bit = 10; + + // Some of those register have specific roles and can't be used as general purpose registers. + // X18 - Reserved for platform specific usage. + // X29 - Frame pointer. + // X30 - Return address. + // X31 - Not an actual register, in some cases maps to SP, and in others to ZR. + public const uint ReservedRegsMask = (1u << 18) | (1u << 29) | (1u << 30) | (1u << 31); + + public const int LrIndex = 30; + public const int SpIndex = 31; + public const int ZrIndex = 31; + public const int SpecialZrIndex = 32; + + public static uint RemapRegisters(RegisterAllocator regAlloc, InstFlags flags, uint encoding) + { + if (flags.HasFlag(InstFlags.Rd) && (!flags.HasFlag(InstFlags.FpSimd) || IsFpToGpr(flags, encoding))) + { + encoding = ReplaceGprRegister(regAlloc, encoding, RdRtBit, flags.HasFlag(InstFlags.RdSP)); + } + + if (flags.HasFlag(InstFlags.Rn) && (!flags.HasFlag(InstFlags.FpSimd) || IsFpFromGpr(flags, encoding) || flags.HasFlag(InstFlags.Memory))) + { + encoding = ReplaceGprRegister(regAlloc, encoding, RnBit, flags.HasFlag(InstFlags.RnSP)); + } + + if (!flags.HasFlag(InstFlags.FpSimd)) + { + if (flags.HasFlag(InstFlags.Rm) || flags.HasFlag(InstFlags.Rs)) + { + encoding = ReplaceGprRegister(regAlloc, encoding, RmRsBit); + } + + if (flags.HasFlag(InstFlags.Ra) || flags.HasFlag(InstFlags.Rt2)) + { + encoding = ReplaceGprRegister(regAlloc, encoding, RaRt2Bit); + } + + if (flags.HasFlag(InstFlags.Rt)) + { + encoding = ReplaceGprRegister(regAlloc, encoding, RdRtBit); + } + } + else if (flags.HasFlag(InstFlags.Rm) && flags.HasFlag(InstFlags.Memory)) + { + encoding = ReplaceGprRegister(regAlloc, encoding, RmRsBit); + } + + return encoding; + } + + public static uint ReplaceRt(uint encoding, int newIndex) + { + return ReplaceRegister(encoding, newIndex, RdRtBit); + } + + public static uint ReplaceRn(uint encoding, int newIndex) + { + return ReplaceRegister(encoding, newIndex, RnBit); + } + + private static uint ReplaceRegister(uint encoding, int newIndex, int bit) + { + encoding &= ~(0x1fu << bit); + encoding |= (uint)newIndex << bit; + + return encoding; + } + + private static uint ReplaceGprRegister(RegisterAllocator regAlloc, uint encoding, int bit, bool hasSP = false) + { + int oldIndex = (int)(encoding >> bit) & 0x1f; + if (oldIndex == ZrIndex && !hasSP) + { + return encoding; + } + + int newIndex = regAlloc.RemapReservedGprRegister(oldIndex); + + encoding &= ~(0x1fu << bit); + encoding |= (uint)newIndex << bit; + + return encoding; + } + + public static (uint, uint) PopulateReadMasks(InstName name, InstFlags flags, uint encoding) + { + uint gprMask = 0; + uint fpSimdMask = 0; + + if (flags.HasFlag(InstFlags.FpSimd)) + { + if (flags.HasFlag(InstFlags.Rd) && flags.HasFlag(InstFlags.ReadRd)) + { + uint mask = MaskFromIndex(ExtractRd(flags, encoding)); + + if (IsFpToGpr(flags, encoding)) + { + gprMask |= mask; + } + else + { + fpSimdMask |= mask; + } + } + + if (flags.HasFlag(InstFlags.Rn)) + { + uint mask = MaskFromIndex(ExtractRn(flags, encoding)); + + if (flags.HasFlag(InstFlags.RnSeq)) + { + int count = GetRnSequenceCount(encoding); + + for (int index = 0; index < count; index++, mask <<= 1) + { + fpSimdMask |= mask; + } + } + else if (IsFpFromGpr(flags, encoding) || flags.HasFlag(InstFlags.Memory)) + { + gprMask |= mask; + } + else + { + fpSimdMask |= mask; + } + } + + if (flags.HasFlag(InstFlags.Rm)) + { + uint mask = MaskFromIndex(ExtractRm(flags, encoding)); + + if (flags.HasFlag(InstFlags.Memory)) + { + gprMask |= mask; + } + else + { + fpSimdMask |= mask; + } + } + + if (flags.HasFlag(InstFlags.Ra)) + { + fpSimdMask |= MaskFromIndex(ExtractRa(flags, encoding)); + } + + if (flags.HasFlag(InstFlags.ReadRt)) + { + if (flags.HasFlag(InstFlags.Rt)) + { + uint mask = MaskFromIndex(ExtractRt(flags, encoding)); + + if (flags.HasFlag(InstFlags.RtSeq)) + { + int count = GetRtSequenceCount(name, encoding); + + for (int index = 0; index < count; index++, mask <<= 1) + { + fpSimdMask |= mask; + } + } + else + { + fpSimdMask |= mask; + } + } + + if (flags.HasFlag(InstFlags.Rt2)) + { + fpSimdMask |= MaskFromIndex(ExtractRt2(flags, encoding)); + } + } + } + else + { + if (flags.HasFlag(InstFlags.Rd) && flags.HasFlag(InstFlags.ReadRd)) + { + gprMask |= MaskFromIndex(ExtractRd(flags, encoding)); + } + + if (flags.HasFlag(InstFlags.Rn)) + { + gprMask |= MaskFromIndex(ExtractRn(flags, encoding)); + } + + if (flags.HasFlag(InstFlags.Rm)) + { + gprMask |= MaskFromIndex(ExtractRm(flags, encoding)); + } + + if (flags.HasFlag(InstFlags.Ra)) + { + gprMask |= MaskFromIndex(ExtractRa(flags, encoding)); + } + + if (flags.HasFlag(InstFlags.ReadRt)) + { + if (flags.HasFlag(InstFlags.Rt)) + { + gprMask |= MaskFromIndex(ExtractRt(flags, encoding)); + } + + if (flags.HasFlag(InstFlags.Rt2)) + { + gprMask |= MaskFromIndex(ExtractRt2(flags, encoding)); + } + } + } + + return (gprMask, fpSimdMask); + } + + public static (uint, uint) PopulateWriteMasks(InstName name, InstFlags flags, uint encoding) + { + uint gprMask = 0; + uint fpSimdMask = 0; + + if (flags.HasFlag(InstFlags.MemWBack)) + { + gprMask |= MaskFromIndex(ExtractRn(flags, encoding)); + } + + if (flags.HasFlag(InstFlags.FpSimd)) + { + if (flags.HasFlag(InstFlags.Rd)) + { + uint mask = MaskFromIndex(ExtractRd(flags, encoding)); + + if (IsFpToGpr(flags, encoding)) + { + gprMask |= mask; + } + else + { + fpSimdMask |= mask; + } + } + + if (!flags.HasFlag(InstFlags.ReadRt)) + { + if (flags.HasFlag(InstFlags.Rt)) + { + uint mask = MaskFromIndex(ExtractRt(flags, encoding)); + + if (flags.HasFlag(InstFlags.RtSeq)) + { + int count = GetRtSequenceCount(name, encoding); + + for (int index = 0; index < count; index++, mask <<= 1) + { + fpSimdMask |= mask; + } + } + else + { + fpSimdMask |= mask; + } + } + + if (flags.HasFlag(InstFlags.Rt2)) + { + fpSimdMask |= MaskFromIndex(ExtractRt2(flags, encoding)); + } + } + } + else + { + if (flags.HasFlag(InstFlags.Rd)) + { + gprMask |= MaskFromIndex(ExtractRd(flags, encoding)); + } + + if (!flags.HasFlag(InstFlags.ReadRt)) + { + if (flags.HasFlag(InstFlags.Rt)) + { + gprMask |= MaskFromIndex(ExtractRt(flags, encoding)); + } + + if (flags.HasFlag(InstFlags.Rt2)) + { + gprMask |= MaskFromIndex(ExtractRt2(flags, encoding)); + } + } + + if (flags.HasFlag(InstFlags.Rs)) + { + gprMask |= MaskFromIndex(ExtractRs(flags, encoding)); + } + } + + return (gprMask, fpSimdMask); + } + + private static uint MaskFromIndex(int index) + { + if (index < SpecialZrIndex) + { + return 1u << index; + } + + return 0u; + } + + private static bool IsFpFromGpr(InstFlags flags, uint encoding) + { + InstFlags bothFlags = InstFlags.FpSimdFromGpr | InstFlags.FpSimdToGpr; + + if ((flags & bothFlags) == bothFlags) // FMOV (general) + { + return (encoding & (1u << 16)) != 0; + } + + return flags.HasFlag(InstFlags.FpSimdFromGpr); + } + + private static bool IsFpToGpr(InstFlags flags, uint encoding) + { + InstFlags bothFlags = InstFlags.FpSimdFromGpr | InstFlags.FpSimdToGpr; + + if ((flags & bothFlags) == bothFlags) // FMOV (general) + { + return (encoding & (1u << 16)) == 0; + } + + return flags.HasFlag(InstFlags.FpSimdToGpr); + } + + private static int GetRtSequenceCount(InstName name, uint encoding) + { + switch (name) + { + case InstName.Ld1AdvsimdMultAsNoPostIndex: + case InstName.Ld1AdvsimdMultAsPostIndex: + case InstName.St1AdvsimdMultAsNoPostIndex: + case InstName.St1AdvsimdMultAsPostIndex: + return ((encoding >> 12) & 0xf) switch + { + 0b0000 => 4, + 0b0010 => 4, + 0b0100 => 3, + 0b0110 => 3, + 0b0111 => 1, + 0b1000 => 2, + 0b1010 => 2, + _ => 1, + }; + case InstName.Ld1rAdvsimdAsNoPostIndex: + case InstName.Ld1rAdvsimdAsPostIndex: + case InstName.Ld1AdvsimdSnglAsNoPostIndex: + case InstName.Ld1AdvsimdSnglAsPostIndex: + case InstName.St1AdvsimdSnglAsNoPostIndex: + case InstName.St1AdvsimdSnglAsPostIndex: + return 1; + case InstName.Ld2rAdvsimdAsNoPostIndex: + case InstName.Ld2rAdvsimdAsPostIndex: + case InstName.Ld2AdvsimdMultAsNoPostIndex: + case InstName.Ld2AdvsimdMultAsPostIndex: + case InstName.Ld2AdvsimdSnglAsNoPostIndex: + case InstName.Ld2AdvsimdSnglAsPostIndex: + case InstName.St2AdvsimdMultAsNoPostIndex: + case InstName.St2AdvsimdMultAsPostIndex: + case InstName.St2AdvsimdSnglAsNoPostIndex: + case InstName.St2AdvsimdSnglAsPostIndex: + return 2; + case InstName.Ld3rAdvsimdAsNoPostIndex: + case InstName.Ld3rAdvsimdAsPostIndex: + case InstName.Ld3AdvsimdMultAsNoPostIndex: + case InstName.Ld3AdvsimdMultAsPostIndex: + case InstName.Ld3AdvsimdSnglAsNoPostIndex: + case InstName.Ld3AdvsimdSnglAsPostIndex: + case InstName.St3AdvsimdMultAsNoPostIndex: + case InstName.St3AdvsimdMultAsPostIndex: + case InstName.St3AdvsimdSnglAsNoPostIndex: + case InstName.St3AdvsimdSnglAsPostIndex: + return 3; + case InstName.Ld4rAdvsimdAsNoPostIndex: + case InstName.Ld4rAdvsimdAsPostIndex: + case InstName.Ld4AdvsimdMultAsNoPostIndex: + case InstName.Ld4AdvsimdMultAsPostIndex: + case InstName.Ld4AdvsimdSnglAsNoPostIndex: + case InstName.Ld4AdvsimdSnglAsPostIndex: + case InstName.St4AdvsimdMultAsNoPostIndex: + case InstName.St4AdvsimdMultAsPostIndex: + case InstName.St4AdvsimdSnglAsNoPostIndex: + case InstName.St4AdvsimdSnglAsPostIndex: + return 4; + } + + return 1; + } + + private static int GetRnSequenceCount(uint encoding) + { + return ((int)(encoding >> 13) & 3) + 1; + } + + public static int ExtractRd(InstFlags flags, uint encoding) + { + Debug.Assert(flags.HasFlag(InstFlags.Rd)); + int index = (int)(encoding >> RdRtBit) & 0x1f; + + if (!flags.HasFlag(InstFlags.RdSP) && index == ZrIndex) + { + return SpecialZrIndex; + } + + return index; + } + + public static int ExtractRn(uint encoding) + { + return (int)(encoding >> RnBit) & 0x1f; + } + + public static int ExtractRn(InstFlags flags, uint encoding) + { + Debug.Assert(flags.HasFlag(InstFlags.Rn)); + int index = ExtractRn(encoding); + + if (!flags.HasFlag(InstFlags.RnSP) && index == ZrIndex) + { + return SpecialZrIndex; + } + + return index; + } + + public static int ExtractRm(uint encoding) + { + return (int)(encoding >> RmRsBit) & 0x1f; + } + + public static int ExtractRm(InstFlags flags, uint encoding) + { + Debug.Assert(flags.HasFlag(InstFlags.Rm)); + int index = ExtractRm(encoding); + + return index == ZrIndex ? SpecialZrIndex : index; + } + + public static int ExtractRs(uint encoding) + { + return (int)(encoding >> RmRsBit) & 0x1f; + } + + public static int ExtractRs(InstFlags flags, uint encoding) + { + Debug.Assert(flags.HasFlag(InstFlags.Rs)); + int index = ExtractRs(encoding); + + return index == ZrIndex ? SpecialZrIndex : index; + } + + public static int ExtractRa(InstFlags flags, uint encoding) + { + Debug.Assert(flags.HasFlag(InstFlags.Ra)); + int index = (int)(encoding >> RaRt2Bit) & 0x1f; + + return index == ZrIndex ? SpecialZrIndex : index; + } + + public static int ExtractRt(uint encoding) + { + return (int)(encoding >> RdRtBit) & 0x1f; + } + + public static int ExtractRt(InstFlags flags, uint encoding) + { + Debug.Assert(flags.HasFlag(InstFlags.Rt)); + int index = ExtractRt(encoding); + + return index == ZrIndex ? SpecialZrIndex : index; + } + + public static int ExtractRt2(InstFlags flags, uint encoding) + { + Debug.Assert(flags.HasFlag(InstFlags.Rt2)); + int index = (int)(encoding >> RaRt2Bit) & 0x1f; + + return index == ZrIndex ? SpecialZrIndex : index; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/Compiler.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/Compiler.cs new file mode 100644 index 000000000..7ef3bf49b --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/Compiler.cs @@ -0,0 +1,743 @@ +using ARMeilleure.Common; +using ARMeilleure.Memory; +using Ryujinx.Cpu.LightningJit.CodeGen; +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; +using Ryujinx.Cpu.LightningJit.Graph; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Numerics; + +namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64 +{ + static class Compiler + { + private const int Encodable26BitsOffsetLimit = 0x2000000; + + private readonly struct Context + { + public readonly CodeWriter Writer; + public readonly RegisterAllocator RegisterAllocator; + public readonly TailMerger TailMerger; + public readonly AddressTable FuncTable; + public readonly IntPtr DispatchStubPointer; + + private readonly MultiBlock _multiBlock; + private readonly RegisterSaveRestore _registerSaveRestore; + private readonly IntPtr _pageTablePointer; + + public Context( + CodeWriter writer, + RegisterAllocator registerAllocator, + TailMerger tailMerger, + RegisterSaveRestore registerSaveRestore, + MultiBlock multiBlock, + AddressTable funcTable, + IntPtr dispatchStubPointer, + IntPtr pageTablePointer) + { + Writer = writer; + RegisterAllocator = registerAllocator; + TailMerger = tailMerger; + _registerSaveRestore = registerSaveRestore; + _multiBlock = multiBlock; + FuncTable = funcTable; + DispatchStubPointer = dispatchStubPointer; + _pageTablePointer = pageTablePointer; + } + + public readonly int GetLrRegisterIndex() + { + return RemapGprRegister(RegisterUtils.LrIndex); + } + + public readonly int RemapGprRegister(int index) + { + return RegisterAllocator.RemapReservedGprRegister(index); + } + + public readonly int GetReservedStackOffset() + { + return _registerSaveRestore.GetReservedStackOffset(); + } + + public readonly void WritePrologue() + { + Assembler asm = new(Writer); + + _registerSaveRestore.WritePrologue(ref asm); + + // If needed, set up the fixed registers with the pointers we will use. + // First one is the context pointer (passed as first argument), + // second one is the page table or address space base, it is at a fixed memory location and considered constant. + + if (RegisterAllocator.FixedContextRegister != 0) + { + asm.Mov(Register(RegisterAllocator.FixedContextRegister), Register(0)); + } + + if (_multiBlock.HasMemoryInstruction) + { + asm.Mov(Register(RegisterAllocator.FixedPageTableRegister), (ulong)_pageTablePointer); + } + + // This assumes that the block with the index 0 is always the entry block. + LoadFromContext(ref asm, _multiBlock.ReadMasks[0]); + } + + public readonly void WriteEpilogueWithoutContext() + { + Assembler asm = new(Writer); + + _registerSaveRestore.WriteEpilogue(ref asm); + } + + public void LoadFromContextAfterCall(int blockIndex) + { + Block block = _multiBlock.Blocks[blockIndex]; + + if (block.SuccessorsCount != 0) + { + Assembler asm = new(Writer); + + RegisterMask readMask = _multiBlock.ReadMasks[block.GetSuccessor(0).Index]; + + for (int sIndex = 1; sIndex < block.SuccessorsCount; sIndex++) + { + IBlock successor = block.GetSuccessor(sIndex); + + readMask |= _multiBlock.ReadMasks[successor.Index]; + } + + LoadFromContext(ref asm, readMask); + } + } + + private void LoadFromContext(ref Assembler asm, RegisterMask readMask) + { + LoadGprFromContext(ref asm, readMask.GprMask, NativeContextOffsets.GprBaseOffset); + LoadFpSimdFromContext(ref asm, readMask.FpSimdMask, NativeContextOffsets.FpSimdBaseOffset); + LoadPStateFromContext(ref asm, readMask.PStateMask, NativeContextOffsets.FlagsBaseOffset); + } + + public void StoreToContextBeforeCall(int blockIndex, ulong? newLrValue = null) + { + Assembler asm = new(Writer); + + StoreToContext(ref asm, _multiBlock.WriteMasks[blockIndex], newLrValue); + } + + private void StoreToContext(ref Assembler asm, RegisterMask writeMask, ulong? newLrValue) + { + StoreGprToContext(ref asm, writeMask.GprMask, NativeContextOffsets.GprBaseOffset, newLrValue); + StoreFpSimdToContext(ref asm, writeMask.FpSimdMask, NativeContextOffsets.FpSimdBaseOffset); + StorePStateToContext(ref asm, writeMask.PStateMask, NativeContextOffsets.FlagsBaseOffset); + } + + private void LoadGprFromContext(ref Assembler asm, uint mask, int baseOffset) + { + Operand contextPtr = Register(RegisterAllocator.FixedContextRegister); + + while (mask != 0) + { + int reg = BitOperations.TrailingZeroCount(mask); + int offset = baseOffset + reg * 8; + + if (reg < 31 && (mask & (2u << reg)) != 0 && offset < RegisterSaveRestore.Encodable9BitsOffsetLimit) + { + mask &= ~(3u << reg); + + asm.LdpRiUn( + Register(RegisterAllocator.RemapReservedGprRegister(reg)), + Register(RegisterAllocator.RemapReservedGprRegister(reg + 1)), + contextPtr, + offset); + } + else + { + mask &= ~(1u << reg); + + asm.LdrRiUn(Register(RegisterAllocator.RemapReservedGprRegister(reg)), contextPtr, offset); + } + } + } + + private void LoadFpSimdFromContext(ref Assembler asm, uint mask, int baseOffset) + { + Operand contextPtr = Register(RegisterAllocator.FixedContextRegister); + + while (mask != 0) + { + int reg = BitOperations.TrailingZeroCount(mask); + int offset = baseOffset + reg * 16; + + mask &= ~(1u << reg); + + asm.LdrRiUn(Register(reg, OperandType.V128), contextPtr, offset); + } + } + + private void LoadPStateFromContext(ref Assembler asm, uint mask, int baseOffset) + { + if (mask == 0) + { + return; + } + + Operand contextPtr = Register(RegisterAllocator.FixedContextRegister); + + int tempRegister = RegisterAllocator.AllocateTempGprRegister(); + + Operand rt = Register(tempRegister, OperandType.I32); + + asm.LdrRiUn(rt, contextPtr, baseOffset); + asm.MsrNzcv(rt); + + RegisterAllocator.FreeTempGprRegister(tempRegister); + } + + private void StoreGprToContext(ref Assembler asm, uint mask, int baseOffset, ulong? newLrValue) + { + Operand contextPtr = Register(RegisterAllocator.FixedContextRegister); + + int tempRegister = -1; + + if (newLrValue.HasValue) + { + // This is required for BLR X30 instructions, where we need to get the target address + // before it is overwritten with the return address that the call would write there. + + tempRegister = RegisterAllocator.AllocateTempGprRegister(); + + asm.Mov(Register(tempRegister), newLrValue.Value); + } + + while (mask != 0) + { + int reg = BitOperations.TrailingZeroCount(mask); + int offset = baseOffset + reg * 8; + + if (reg < 31 && (mask & (2u << reg)) != 0 && offset < RegisterSaveRestore.Encodable9BitsOffsetLimit) + { + mask &= ~(3u << reg); + + asm.StpRiUn( + Register(RemapReservedGprRegister(reg, tempRegister)), + Register(RemapReservedGprRegister(reg + 1, tempRegister)), + contextPtr, + offset); + } + else + { + mask &= ~(1u << reg); + + asm.StrRiUn(Register(RemapReservedGprRegister(reg, tempRegister)), contextPtr, offset); + } + } + + if (tempRegister >= 0) + { + RegisterAllocator.FreeTempGprRegister(tempRegister); + } + } + + private int RemapReservedGprRegister(int index, int tempRegister) + { + if (tempRegister >= 0 && index == RegisterUtils.LrIndex) + { + return tempRegister; + } + + return RegisterAllocator.RemapReservedGprRegister(index); + } + + private void StoreFpSimdToContext(ref Assembler asm, uint mask, int baseOffset) + { + Operand contextPtr = Register(RegisterAllocator.FixedContextRegister); + + while (mask != 0) + { + int reg = BitOperations.TrailingZeroCount(mask); + int offset = baseOffset + reg * 16; + + mask &= ~(1u << reg); + + asm.StrRiUn(Register(reg, OperandType.V128), contextPtr, offset); + } + } + + private void StorePStateToContext(ref Assembler asm, uint mask, int baseOffset) + { + if (mask == 0) + { + return; + } + + Operand contextPtr = Register(RegisterAllocator.FixedContextRegister); + + int tempRegister = RegisterAllocator.AllocateTempGprRegister(); + + Operand rt = Register(tempRegister, OperandType.I32); + + asm.MrsNzcv(rt); + asm.StrRiUn(rt, contextPtr, baseOffset); + + RegisterAllocator.FreeTempGprRegister(tempRegister); + } + } + + private readonly struct PendingBranch + { + public readonly int BlockIndex; + public readonly ulong Pc; + public readonly InstName Name; + public readonly uint Encoding; + public readonly int WriterPointer; + + public PendingBranch(int blockIndex, ulong pc, InstName name, uint encoding, int writerPointer) + { + BlockIndex = blockIndex; + Pc = pc; + Name = name; + Encoding = encoding; + WriterPointer = writerPointer; + } + } + + public static CompiledFunction Compile(CpuPreset cpuPreset, IMemoryManager memoryManager, ulong address, AddressTable funcTable, IntPtr dispatchStubPtr) + { + MultiBlock multiBlock = Decoder.DecodeMulti(cpuPreset, memoryManager, address); + + Dictionary targets = new(); + List pendingBranches = new(); + + uint gprUseMask = multiBlock.GlobalUseMask.GprMask; + uint fpSimdUseMask = multiBlock.GlobalUseMask.FpSimdMask; + uint pStateUseMask = multiBlock.GlobalUseMask.PStateMask; + + CodeWriter writer = new(); + RegisterAllocator regAlloc = new(gprUseMask, fpSimdUseMask, pStateUseMask, multiBlock.HasHostCall); + RegisterSaveRestore rsr = new( + regAlloc.AllGprMask & AbiConstants.GprCalleeSavedRegsMask, + regAlloc.AllFpSimdMask & AbiConstants.FpSimdCalleeSavedRegsMask, + OperandType.FP64, + multiBlock.HasHostCall, + multiBlock.HasHostCall ? CalculateStackSizeForCallSpill(regAlloc.AllGprMask, regAlloc.AllFpSimdMask, regAlloc.AllPStateMask) : 0); + + TailMerger tailMerger = new(); + + Context context = new(writer, regAlloc, tailMerger, rsr, multiBlock, funcTable, dispatchStubPtr, memoryManager.PageTablePointer); + + context.WritePrologue(); + + ulong pc = address; + + for (int blockIndex = 0; blockIndex < multiBlock.Blocks.Count; blockIndex++) + { + Block block = multiBlock.Blocks[blockIndex]; + + Debug.Assert(block.Address == pc); + + targets.Add(pc, writer.InstructionPointer); + + int instCount = block.EndsWithBranch ? block.Instructions.Count - 1 : block.Instructions.Count; + + for (int index = 0; index < instCount; index++) + { + InstInfo instInfo = block.Instructions[index]; + + uint encoding = RegisterUtils.RemapRegisters(regAlloc, instInfo.Flags, instInfo.Encoding); + + if (instInfo.AddressForm != AddressForm.None) + { + InstEmitMemory.RewriteInstruction( + memoryManager.AddressSpaceBits, + memoryManager.Type, + writer, + regAlloc, + instInfo.Name, + instInfo.Flags, + instInfo.AddressForm, + pc, + encoding); + } + else if (instInfo.Name == InstName.Sys) + { + InstEmitMemory.RewriteSysInstruction(memoryManager.AddressSpaceBits, memoryManager.Type, writer, regAlloc, encoding); + } + else if (instInfo.Name.IsSystem()) + { + bool needsContextStoreLoad = InstEmitSystem.NeedsContextStoreLoad(instInfo.Name); + + if (needsContextStoreLoad) + { + context.StoreToContextBeforeCall(blockIndex); + } + + InstEmitSystem.RewriteInstruction(writer, regAlloc, tailMerger, instInfo.Name, pc, encoding, rsr.GetReservedStackOffset()); + + if (needsContextStoreLoad) + { + context.LoadFromContextAfterCall(blockIndex); + } + } + else + { + writer.WriteInstruction(encoding); + } + + pc += 4UL; + } + + if (block.IsLoopEnd) + { + // If this is a loop, the code might run for a long time uninterrupted. + // We insert a "sync point" here to ensure the loop can be interrupted if needed. + + InstEmitSystem.WriteSyncPoint(writer, context.RegisterAllocator, tailMerger, context.GetReservedStackOffset()); + } + + if (blockIndex < multiBlock.Blocks.Count - 1) + { + InstInfo lastInstructionInfo = block.Instructions[^1]; + InstName lastInstructionName = lastInstructionInfo.Name; + InstFlags lastInstructionFlags = lastInstructionInfo.Flags; + uint lastInstructionEncoding = lastInstructionInfo.Encoding; + + lastInstructionEncoding = RegisterUtils.RemapRegisters(regAlloc, lastInstructionFlags, lastInstructionEncoding); + + if (lastInstructionName.IsCall()) + { + context.StoreToContextBeforeCall(blockIndex, pc + 4UL); + + InstEmitSystem.RewriteCallInstruction( + writer, + regAlloc, + tailMerger, + context.WriteEpilogueWithoutContext, + funcTable, + dispatchStubPtr, + lastInstructionName, + pc, + lastInstructionEncoding, + context.GetReservedStackOffset()); + + context.LoadFromContextAfterCall(blockIndex); + + pc += 4UL; + } + else if (lastInstructionName == InstName.Ret) + { + RewriteBranchInstruction(context, blockIndex, lastInstructionName, pc, lastInstructionEncoding); + + pc += 4UL; + } + else if (block.EndsWithBranch) + { + pendingBranches.Add(new(blockIndex, pc, lastInstructionName, lastInstructionEncoding, writer.InstructionPointer)); + writer.WriteInstruction(0u); // Placeholder. + + pc += 4UL; + } + } + } + + int lastBlockIndex = multiBlock.Blocks[^1].Index; + + if (multiBlock.IsTruncated) + { + Assembler asm = new(writer); + + WriteTailCallConstant(context, ref asm, lastBlockIndex, pc); + } + else + { + InstInfo lastInstructionInfo = multiBlock.Blocks[^1].Instructions[^1]; + InstName lastInstructionName = lastInstructionInfo.Name; + InstFlags lastInstructionFlags = lastInstructionInfo.Flags; + uint lastInstructionEncoding = lastInstructionInfo.Encoding; + + lastInstructionEncoding = RegisterUtils.RemapRegisters(regAlloc, lastInstructionFlags, lastInstructionEncoding); + + RewriteBranchInstruction(context, lastBlockIndex, lastInstructionName, pc, lastInstructionEncoding); + + pc += 4; + } + + foreach (PendingBranch pendingBranch in pendingBranches) + { + RewriteBranchInstructionWithTarget( + context, + pendingBranch.BlockIndex, + pendingBranch.Name, + pendingBranch.Pc, + pendingBranch.Encoding, + pendingBranch.WriterPointer, + targets); + } + + tailMerger.WriteReturn(writer, context.WriteEpilogueWithoutContext); + + return new(writer.AsByteSpan(), (int)(pc - address)); + } + + private static int CalculateStackSizeForCallSpill(uint gprUseMask, uint fpSimdUseMask, uint pStateUseMask) + { + // Note that we don't discard callee saved FP/SIMD register because only the lower 64 bits is callee saved, + // so if the function is using the full register, that won't be enough. + // We could do better, but it's likely not worth it since this case happens very rarely in practice. + + return BitOperations.PopCount(gprUseMask & ~AbiConstants.GprCalleeSavedRegsMask) * 8 + + BitOperations.PopCount(fpSimdUseMask) * 16 + + (pStateUseMask != 0 ? 8 : 0); + } + + private static void RewriteBranchInstruction(in Context context, int blockIndex, InstName name, ulong pc, uint encoding) + { + CodeWriter writer = context.Writer; + Assembler asm = new(writer); + + int originalOffset; + ulong nextAddress = pc + 4UL; + ulong targetAddress; + + switch (name) + { + case InstName.BUncond: + originalOffset = ImmUtils.ExtractSImm26Times4(encoding); + targetAddress = pc + (ulong)originalOffset; + + WriteTailCallConstant(context, ref asm, blockIndex, targetAddress); + break; + + case InstName.Bl: + case InstName.Blr: + case InstName.Br: + if (name == InstName.Bl) + { + asm.Mov(Register(context.GetLrRegisterIndex()), nextAddress); + + int imm = ImmUtils.ExtractSImm26Times4(encoding); + + WriteTailCallConstant(context, ref asm, blockIndex, pc + (ulong)imm); + } + else + { + bool isCall = name == InstName.Blr; + if (isCall) + { + context.StoreToContextBeforeCall(blockIndex, nextAddress); + } + else + { + context.StoreToContextBeforeCall(blockIndex); + } + + InstEmitSystem.RewriteCallInstruction( + context.Writer, + context.RegisterAllocator, + context.TailMerger, + context.WriteEpilogueWithoutContext, + context.FuncTable, + context.DispatchStubPointer, + name, + pc, + encoding, + context.GetReservedStackOffset(), + isTail: true); + } + break; + + case InstName.Ret: + int rnIndex = RegisterUtils.ExtractRn(encoding); + if (rnIndex == RegisterUtils.ZrIndex) + { + WriteTailCallConstant(context, ref asm, blockIndex, 0UL); + } + else + { + rnIndex = context.RemapGprRegister(rnIndex); + context.StoreToContextBeforeCall(blockIndex); + + if (rnIndex != 0) + { + asm.Mov(Register(0), Register(rnIndex)); + } + + context.TailMerger.AddUnconditionalReturn(writer, asm); + } + break; + + case InstName.BCond: + case InstName.Cbnz: + case InstName.Cbz: + case InstName.Tbnz: + case InstName.Tbz: + uint branchMask; + + if (name == InstName.Tbnz || name == InstName.Tbz) + { + originalOffset = ImmUtils.ExtractSImm14Times4(encoding); + branchMask = 0x3fff; + } + else + { + originalOffset = ImmUtils.ExtractSImm19Times4(encoding); + branchMask = 0x7ffff; + } + + targetAddress = pc + (ulong)originalOffset; + + int branchIndex = writer.InstructionPointer; + + writer.WriteInstruction(0u); // Reserved for branch. + WriteTailCallConstant(context, ref asm, blockIndex, nextAddress); + + int targetIndex = writer.InstructionPointer; + + writer.WriteInstructionAt(branchIndex, (encoding & ~(branchMask << 5)) | (uint)(((targetIndex - branchIndex) & branchMask) << 5)); + WriteTailCallConstant(context, ref asm, blockIndex, targetAddress); + break; + + default: + Debug.Fail($"Unknown branch instruction \"{name}\"."); + break; + } + } + + private static void RewriteBranchInstructionWithTarget( + in Context context, + int blockIndex, + InstName name, + ulong pc, + uint encoding, + int branchIndex, + Dictionary targets) + { + CodeWriter writer = context.Writer; + Assembler asm = new(writer); + + int delta; + int targetIndex; + int originalOffset; + ulong targetAddress; + + switch (name) + { + case InstName.BUncond: + originalOffset = ImmUtils.ExtractSImm26Times4(encoding); + targetAddress = pc + (ulong)originalOffset; + + if (targets.TryGetValue(targetAddress, out targetIndex)) + { + delta = targetIndex - branchIndex; + + if (delta >= -Encodable26BitsOffsetLimit && delta < Encodable26BitsOffsetLimit) + { + writer.WriteInstructionAt(branchIndex, (encoding & ~0x3ffffffu) | (uint)(delta & 0x3ffffff)); + break; + } + } + + targetIndex = writer.InstructionPointer; + delta = targetIndex - branchIndex; + + writer.WriteInstructionAt(branchIndex, (encoding & ~0x3ffffffu) | (uint)(delta & 0x3ffffff)); + WriteTailCallConstant(context, ref asm, blockIndex, targetAddress); + break; + + case InstName.BCond: + case InstName.Cbnz: + case InstName.Cbz: + case InstName.Tbnz: + case InstName.Tbz: + uint branchMask; + + if (name == InstName.Tbnz || name == InstName.Tbz) + { + originalOffset = ImmUtils.ExtractSImm14Times4(encoding); + branchMask = 0x3fff; + } + else + { + originalOffset = ImmUtils.ExtractSImm19Times4(encoding); + branchMask = 0x7ffff; + } + + int branchMax = (int)(branchMask + 1) / 2; + + targetAddress = pc + (ulong)originalOffset; + + if (targets.TryGetValue(targetAddress, out targetIndex)) + { + delta = targetIndex - branchIndex; + + if (delta >= -branchMax && delta < branchMax) + { + writer.WriteInstructionAt(branchIndex, (encoding & ~(branchMask << 5)) | (uint)((delta & branchMask) << 5)); + break; + } + } + + targetIndex = writer.InstructionPointer; + delta = targetIndex - branchIndex; + + if (delta >= -branchMax && delta < branchMax) + { + writer.WriteInstructionAt(branchIndex, (encoding & ~(branchMask << 5)) | (uint)((delta & branchMask) << 5)); + WriteTailCallConstant(context, ref asm, blockIndex, targetAddress); + } + else + { + // If the branch target is too far away, we use a regular unconditional branch + // instruction instead which has a much higher range. + // We branch directly to the end of the function, where we put the conditional branch, + // and then branch back to the next instruction or return the branch target depending + // on the branch being taken or not. + + uint branchInst = 0x14000000u | ((uint)delta & 0x3ffffff); + Debug.Assert(ImmUtils.ExtractSImm26Times4(branchInst) == delta * 4); + + writer.WriteInstructionAt(branchIndex, branchInst); + + int movedBranchIndex = writer.InstructionPointer; + + writer.WriteInstruction(0u); // Placeholder + asm.B((branchIndex + 1 - writer.InstructionPointer) * 4); + + delta = writer.InstructionPointer - movedBranchIndex; + + writer.WriteInstructionAt(movedBranchIndex, (encoding & ~(branchMask << 5)) | (uint)((delta & branchMask) << 5)); + WriteTailCallConstant(context, ref asm, blockIndex, targetAddress); + } + break; + + default: + Debug.Fail($"Unknown branch instruction \"{name}\"."); + break; + } + } + + private static void WriteTailCallConstant(in Context context, ref Assembler asm, int blockIndex, ulong address) + { + context.StoreToContextBeforeCall(blockIndex); + InstEmitSystem.WriteCallWithGuestAddress( + context.Writer, + ref asm, + context.RegisterAllocator, + context.TailMerger, + context.WriteEpilogueWithoutContext, + context.FuncTable, + context.DispatchStubPointer, + context.GetReservedStackOffset(), + 0UL, + new Operand(OperandKind.Constant, OperandType.I64, address), + isTail: true); + } + + private static Operand Register(int register, OperandType type = OperandType.I64) + { + return new Operand(register, RegisterType.Integer, type); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/Decoder.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/Decoder.cs new file mode 100644 index 000000000..738b8a32d --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/Decoder.cs @@ -0,0 +1,384 @@ +using ARMeilleure.Memory; +using Ryujinx.Cpu.LightningJit.Graph; +using System.Collections.Generic; +using System.Diagnostics; +using System.Numerics; + +namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64 +{ + static class Decoder + { + private const int MaxInstructionsPerBlock = 1000; + + private const uint NzcvFlags = 0xfu << 28; + private const uint CFlag = 0x1u << 29; + + public static MultiBlock DecodeMulti(CpuPreset cpuPreset, IMemoryManager memoryManager, ulong address) + { + List blocks = new(); + List branchTargets = new(); + + RegisterMask useMask = RegisterMask.Zero; + + bool hasHostCall = false; + bool hasMemoryInstruction = false; + + while (true) + { + Block block = Decode(cpuPreset, memoryManager, address, ref useMask, ref hasHostCall, ref hasMemoryInstruction); + + if (!block.IsTruncated && TryGetBranchTarget(block, out ulong targetAddress)) + { + branchTargets.Add(targetAddress); + } + + blocks.Add(block); + + if (block.IsTruncated || !HasNextBlock(block, block.EndAddress - 4UL, branchTargets)) + { + break; + } + + address = block.EndAddress; + } + + branchTargets.Sort(); + SplitBlocks(blocks, branchTargets); + NumberAndLinkBlocks(blocks); + + return new(blocks, useMask, hasHostCall, hasMemoryInstruction); + } + + private static bool TryGetBranchTarget(Block block, out ulong targetAddress) + { + return TryGetBranchTarget(block.Instructions[^1].Name, block.EndAddress - 4UL, block.Instructions[^1].Encoding, out targetAddress); + } + + private static bool TryGetBranchTarget(InstName name, ulong pc, uint encoding, out ulong targetAddress) + { + int originalOffset; + + switch (name) + { + case InstName.BUncond: + originalOffset = ImmUtils.ExtractSImm26Times4(encoding); + targetAddress = pc + (ulong)originalOffset; + + return true; + + case InstName.BCond: + case InstName.Cbnz: + case InstName.Cbz: + case InstName.Tbnz: + case InstName.Tbz: + if (name == InstName.Tbnz || name == InstName.Tbz) + { + originalOffset = ImmUtils.ExtractSImm14Times4(encoding); + } + else + { + originalOffset = ImmUtils.ExtractSImm19Times4(encoding); + } + + targetAddress = pc + (ulong)originalOffset; + + return true; + } + + targetAddress = 0; + + return false; + } + + private static void SplitBlocks(List blocks, List branchTargets) + { + int btIndex = 0; + + while (btIndex < branchTargets.Count) + { + for (int blockIndex = 0; blockIndex < blocks.Count && btIndex < branchTargets.Count; blockIndex++) + { + Block block = blocks[blockIndex]; + ulong currentBranchTarget = branchTargets[btIndex]; + + while (currentBranchTarget >= block.Address && currentBranchTarget < block.EndAddress) + { + if (block.Address != currentBranchTarget) + { + (Block leftBlock, Block rightBlock) = block.SplitAtAddress(currentBranchTarget); + + blocks.Insert(blockIndex, leftBlock); + blocks[blockIndex + 1] = rightBlock; + + block = leftBlock; + } + + btIndex++; + + while (btIndex < branchTargets.Count && branchTargets[btIndex] == currentBranchTarget) + { + btIndex++; + } + + if (btIndex >= branchTargets.Count) + { + break; + } + + currentBranchTarget = branchTargets[btIndex]; + } + } + + Debug.Assert(btIndex < int.MaxValue); + btIndex++; + } + } + + private static void NumberAndLinkBlocks(List blocks) + { + Dictionary blocksByAddress = new(); + + for (int blockIndex = 0; blockIndex < blocks.Count; blockIndex++) + { + Block block = blocks[blockIndex]; + + blocksByAddress.Add(block.Address, block); + } + + for (int blockIndex = 0; blockIndex < blocks.Count; blockIndex++) + { + Block block = blocks[blockIndex]; + + block.Number(blockIndex); + + if (!block.IsTruncated) + { + bool hasNext = !block.EndsWithBranch; + bool hasBranch = false; + + switch (block.Instructions[^1].Name) + { + case InstName.BUncond: + hasBranch = true; + break; + + case InstName.BCond: + case InstName.Cbnz: + case InstName.Cbz: + case InstName.Tbnz: + case InstName.Tbz: + hasNext = true; + hasBranch = true; + break; + + case InstName.Bl: + case InstName.Blr: + hasNext = true; + break; + + case InstName.Ret: + hasNext = false; + hasBranch = false; + break; + } + + if (hasNext && blocksByAddress.TryGetValue(block.EndAddress, out Block nextBlock)) + { + block.AddSuccessor(nextBlock); + nextBlock.AddPredecessor(block); + } + + if (hasBranch && + TryGetBranchTarget(block, out ulong targetAddress) && + blocksByAddress.TryGetValue(targetAddress, out Block branchBlock)) + { + block.AddSuccessor(branchBlock); + branchBlock.AddPredecessor(block); + } + } + } + } + + private static bool HasNextBlock(in Block block, ulong pc, List branchTargets) + { + switch (block.Instructions[^1].Name) + { + case InstName.BUncond: + return branchTargets.Contains(pc + 4UL) || + (TryGetBranchTarget(block, out ulong targetAddress) && targetAddress >= pc && targetAddress < pc + 0x1000); + + case InstName.BCond: + case InstName.Bl: + case InstName.Blr: + case InstName.Cbnz: + case InstName.Cbz: + case InstName.Tbnz: + case InstName.Tbz: + return true; + + case InstName.Br: + return false; + + case InstName.Ret: + return branchTargets.Contains(pc + 4UL); + } + + return !block.EndsWithBranch; + } + + private static Block Decode( + CpuPreset cpuPreset, + IMemoryManager memoryManager, + ulong address, + ref RegisterMask useMask, + ref bool hasHostCall, + ref bool hasMemoryInstruction) + { + ulong startAddress = address; + + List insts = new(); + + uint gprUseMask = useMask.GprMask; + uint fpSimdUseMask = useMask.FpSimdMask; + uint pStateUseMask = useMask.PStateMask; + + uint encoding; + InstName name; + InstFlags flags; + bool isControlFlow; + bool isTruncated = false; + + do + { + encoding = memoryManager.Read(address); + address += 4UL; + + (name, flags, AddressForm addressForm) = InstTable.GetInstNameAndFlags(encoding, cpuPreset.Version, cpuPreset.Features); + + if (name.IsPrivileged()) + { + name = InstName.UdfPermUndef; + flags = InstFlags.None; + addressForm = AddressForm.None; + } + + (uint instGprReadMask, uint instFpSimdReadMask) = RegisterUtils.PopulateReadMasks(name, flags, encoding); + (uint instGprWriteMask, uint instFpSimdWriteMask) = RegisterUtils.PopulateWriteMasks(name, flags, encoding); + + if (name.IsCall()) + { + instGprWriteMask |= 1u << RegisterUtils.LrIndex; + } + + uint tempGprUseMask = gprUseMask | instGprReadMask | instGprWriteMask; + + if (CalculateAvailableTemps(tempGprUseMask) < CalculateRequiredGprTemps(tempGprUseMask) || insts.Count >= MaxInstructionsPerBlock) + { + isTruncated = true; + address -= 4UL; + + break; + } + + gprUseMask = tempGprUseMask; + + uint instPStateReadMask = 0; + uint instPStateWriteMask = 0; + + if (flags.HasFlag(InstFlags.Nzcv) || IsMrsNzcv(encoding)) + { + instPStateReadMask = NzcvFlags; + } + else if (flags.HasFlag(InstFlags.C)) + { + instPStateReadMask = CFlag; + } + + if (flags.HasFlag(InstFlags.S) || IsMsrNzcv(encoding)) + { + instPStateWriteMask = NzcvFlags; + } + + if (flags.HasFlag(InstFlags.Memory) || name == InstName.Sys) + { + hasMemoryInstruction = true; + } + + fpSimdUseMask |= instFpSimdReadMask | instFpSimdWriteMask; + pStateUseMask |= instPStateReadMask | instPStateWriteMask; + + if (name.IsSystemOrCall() && !hasHostCall) + { + hasHostCall = name.IsCall() || InstEmitSystem.NeedsCall(encoding); + } + + isControlFlow = name.IsControlFlowOrException(); + + RegisterUse registerUse = new( + instGprReadMask, + instGprWriteMask, + instFpSimdReadMask, + instFpSimdWriteMask, + instPStateReadMask, + instPStateWriteMask); + + insts.Add(new(encoding, name, flags, addressForm, registerUse)); + } + while (!isControlFlow); + + bool isLoopEnd = false; + + if (!isTruncated && IsBackwardsBranch(name, encoding)) + { + hasHostCall = true; + isLoopEnd = true; + } + + useMask = new(gprUseMask, fpSimdUseMask, pStateUseMask); + + return new(startAddress, address, insts, !isTruncated && !name.IsException(), isTruncated, isLoopEnd); + } + + private static bool IsMrsNzcv(uint encoding) + { + return (encoding & ~0x1fu) == 0xd53b4200u; + } + + private static bool IsMsrNzcv(uint encoding) + { + return (encoding & ~0x1fu) == 0xd51b4200u; + } + + private static bool IsBackwardsBranch(InstName name, uint encoding) + { + switch (name) + { + case InstName.BUncond: + return ImmUtils.ExtractSImm26Times4(encoding) < 0; + + case InstName.BCond: + case InstName.Cbnz: + case InstName.Cbz: + case InstName.Tbnz: + case InstName.Tbz: + int imm = name == InstName.Tbnz || name == InstName.Tbz + ? ImmUtils.ExtractSImm14Times4(encoding) + : ImmUtils.ExtractSImm19Times4(encoding); + + return imm < 0; + } + + return false; + } + + private static int CalculateRequiredGprTemps(uint gprUseMask) + { + return BitOperations.PopCount(gprUseMask & RegisterUtils.ReservedRegsMask) + RegisterAllocator.MaxTempsInclFixed; + } + + private static int CalculateAvailableTemps(uint gprUseMask) + { + return BitOperations.PopCount(~(gprUseMask | RegisterUtils.ReservedRegsMask)); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitMemory.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitMemory.cs new file mode 100644 index 000000000..ece1520fd --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitMemory.cs @@ -0,0 +1,593 @@ +using ARMeilleure.Memory; +using Ryujinx.Cpu.LightningJit.CodeGen; +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; +using System; +using System.Diagnostics; + +namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64 +{ + static class InstEmitMemory + { + private const uint XMask = 0x3f808000u; + private const uint XValue = 0x8000000u; + + public static void RewriteSysInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, uint encoding) + { + int rtIndex = RegisterUtils.ExtractRt(encoding); + if (rtIndex == RegisterUtils.ZrIndex) + { + writer.WriteInstruction(encoding); + + return; + } + + int tempRegister = regAlloc.AllocateTempGprRegister(); + Operand rt = new(tempRegister, RegisterType.Integer, OperandType.I64); + Operand guestAddress = new(rtIndex, RegisterType.Integer, OperandType.I64); + + Assembler asm = new(writer); + + WriteAddressTranslation(asBits, mmType, regAlloc, ref asm, rt, guestAddress); + + encoding = RegisterUtils.ReplaceRt(encoding, tempRegister); + + writer.WriteInstruction(encoding); + + regAlloc.FreeTempGprRegister(tempRegister); + } + + public static void RewriteInstruction( + int asBits, + MemoryManagerType mmType, + CodeWriter writer, + RegisterAllocator regAlloc, + InstName name, + InstFlags flags, + AddressForm addressForm, + ulong pc, + uint encoding) + { + switch (addressForm) + { + case AddressForm.OffsetReg: + RewriteOffsetRegMemoryInstruction(asBits, mmType, writer, regAlloc, flags, encoding); + break; + case AddressForm.PostIndexed: + RewritePostIndexedMemoryInstruction(asBits, mmType, writer, regAlloc, flags, encoding); + break; + case AddressForm.PreIndexed: + RewritePreIndexedMemoryInstruction(asBits, mmType, writer, regAlloc, flags, encoding); + break; + case AddressForm.SignedScaled: + RewriteSignedScaledMemoryInstruction(asBits, mmType, writer, regAlloc, flags, encoding); + break; + case AddressForm.UnsignedScaled: + RewriteUnsignedScaledMemoryInstruction(asBits, mmType, writer, regAlloc, flags, encoding); + break; + case AddressForm.BaseRegister: + // Some applications uses unordered memory instructions in places where + // it does need proper ordering, and only work on some CPUs. + // To work around this, make all exclusive access operations ordered. + + if ((encoding & XMask) == XValue) + { + // Set ordered flag. + encoding |= 1u << 15; + } + + RewriteBaseRegisterMemoryInstruction(asBits, mmType, writer, regAlloc, encoding); + break; + case AddressForm.StructNoOffset: + RewriteBaseRegisterMemoryInstruction(asBits, mmType, writer, regAlloc, encoding); + break; + case AddressForm.BasePlusOffset: + RewriteBasePlusOffsetMemoryInstruction(asBits, mmType, writer, regAlloc, encoding); + break; + case AddressForm.Literal: + RewriteLiteralMemoryInstruction(asBits, mmType, writer, regAlloc, name, pc, encoding); + break; + case AddressForm.StructPostIndexedReg: + RewriteStructPostIndexedRegMemoryInstruction(asBits, mmType, writer, regAlloc, encoding); + break; + default: + writer.WriteInstruction(encoding); + break; + } + } + + private static void RewriteOffsetRegMemoryInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, InstFlags flags, uint encoding) + { + // TODO: Some unallocated encoding cases. + + ArmExtensionType extensionType = (ArmExtensionType)((encoding >> 13) & 7); + + uint size = encoding >> 30; + + if (flags.HasFlag(InstFlags.FpSimd)) + { + size |= (encoding >> 21) & 4u; + } + + int shift = (encoding & (1u << 12)) != 0 ? (int)size : 0; + + int tempRegister = regAlloc.AllocateTempGprRegister(); + Operand rn = new(tempRegister, RegisterType.Integer, OperandType.I64); + Operand guestAddress = new(RegisterUtils.ExtractRn(encoding), RegisterType.Integer, OperandType.I64); + Operand guestOffset = new(RegisterUtils.ExtractRm(encoding), RegisterType.Integer, OperandType.I64); + + Assembler asm = new(writer); + + asm.Add(rn, guestAddress, guestOffset, extensionType, shift); + + WriteAddressTranslation(asBits, mmType, regAlloc, ref asm, rn, rn); + + encoding = RegisterUtils.ReplaceRn(encoding, tempRegister); + encoding = (encoding & ~(0xfffu << 10)) | (1u << 24); // Register -> Unsigned offset + + writer.WriteInstruction(encoding); + + regAlloc.FreeTempGprRegister(tempRegister); + } + + private static void RewritePostIndexedMemoryInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, InstFlags flags, uint encoding) + { + bool isPair = flags.HasFlag(InstFlags.Rt2); + int imm = isPair ? ExtractSImm7Scaled(flags, encoding) : ExtractSImm9(encoding); + + int tempRegister = regAlloc.AllocateTempGprRegister(); + Operand rn = new(tempRegister, RegisterType.Integer, OperandType.I64); + Operand guestAddress = new(RegisterUtils.ExtractRn(encoding), RegisterType.Integer, OperandType.I64); + + Assembler asm = new(writer); + + WriteAddressTranslation(asBits, mmType, regAlloc, ref asm, rn, guestAddress); + + encoding = RegisterUtils.ReplaceRn(encoding, tempRegister); + + if (isPair) + { + // Post-index -> Signed offset + encoding &= ~(0x7fu << 15); + encoding ^= 3u << 23; + } + else + { + // Post-index -> Unsigned offset + encoding = (encoding & ~(0xfffu << 10)) | (1u << 24); + } + + writer.WriteInstruction(encoding); + + WriteAddConstant(ref asm, guestAddress, guestAddress, imm); + + regAlloc.FreeTempGprRegister(tempRegister); + } + + private static void RewritePreIndexedMemoryInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, InstFlags flags, uint encoding) + { + bool isPair = flags.HasFlag(InstFlags.Rt2); + int imm = isPair ? ExtractSImm7Scaled(flags, encoding) : ExtractSImm9(encoding); + + int tempRegister = regAlloc.AllocateTempGprRegister(); + Operand rn = new(tempRegister, RegisterType.Integer, OperandType.I64); + Operand guestAddress = new(RegisterUtils.ExtractRn(encoding), RegisterType.Integer, OperandType.I64); + + Assembler asm = new(writer); + + WriteAddConstant(ref asm, guestAddress, guestAddress, imm); + WriteAddressTranslation(asBits, mmType, regAlloc, ref asm, rn, guestAddress); + + encoding = RegisterUtils.ReplaceRn(encoding, tempRegister); + + if (isPair) + { + // Pre-index -> Signed offset + encoding &= ~(0x7fu << 15); + encoding &= ~(1u << 23); + } + else + { + // Pre-index -> Unsigned offset + encoding = (encoding & ~(0xfffu << 10)) | (1u << 24); + } + + writer.WriteInstruction(encoding); + + regAlloc.FreeTempGprRegister(tempRegister); + } + + private static void RewriteSignedScaledMemoryInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, InstFlags flags, uint encoding) + { + RewriteMemoryInstruction(asBits, mmType, writer, regAlloc, encoding, ExtractSImm7Scaled(flags, encoding), 0x7fu << 15); + } + + private static void RewriteUnsignedScaledMemoryInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, InstFlags flags, uint encoding) + { + RewriteMemoryInstruction(asBits, mmType, writer, regAlloc, encoding, ExtractUImm12Scaled(flags, encoding), 0xfffu << 10); + } + + private static void RewriteBaseRegisterMemoryInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, uint encoding) + { + RewriteMemoryInstruction(asBits, mmType, writer, regAlloc, encoding, 0, 0u); + } + + private static void RewriteBasePlusOffsetMemoryInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, uint encoding) + { + RewriteMemoryInstruction(asBits, mmType, writer, regAlloc, encoding, ExtractSImm9(encoding), 0x1ffu << 12); + } + + private static void RewriteMemoryInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, uint encoding, int imm, uint immMask) + { + int tempRegister = regAlloc.AllocateTempGprRegister(); + Operand rn = new(tempRegister, RegisterType.Integer, OperandType.I64); + Operand guestAddress = new(RegisterUtils.ExtractRn(encoding), RegisterType.Integer, OperandType.I64); + + Assembler asm = new(writer); + + bool canFoldOffset = CanFoldOffset(mmType, imm); + if (canFoldOffset) + { + imm = 0; + } + + WriteAddressTranslation(asBits, mmType, regAlloc, ref asm, rn, guestAddress, imm); + + encoding = RegisterUtils.ReplaceRn(encoding, tempRegister); + + if (!canFoldOffset) + { + encoding &= ~immMask; // Clear offset + } + + writer.WriteInstruction(encoding); + + regAlloc.FreeTempGprRegister(tempRegister); + } + + private static void RewriteLiteralMemoryInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, InstName name, ulong pc, uint encoding) + { + Assembler asm = new(writer); + + ulong targetAddress; + long imm; + int rtIndex = (int)(encoding & 0x1f); + + if (rtIndex == RegisterUtils.ZrIndex && name != InstName.PrfmLit) + { + return; + } + + Operand rt; + + if (name == InstName.LdrLitFpsimd) + { + uint opc = encoding >> 30; + + // TODO: Undefined if opc is invalid? + + rt = new(rtIndex, RegisterType.Vector, opc switch + { + 0 => OperandType.FP32, + 1 => OperandType.FP64, + _ => OperandType.V128, + }); + } + else + { + rt = new(rtIndex, RegisterType.Integer, OperandType.I64); + } + + switch (name) + { + case InstName.Adr: + case InstName.Adrp: + imm = ((long)(encoding >> 29) & 3) | ((long)(encoding >> 3) & 0x1ffffc); + imm <<= 43; + + if (name == InstName.Adrp) + { + imm >>= 31; + targetAddress = (pc & ~0xfffUL) + (ulong)imm; + } + else + { + imm >>= 43; + targetAddress = pc + (ulong)imm; + } + + asm.Mov(rt, targetAddress); + break; + case InstName.LdrLitGen: + case InstName.LdrswLit: + case InstName.LdrLitFpsimd: + case InstName.PrfmLit: + imm = encoding & ~0x1fu; + imm <<= 40; + imm >>= 43; + targetAddress = pc + (ulong)imm; + + int tempRegister = regAlloc.AllocateTempGprRegister(); + Operand rn = new(tempRegister, RegisterType.Integer, OperandType.I64); + + WriteAddressTranslation(asBits, mmType, regAlloc, ref asm, rn, targetAddress); + + switch (name) + { + case InstName.LdrLitGen: + case InstName.LdrLitFpsimd: + asm.LdrRiUn(rt, rn, 0); + break; + case InstName.LdrswLit: + asm.LdrswRiUn(rt, rn, 0); + break; + case InstName.PrfmLit: + asm.PrfmR(rt, rn); + break; + } + + regAlloc.FreeTempGprRegister(tempRegister); + break; + default: + Debug.Fail($"Invalid literal memory instruction '{name}'."); + break; + } + } + + private static void RewriteStructPostIndexedRegMemoryInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, uint encoding) + { + // TODO: Some unallocated encoding cases. + + int tempRegister = regAlloc.AllocateTempGprRegister(); + Operand rn = new(tempRegister, RegisterType.Integer, OperandType.I64); + Operand guestAddress = new(RegisterUtils.ExtractRn(encoding), RegisterType.Integer, OperandType.I64); + + int rmIndex = RegisterUtils.ExtractRm(encoding); + + Assembler asm = new(writer); + + WriteAddressTranslation(asBits, mmType, regAlloc, ref asm, rn, guestAddress); + + encoding = RegisterUtils.ReplaceRn(encoding, tempRegister); + encoding &= ~((0x1fu << 16) | (1u << 23)); // Post-index -> No offset + + writer.WriteInstruction(encoding); + + if (rmIndex == RegisterUtils.ZrIndex) + { + bool isSingleStruct = (encoding & (1u << 24)) != 0; + int offset; + + if (isSingleStruct) + { + int sElems = (int)(((encoding >> 12) & 2u) | ((encoding >> 21) & 1u)) + 1; + + int size = (int)(encoding >> 10) & 3; + int s = (int)(encoding >> 12) & 1; + int scale = (int)(encoding >> 14) & 3; + int l = (int)(encoding >> 22) & 1; + + switch (scale) + { + case 1: + if ((size & 1) != 0) + { + // Undef. + } + + break; + + case 2: + if ((size & 2) != 0 || + ((size & 1) != 0 && s != 0)) + { + // Undef. + } + + if ((size & 1) != 0) + { + scale = 3; + } + + break; + + case 3: + if (l == 0 || s != 0) + { + // Undef. + } + + scale = size; + + break; + } + + int eBytes = 1 << scale; + + offset = eBytes * sElems; + } + else + { + int reps; + int sElems; + + switch ((encoding >> 12) & 0xf) + { + case 0b0000: + reps = 1; + sElems = 4; + break; + case 0b0010: + reps = 4; + sElems = 1; + break; + case 0b0100: + reps = 1; + sElems = 3; + break; + case 0b0110: + reps = 3; + sElems = 1; + break; + case 0b0111: + reps = 1; + sElems = 1; + break; + case 0b1000: + reps = 1; + sElems = 2; + break; + case 0b1010: + reps = 2; + sElems = 1; + break; + + default: + // Undef. + reps = 0; + sElems = 0; + break; + } + + int size = (int)(encoding >> 10) & 3; + bool q = (encoding & (1u << 30)) != 0; + + if (!q && size == 3 && sElems != 1) + { + // Undef. + } + + offset = reps * (q ? 16 : 8) * sElems; + } + + asm.Add(guestAddress, guestAddress, new Operand(OperandKind.Constant, OperandType.I32, (ulong)offset)); + } + else + { + Operand guestOffset = new(rmIndex, RegisterType.Integer, OperandType.I64); + + asm.Add(guestAddress, guestAddress, guestOffset); + } + + regAlloc.FreeTempGprRegister(tempRegister); + } + + private static void WriteAddressTranslation( + int asBits, + MemoryManagerType mmType, + RegisterAllocator regAlloc, + ref Assembler asm, + Operand destination, + Operand guestAddress, + int offset) + { + if (offset != 0) + { + // They are assumed to be on different registers, otherwise this operation will thrash the address. + Debug.Assert(destination.Value != guestAddress.Value); + + if (Math.Abs(offset) >= 0x1000) + { + // Too high to encode as 12-bit immediate, do a separate move. + asm.Mov(destination, (ulong)offset); + asm.Add(destination, destination, guestAddress); + } + else + { + // Encode as 12-bit immediate. + WriteAddConstant(ref asm, destination, guestAddress, offset); + } + + guestAddress = destination; + } + + WriteAddressTranslation(asBits, mmType, regAlloc, ref asm, destination, guestAddress); + } + + private static void WriteAddressTranslation(int asBits, MemoryManagerType mmType, RegisterAllocator regAlloc, ref Assembler asm, Operand destination, ulong guestAddress) + { + asm.Mov(destination, guestAddress); + + WriteAddressTranslation(asBits, mmType, regAlloc, ref asm, destination, destination); + } + + private static void WriteAddressTranslation(int asBits, MemoryManagerType mmType, RegisterAllocator regAlloc, ref Assembler asm, Operand destination, Operand guestAddress) + { + Operand basePointer = new(regAlloc.FixedPageTableRegister, RegisterType.Integer, OperandType.I64); + + if (mmType == MemoryManagerType.HostMapped || mmType == MemoryManagerType.HostMappedUnsafe) + { + if (mmType == MemoryManagerType.HostMapped) + { + asm.And(destination, guestAddress, new Operand(OperandKind.Constant, OperandType.I64, ulong.MaxValue >> (64 - asBits))); + guestAddress = destination; + } + + asm.Add(destination, basePointer, guestAddress); + } + else + { + throw new NotImplementedException(mmType.ToString()); + } + } + + private static void WriteAddConstant(ref Assembler asm, Operand rd, Operand rn, int value) + { + if (value < 0) + { + asm.Sub(rd, rn, new Operand(OperandKind.Constant, OperandType.I32, (ulong)-value)); + } + else + { + asm.Add(rd, rn, new Operand(OperandKind.Constant, OperandType.I32, (ulong)value)); + } + } + + private static bool CanFoldOffset(MemoryManagerType mmType, int offset) + { + return mmType == MemoryManagerType.HostMappedUnsafe; + } + + private static int ExtractSImm7Scaled(InstFlags flags, uint encoding) + { + uint opc = flags.HasFlag(InstFlags.FpSimd) ? encoding >> 30 : encoding >> 31; + return ExtractSImm7(encoding) << (int)(2 + opc); + } + + private static int ExtractSImm7(uint encoding) + { + int imm = (int)(encoding >> 15); + + imm <<= 25; + imm >>= 25; + + return imm; + } + + private static int ExtractSImm9(uint encoding) + { + int imm = (int)(encoding >> 12); + + imm <<= 23; + imm >>= 23; + + return imm; + } + + private static int ExtractUImm12Scaled(InstFlags flags, uint encoding) + { + uint size = encoding >> 30; + + if (flags.HasFlag(InstFlags.FpSimd)) + { + size |= (encoding >> 21) & 4u; + } + + return ExtractUImm12(encoding) << (int)size; + } + + private static int ExtractUImm12(uint encoding) + { + return (int)(encoding >> 10) & 0xfff; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitSystem.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitSystem.cs new file mode 100644 index 000000000..3d4204fc1 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitSystem.cs @@ -0,0 +1,610 @@ +using ARMeilleure.Common; +using Ryujinx.Cpu.LightningJit.CodeGen; +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; +using System; +using System.Diagnostics; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64 +{ + static class InstEmitSystem + { + private delegate void SoftwareInterruptHandler(ulong address, int imm); + private delegate ulong Get64(); + private delegate bool GetBool(); + + public static void RewriteInstruction( + CodeWriter writer, + RegisterAllocator regAlloc, + TailMerger tailMerger, + InstName name, + ulong pc, + uint encoding, + int spillBaseOffset) + { + if (name == InstName.Brk) + { + Assembler asm = new(writer); + + WriteCall(ref asm, regAlloc, GetBrkHandlerPtr(), spillBaseOffset, null, pc, encoding); + WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, spillBaseOffset); + } + else if (name == InstName.Svc) + { + uint svcId = (ushort)(encoding >> 5); + + Assembler asm = new(writer); + + WriteCall(ref asm, regAlloc, GetSvcHandlerPtr(), spillBaseOffset, null, pc, svcId); + WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, spillBaseOffset); + } + else if (name == InstName.UdfPermUndef) + { + Assembler asm = new(writer); + + WriteCall(ref asm, regAlloc, GetUdfHandlerPtr(), spillBaseOffset, null, pc, encoding); + WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, spillBaseOffset); + } + else if ((encoding & ~0x1f) == 0xd53bd060) // mrs x0, tpidrro_el0 + { + uint rd = encoding & 0x1f; + + if (rd != RegisterUtils.ZrIndex) + { + Assembler asm = new(writer); + + asm.LdrRiUn(Register((int)rd), Register(regAlloc.FixedContextRegister), NativeContextOffsets.TpidrroEl0Offset); + } + } + else if ((encoding & ~0x1f) == 0xd53bd040) // mrs x0, tpidr_el0 + { + uint rd = encoding & 0x1f; + + if (rd != RegisterUtils.ZrIndex) + { + Assembler asm = new(writer); + + asm.LdrRiUn(Register((int)rd), Register(regAlloc.FixedContextRegister), NativeContextOffsets.TpidrEl0Offset); + } + } + else if ((encoding & ~0x1f) == 0xd53b0020 && IsAppleOS()) // mrs x0, ctr_el0 + { + uint rd = encoding & 0x1f; + + if (rd != RegisterUtils.ZrIndex) + { + Assembler asm = new(writer); + + // TODO: Use host value? But that register can't be accessed on macOS... + asm.Mov(Register((int)rd, OperandType.I32), 0x8444c004); + } + } + else if ((encoding & ~0x1f) == 0xd53be020) // mrs x0, cntpct_el0 + { + uint rd = encoding & 0x1f; + + if (rd != RegisterUtils.ZrIndex) + { + Assembler asm = new(writer); + + WriteCall(ref asm, regAlloc, GetCntpctEl0Ptr(), spillBaseOffset, (int)rd); + } + } + else if ((encoding & ~0x1f) == 0xd51bd040) // msr tpidr_el0, x0 + { + uint rd = encoding & 0x1f; + + if (rd != RegisterUtils.ZrIndex) + { + Assembler asm = new(writer); + + asm.StrRiUn(Register((int)rd), Register(regAlloc.FixedContextRegister), NativeContextOffsets.TpidrEl0Offset); + } + } + else + { + writer.WriteInstruction(encoding); + } + } + + public static bool NeedsCall(uint encoding) + { + if ((encoding & ~(0xffffu << 5)) == 0xd4000001u) // svc #0 + { + return true; + } + else if ((encoding & ~0x1f) == 0xd53b0020 && IsAppleOS()) // mrs x0, ctr_el0 + { + return true; + } + else if ((encoding & ~0x1f) == 0xd53be020) // mrs x0, cntpct_el0 + { + return true; + } + + return false; + } + + private static bool IsAppleOS() + { + return OperatingSystem.IsMacOS() || OperatingSystem.IsIOS(); + } + + public static bool NeedsContextStoreLoad(InstName name) + { + return name == InstName.Svc; + } + + private static IntPtr GetBrkHandlerPtr() + { + return Marshal.GetFunctionPointerForDelegate(NativeInterface.Break); + } + + private static IntPtr GetSvcHandlerPtr() + { + return Marshal.GetFunctionPointerForDelegate(NativeInterface.SupervisorCall); + } + + private static IntPtr GetUdfHandlerPtr() + { + return Marshal.GetFunctionPointerForDelegate(NativeInterface.Undefined); + } + + private static IntPtr GetCntpctEl0Ptr() + { + return Marshal.GetFunctionPointerForDelegate(NativeInterface.GetCntpctEl0); + } + + private static IntPtr CheckSynchronizationPtr() + { + return Marshal.GetFunctionPointerForDelegate(NativeInterface.CheckSynchronization); + } + + public static void WriteSyncPoint(CodeWriter writer, RegisterAllocator regAlloc, TailMerger tailMerger, int spillBaseOffset) + { + Assembler asm = new(writer); + + WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, spillBaseOffset); + } + + private static void WriteSyncPoint(CodeWriter writer, ref Assembler asm, RegisterAllocator regAlloc, TailMerger tailMerger, int spillBaseOffset) + { + int tempRegister = regAlloc.AllocateTempGprRegister(); + + Operand rt = Register(tempRegister, OperandType.I32); + + asm.LdrRiUn(rt, Register(regAlloc.FixedContextRegister), NativeContextOffsets.CounterOffset); + + int branchIndex = writer.InstructionPointer; + asm.Cbnz(rt, 0); + + WriteSpill(ref asm, regAlloc, 1u << tempRegister, spillBaseOffset, tempRegister); + + Operand rn = Register(tempRegister == 0 ? 1 : 0); + + asm.Mov(rn, (ulong)CheckSynchronizationPtr()); + asm.Blr(rn); + + tailMerger.AddConditionalZeroReturn(writer, asm, Register(0, OperandType.I32)); + + WriteFill(ref asm, regAlloc, 1u << tempRegister, spillBaseOffset, tempRegister); + + asm.LdrRiUn(rt, Register(regAlloc.FixedContextRegister), NativeContextOffsets.CounterOffset); + + uint branchInst = writer.ReadInstructionAt(branchIndex); + writer.WriteInstructionAt(branchIndex, branchInst | (((uint)(writer.InstructionPointer - branchIndex) & 0x7ffff) << 5)); + + asm.Sub(rt, rt, new Operand(OperandKind.Constant, OperandType.I32, 1)); + asm.StrRiUn(rt, Register(regAlloc.FixedContextRegister), NativeContextOffsets.CounterOffset); + + regAlloc.FreeTempGprRegister(tempRegister); + } + + public static void RewriteCallInstruction( + CodeWriter writer, + RegisterAllocator regAlloc, + TailMerger tailMerger, + Action writeEpilogue, + AddressTable funcTable, + IntPtr dispatchStubPtr, + InstName name, + ulong pc, + uint encoding, + int spillBaseOffset, + bool isTail = false) + { + Assembler asm = new(writer); + + switch (name) + { + case InstName.BUncond: + case InstName.Bl: + case InstName.Blr: + case InstName.Br: + if (name == InstName.BUncond || name == InstName.Bl) + { + int imm = ImmUtils.ExtractSImm26Times4(encoding); + + WriteCallWithGuestAddress( + writer, + ref asm, + regAlloc, + tailMerger, + writeEpilogue, + funcTable, + dispatchStubPtr, + spillBaseOffset, + pc, + new(OperandKind.Constant, OperandType.I64, pc + (ulong)imm), + isTail); + } + else + { + int rnIndex = RegisterUtils.ExtractRn(encoding); + if (rnIndex == RegisterUtils.ZrIndex) + { + WriteCallWithGuestAddress( + writer, + ref asm, + regAlloc, + tailMerger, + writeEpilogue, + funcTable, + dispatchStubPtr, + spillBaseOffset, + pc, + new(OperandKind.Constant, OperandType.I64, 0UL), + isTail); + } + else + { + rnIndex = regAlloc.RemapReservedGprRegister(rnIndex); + + WriteCallWithGuestAddress( + writer, + ref asm, + regAlloc, + tailMerger, + writeEpilogue, + funcTable, + dispatchStubPtr, + spillBaseOffset, + pc, + Register(rnIndex), + isTail); + } + } + break; + + default: + Debug.Fail($"Unknown branch instruction \"{name}\"."); + break; + } + } + + public unsafe static void WriteCallWithGuestAddress( + CodeWriter writer, + ref Assembler asm, + RegisterAllocator regAlloc, + TailMerger tailMerger, + Action writeEpilogue, + AddressTable funcTable, + IntPtr funcPtr, + int spillBaseOffset, + ulong pc, + Operand guestAddress, + bool isTail = false) + { + int tempRegister; + + if (guestAddress.Kind == OperandKind.Constant) + { + tempRegister = regAlloc.AllocateTempGprRegister(); + + asm.Mov(Register(tempRegister), guestAddress.Value); + asm.StrRiUn(Register(tempRegister), Register(regAlloc.FixedContextRegister), NativeContextOffsets.DispatchAddressOffset); + + regAlloc.FreeTempGprRegister(tempRegister); + } + else + { + asm.StrRiUn(guestAddress, Register(regAlloc.FixedContextRegister), NativeContextOffsets.DispatchAddressOffset); + } + + tempRegister = regAlloc.FixedContextRegister == 1 ? 2 : 1; + + if (!isTail) + { + WriteSpillSkipContext(ref asm, regAlloc, spillBaseOffset); + } + + Operand rn = Register(tempRegister); + + if (regAlloc.FixedContextRegister != 0) + { + asm.Mov(Register(0), Register(regAlloc.FixedContextRegister)); + } + + if (guestAddress.Kind == OperandKind.Constant && funcTable != null) + { + ulong funcPtrLoc = (ulong)Unsafe.AsPointer(ref funcTable.GetValue(guestAddress.Value)); + + asm.Mov(rn, funcPtrLoc & ~0xfffUL); + asm.LdrRiUn(rn, rn, (int)(funcPtrLoc & 0xfffUL)); + } + else + { + asm.Mov(rn, (ulong)funcPtr); + } + + if (isTail) + { + writeEpilogue(); + asm.Br(rn); + } + else + { + asm.Blr(rn); + + ulong nextAddress = pc + 4UL; + + asm.Mov(rn, nextAddress); + asm.Cmp(Register(0), rn); + + tailMerger.AddConditionalReturn(writer, asm, ArmCondition.Ne); + + WriteFillSkipContext(ref asm, regAlloc, spillBaseOffset); + } + } + + private static void WriteCall( + ref Assembler asm, + RegisterAllocator regAlloc, + IntPtr funcPtr, + int spillBaseOffset, + int? resultRegister, + params ulong[] callArgs) + { + uint resultMask = 0u; + + if (resultRegister.HasValue) + { + resultMask = 1u << resultRegister.Value; + } + + int tempRegister = callArgs.Length; + + if (resultRegister.HasValue && tempRegister == resultRegister.Value) + { + tempRegister++; + } + + WriteSpill(ref asm, regAlloc, resultMask, spillBaseOffset, tempRegister); + + // We only support up to 7 arguments right now. + // ABI defines the first 8 integer arguments to be passed on registers X0-X7. + // We need at least one register to put the function address on, so that reduces the number of + // registers we can use for that by one. + + Debug.Assert(callArgs.Length < 8); + + for (int index = 0; index < callArgs.Length; index++) + { + asm.Mov(Register(index), callArgs[index]); + } + + Operand rn = Register(tempRegister); + + asm.Mov(rn, (ulong)funcPtr); + asm.Blr(rn); + + if (resultRegister.HasValue && resultRegister.Value != 0) + { + asm.Mov(Register(resultRegister.Value), Register(0)); + } + + WriteFill(ref asm, regAlloc, resultMask, spillBaseOffset, tempRegister); + } + + private static void WriteSpill(ref Assembler asm, RegisterAllocator regAlloc, uint exceptMask, int spillOffset, int tempRegister) + { + WriteSpillOrFill(ref asm, regAlloc, exceptMask, spillOffset, tempRegister, spill: true); + } + + private static void WriteFill(ref Assembler asm, RegisterAllocator regAlloc, uint exceptMask, int spillOffset, int tempRegister) + { + WriteSpillOrFill(ref asm, regAlloc, exceptMask, spillOffset, tempRegister, spill: false); + } + + private static void WriteSpillOrFill( + ref Assembler asm, + RegisterAllocator regAlloc, + uint exceptMask, + int spillOffset, + int tempRegister, + bool spill) + { + uint gprMask = regAlloc.AllGprMask & ~(AbiConstants.GprCalleeSavedRegsMask | exceptMask); + + if (regAlloc.AllPStateMask != 0 && !spill) + { + // We must reload the status register before reloading the GPRs, + // since we might otherwise trash one of them by using it as temp register. + + Operand rt = Register(tempRegister, OperandType.I32); + + asm.LdrRiUn(rt, Register(RegisterUtils.SpIndex), spillOffset + BitOperations.PopCount(gprMask) * 8); + asm.MsrNzcv(rt); + } + + while (gprMask != 0) + { + int reg = BitOperations.TrailingZeroCount(gprMask); + + if (reg < 31 && (gprMask & (2u << reg)) != 0 && spillOffset < RegisterSaveRestore.Encodable9BitsOffsetLimit) + { + if (spill) + { + asm.StpRiUn( + Register(regAlloc.RemapReservedGprRegister(reg)), + Register(regAlloc.RemapReservedGprRegister(reg + 1)), + Register(RegisterUtils.SpIndex), + spillOffset); + } + else + { + asm.LdpRiUn( + Register(regAlloc.RemapReservedGprRegister(reg)), + Register(regAlloc.RemapReservedGprRegister(reg + 1)), + Register(RegisterUtils.SpIndex), + spillOffset); + } + + gprMask &= ~(3u << reg); + spillOffset += 16; + } + else + { + if (spill) + { + asm.StrRiUn(Register(regAlloc.RemapReservedGprRegister(reg)), Register(RegisterUtils.SpIndex), spillOffset); + } + else + { + asm.LdrRiUn(Register(regAlloc.RemapReservedGprRegister(reg)), Register(RegisterUtils.SpIndex), spillOffset); + } + + gprMask &= ~(1u << reg); + spillOffset += 8; + } + } + + if (regAlloc.AllPStateMask != 0) + { + if (spill) + { + Operand rt = Register(tempRegister, OperandType.I32); + + asm.MrsNzcv(rt); + asm.StrRiUn(rt, Register(RegisterUtils.SpIndex), spillOffset); + } + + spillOffset += 8; + } + + if ((spillOffset & 8) != 0) + { + spillOffset += 8; + } + + uint fpSimdMask = regAlloc.AllFpSimdMask; + + while (fpSimdMask != 0) + { + int reg = BitOperations.TrailingZeroCount(fpSimdMask); + + if (reg < 31 && (fpSimdMask & (2u << reg)) != 0 && spillOffset < RegisterSaveRestore.Encodable9BitsOffsetLimit) + { + if (spill) + { + asm.StpRiUn( + Register(reg, OperandType.V128), + Register(reg + 1, OperandType.V128), + Register(RegisterUtils.SpIndex), + spillOffset); + } + else + { + asm.LdpRiUn( + Register(reg, OperandType.V128), + Register(reg + 1, OperandType.V128), + Register(RegisterUtils.SpIndex), + spillOffset); + } + + fpSimdMask &= ~(3u << reg); + spillOffset += 32; + } + else + { + if (spill) + { + asm.StrRiUn(Register(reg, OperandType.V128), Register(RegisterUtils.SpIndex), spillOffset); + } + else + { + asm.LdrRiUn(Register(reg, OperandType.V128), Register(RegisterUtils.SpIndex), spillOffset); + } + + fpSimdMask &= ~(1u << reg); + spillOffset += 16; + } + } + } + + private static void WriteSpillSkipContext(ref Assembler asm, RegisterAllocator regAlloc, int spillOffset) + { + WriteSpillOrFillSkipContext(ref asm, regAlloc, spillOffset, spill: true); + } + + private static void WriteFillSkipContext(ref Assembler asm, RegisterAllocator regAlloc, int spillOffset) + { + WriteSpillOrFillSkipContext(ref asm, regAlloc, spillOffset, spill: false); + } + + private static void WriteSpillOrFillSkipContext(ref Assembler asm, RegisterAllocator regAlloc, int spillOffset, bool spill) + { + uint gprMask = regAlloc.AllGprMask & ((1u << regAlloc.FixedContextRegister) | (1u << regAlloc.FixedPageTableRegister)); + gprMask &= ~AbiConstants.GprCalleeSavedRegsMask; + + while (gprMask != 0) + { + int reg = BitOperations.TrailingZeroCount(gprMask); + + if (reg < 31 && (gprMask & (2u << reg)) != 0 && spillOffset < RegisterSaveRestore.Encodable9BitsOffsetLimit) + { + if (spill) + { + asm.StpRiUn( + Register(regAlloc.RemapReservedGprRegister(reg)), + Register(regAlloc.RemapReservedGprRegister(reg + 1)), + Register(RegisterUtils.SpIndex), + spillOffset); + } + else + { + asm.LdpRiUn( + Register(regAlloc.RemapReservedGprRegister(reg)), + Register(regAlloc.RemapReservedGprRegister(reg + 1)), + Register(RegisterUtils.SpIndex), + spillOffset); + } + + gprMask &= ~(3u << reg); + spillOffset += 16; + } + else + { + if (spill) + { + asm.StrRiUn(Register(regAlloc.RemapReservedGprRegister(reg)), Register(RegisterUtils.SpIndex), spillOffset); + } + else + { + asm.LdrRiUn(Register(regAlloc.RemapReservedGprRegister(reg)), Register(RegisterUtils.SpIndex), spillOffset); + } + + gprMask &= ~(1u << reg); + spillOffset += 8; + } + } + } + + private static Operand Register(int register, OperandType type = OperandType.I64) + { + return new Operand(register, RegisterType.Integer, type); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstTable.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstTable.cs new file mode 100644 index 000000000..88718afb1 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstTable.cs @@ -0,0 +1,1605 @@ +using Ryujinx.Cpu.LightningJit.Table; +using System.Collections.Generic; + +namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64 +{ + static class InstTable + { + private static readonly InstTableLevel _table; + + private readonly struct InstInfo : IInstInfo + { + public uint Encoding { get; } + public uint EncodingMask { get; } + public InstEncoding[] Constraints { get; } + public InstName Name { get; } + public IsaVersion Version { get; } + public IsaFeature Feature { get; } + public InstFlags Flags { get; } + public AddressForm AddressForm { get; } + + public InstInfo( + uint encoding, + uint encodingMask, + InstEncoding[] constraints, + InstName name, + IsaVersion isaVersion, + IsaFeature isaFeature, + InstFlags flags, + AddressForm addressForm = AddressForm.None) + { + if (addressForm != AddressForm.None) + { + flags |= InstFlags.Memory; + } + + Encoding = encoding; + EncodingMask = encodingMask; + Constraints = constraints; + Name = name; + Version = isaVersion; + Feature = isaFeature; + Flags = flags; + AddressForm = addressForm; + } + + public InstInfo( + uint encoding, + uint encodingMask, + InstEncoding[] constraints, + InstName name, + IsaVersion isaVersion, + InstFlags flags, + AddressForm addressForm = AddressForm.None) : this(encoding, encodingMask, constraints, name, isaVersion, IsaFeature.None, flags, addressForm) + { + } + + public InstInfo( + uint encoding, + uint encodingMask, + InstName name, + IsaVersion isaVersion, + IsaFeature isaFeature, + InstFlags flags, + AddressForm addressForm = AddressForm.None) : this(encoding, encodingMask, null, name, isaVersion, isaFeature, flags, addressForm) + { + } + + public InstInfo( + uint encoding, + uint encodingMask, + InstName name, + IsaVersion isaVersion, + InstFlags flags, + AddressForm addressForm = AddressForm.None) : this(encoding, encodingMask, null, name, isaVersion, IsaFeature.None, flags, addressForm) + { + } + + public bool IsConstrained(uint encoding) + { + if (Constraints != null) + { + foreach (InstEncoding constraint in Constraints) + { + if ((encoding & constraint.EncodingMask) == constraint.Encoding) + { + return true; + } + } + } + + return false; + } + } + + static InstTable() + { + InstEncoding[] qsizeConstraints = new InstEncoding[] + { + new(0x00C00000, 0x40C00000), + }; + + InstEncoding[] sizeConstraints = new InstEncoding[] + { + new(0x00C00000, 0x00C00000), + }; + + InstEncoding[] opuOpuOpuConstraints = new InstEncoding[] + { + new(0x00001400, 0x00001C00), + new(0x00001800, 0x00001C00), + new(0x00001C00, 0x00001C00), + }; + + InstEncoding[] shiftSfimm6Constraints = new InstEncoding[] + { + new(0x00C00000, 0x00C00000), + new(0x00008000, 0x80008000), + }; + + InstEncoding[] qsizeSizeConstraints = new InstEncoding[] + { + new(0x00800000, 0x40C00000), + new(0x00C00000, 0x00C00000), + }; + + InstEncoding[] nimmsNimmsNimmsNimmsNimmsNimmsNimmsNimmsSfnConstraints = new InstEncoding[] + { + new(0x0040FC00, 0x0040FC00), + new(0x00007C00, 0x0040FC00), + new(0x0000BC00, 0x0040FC00), + new(0x0000DC00, 0x0040FC00), + new(0x0000EC00, 0x0040FC00), + new(0x0000F400, 0x0040FC00), + new(0x0000F800, 0x0040FC00), + new(0x0000FC00, 0x0040FC00), + new(0x00400000, 0x80400000), + }; + + InstEncoding[] sfimm6Constraints = new InstEncoding[] + { + new(0x00008000, 0x80008000), + }; + + InstEncoding[] sfnSfnSfimmr5Sfimms5Constraints = new InstEncoding[] + { + new(0x80000000, 0x80400000), + new(0x00400000, 0x80400000), + new(0x00200000, 0x80200000), + new(0x00008000, 0x80008000), + }; + + InstEncoding[] cmodeopqConstraints = new InstEncoding[] + { + new(0x2000F000, 0x6000F000), + }; + + InstEncoding[] rsRtConstraints = new InstEncoding[] + { + new(0x00010000, 0x00010000), + new(0x00000001, 0x00000001), + }; + + InstEncoding[] sfszSfszSfszSfszConstraints = new InstEncoding[] + { + new(0x80000000, 0x80000C00), + new(0x80000400, 0x80000C00), + new(0x80000800, 0x80000C00), + new(0x00000C00, 0x80000C00), + }; + + InstEncoding[] imm5Constraints = new InstEncoding[] + { + new(0x00000000, 0x000F0000), + }; + + InstEncoding[] imm5Imm5qConstraints = new InstEncoding[] + { + new(0x00000000, 0x000F0000), + new(0x00080000, 0x400F0000), + }; + + InstEncoding[] nsfNsfSfimmsConstraints = new InstEncoding[] + { + new(0x00400000, 0x80400000), + new(0x80000000, 0x80400000), + new(0x00008000, 0x80008000), + }; + + InstEncoding[] qimm4Constraints = new InstEncoding[] + { + new(0x00004000, 0x40004000), + }; + + InstEncoding[] qszConstraints = new InstEncoding[] + { + new(0x00400000, 0x40400000), + }; + + InstEncoding[] euacEuacEuacConstraints = new InstEncoding[] + { + new(0x00000800, 0x20800800), + new(0x00800000, 0x20800800), + new(0x00800800, 0x20800800), + }; + + InstEncoding[] qszEuacEuacEuacConstraints = new InstEncoding[] + { + new(0x00400000, 0x40400000), + new(0x00000800, 0x20800800), + new(0x00800000, 0x20800800), + new(0x00800800, 0x20800800), + }; + + InstEncoding[] szConstraints = new InstEncoding[] + { + new(0x00400000, 0x00400000), + }; + + InstEncoding[] sizeQsizeConstraints = new InstEncoding[] + { + new(0x00000000, 0x00C00000), + new(0x00C00000, 0x40C00000), + }; + + InstEncoding[] sizeSizeSizelSizeqSizehqConstraints = new InstEncoding[] + { + new(0x00000000, 0x00C00000), + new(0x00C00000, 0x00C00000), + new(0x00A00000, 0x00E00000), + new(0x00800000, 0x40C00000), + new(0x00400800, 0x40C00800), + }; + + InstEncoding[] szConstraints2 = new InstEncoding[] + { + new(0x00000000, 0x00400000), + }; + + InstEncoding[] immhConstraints = new InstEncoding[] + { + new(0x00000000, 0x00780000), + }; + + InstEncoding[] immhQimmhConstraints = new InstEncoding[] + { + new(0x00000000, 0x00780000), + new(0x00400000, 0x40400000), + }; + + InstEncoding[] sfscaleConstraints = new InstEncoding[] + { + new(0x00000000, 0x80008000), + }; + + InstEncoding[] ftypeopcFtypeopcFtypeopcFtypeopcFtypeOpcConstraints = new InstEncoding[] + { + new(0x00000000, 0x00C18000), + new(0x00408000, 0x00C18000), + new(0x00810000, 0x00C18000), + new(0x00C18000, 0x00C18000), + new(0x00800000, 0x00C00000), + new(0x00010000, 0x00018000), + }; + + InstEncoding[] szlConstraints = new InstEncoding[] + { + new(0x00600000, 0x00600000), + }; + + InstEncoding[] szlQszConstraints = new InstEncoding[] + { + new(0x00600000, 0x00600000), + new(0x00400000, 0x40400000), + }; + + InstEncoding[] qConstraints = new InstEncoding[] + { + new(0x00000000, 0x40000000), + }; + + InstEncoding[] sfftypermodeSfftypermodeConstraints = new InstEncoding[] + { + new(0x00400000, 0x80C80000), + new(0x80000000, 0x80C80000), + }; + + InstEncoding[] uo1o2Constraints = new InstEncoding[] + { + new(0x20800000, 0x20801000), + }; + + InstEncoding[] qszUo1o2Constraints = new InstEncoding[] + { + new(0x00400000, 0x40400000), + new(0x20800000, 0x20801000), + }; + + InstEncoding[] sConstraints = new InstEncoding[] + { + new(0x00001000, 0x00001000), + }; + + InstEncoding[] opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints = new InstEncoding[] + { + new(0x00004400, 0x0000C400), + new(0x00008800, 0x0000C800), + new(0x00009400, 0x0000D400), + new(0x0000C000, 0x0000C000), + }; + + InstEncoding[] qsizeConstraints2 = new InstEncoding[] + { + new(0x00000C00, 0x40000C00), + }; + + InstEncoding[] rtRtConstraints = new InstEncoding[] + { + new(0x00000018, 0x00000018), + new(0x00000001, 0x00000001), + }; + + InstEncoding[] opc1sizeOpc1sizeOpc1sizeConstraints = new InstEncoding[] + { + new(0x40800000, 0xC0800000), + new(0x80800000, 0xC0800000), + new(0xC0800000, 0xC0800000), + }; + + InstEncoding[] rtRt2Constraints = new InstEncoding[] + { + new(0x0000001F, 0x0000001F), + new(0x001F0000, 0x001F0000), + }; + + InstEncoding[] opcConstraints = new InstEncoding[] + { + new(0xC0000000, 0xC0000000), + }; + + InstEncoding[] opcConstraints2 = new InstEncoding[] + { + new(0x40000000, 0x40000000), + }; + + InstEncoding[] opclOpcConstraints = new InstEncoding[] + { + new(0x40000000, 0x40400000), + new(0xC0000000, 0xC0000000), + }; + + InstEncoding[] optionConstraints = new InstEncoding[] + { + new(0x00000000, 0x00004000), + }; + + InstEncoding[] opc1sizeOpc1sizeOpc1sizeOptionConstraints = new InstEncoding[] + { + new(0x40800000, 0xC0800000), + new(0x80800000, 0xC0800000), + new(0xC0800000, 0xC0800000), + new(0x00000000, 0x00004000), + }; + + InstEncoding[] sizeSizeConstraints = new InstEncoding[] + { + new(0x00000000, 0x00C00000), + new(0x00C00000, 0x00C00000), + }; + + InstEncoding[] sfhwConstraints = new InstEncoding[] + { + new(0x00400000, 0x80400000), + }; + + InstEncoding[] rtConstraints = new InstEncoding[] + { + new(0x00000001, 0x00000001), + }; + + InstEncoding[] usizeUsizeUsizeSizeConstraints = new InstEncoding[] + { + new(0x20400000, 0x20C00000), + new(0x20800000, 0x20C00000), + new(0x20C00000, 0x20C00000), + new(0x00C00000, 0x00C00000), + }; + + InstEncoding[] sizeSizeConstraints2 = new InstEncoding[] + { + new(0x00400000, 0x00C00000), + new(0x00800000, 0x00C00000), + }; + + InstEncoding[] rtConstraints2 = new InstEncoding[] + { + new(0x00000018, 0x00000018), + }; + + InstEncoding[] sfopcConstraints = new InstEncoding[] + { + new(0x00000400, 0x80000400), + }; + + InstEncoding[] sizeSizeSizeConstraints = new InstEncoding[] + { + new(0x00400000, 0x00C00000), + new(0x00800000, 0x00C00000), + new(0x00C00000, 0x00C00000), + }; + + InstEncoding[] sizeSizeConstraints3 = new InstEncoding[] + { + new(0x00800000, 0x00C00000), + new(0x00C00000, 0x00C00000), + }; + + InstEncoding[] sfConstraints = new InstEncoding[] + { + new(0x00000000, 0x80000000), + }; + + InstEncoding[] immhImmhConstraints = new InstEncoding[] + { + new(0x00000000, 0x00780000), + new(0x00400000, 0x00400000), + }; + + InstEncoding[] sizeSizeConstraints4 = new InstEncoding[] + { + new(0x00C00000, 0x00C00000), + new(0x00000000, 0x00C00000), + }; + + InstEncoding[] ssizeSsizeSsizeConstraints = new InstEncoding[] + { + new(0x00000000, 0x00C00800), + new(0x00400000, 0x00C00800), + new(0x00800000, 0x00C00800), + }; + + InstEncoding[] immhOpuConstraints = new InstEncoding[] + { + new(0x00000000, 0x00780000), + new(0x00000000, 0x20001000), + }; + + InstEncoding[] immhQimmhOpuConstraints = new InstEncoding[] + { + new(0x00000000, 0x00780000), + new(0x00400000, 0x40400000), + new(0x00000000, 0x20001000), + }; + + List insts = new() + { + new(0x5AC02000, 0x7FFFFC00, InstName.Abs, IsaVersion.v89, InstFlags.RdRn), + new(0x5EE0B800, 0xFFFFFC00, InstName.AbsAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0E20B800, 0xBF3FFC00, qsizeConstraints, InstName.AbsAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1A000000, 0x7FE0FC00, InstName.Adc, IsaVersion.v80, InstFlags.RdRnRmC), + new(0x3A000000, 0x7FE0FC00, InstName.Adcs, IsaVersion.v80, InstFlags.RdRnRmCS), + new(0x91800000, 0xFFC0C000, InstName.Addg, IsaVersion.v85, InstFlags.None), + new(0x0E204000, 0xBF20FC00, sizeConstraints, InstName.AddhnAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd), + new(0x5EF1B800, 0xFFFFFC00, InstName.AddpAdvsimdPair, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0E20BC00, 0xBF20FC00, qsizeConstraints, InstName.AddpAdvsimdVec, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2B200000, 0x7FE00000, opuOpuOpuConstraints, InstName.AddsAddsubExt, IsaVersion.v80, InstFlags.RdRnSPRmS), + new(0x31000000, 0x7F800000, InstName.AddsAddsubImm, IsaVersion.v80, InstFlags.RdRnSPS), + new(0x2B000000, 0x7F200000, shiftSfimm6Constraints, InstName.AddsAddsubShift, IsaVersion.v80, InstFlags.RdRnRmS), + new(0x0E31B800, 0xBF3FFC00, qsizeSizeConstraints, InstName.AddvAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0B200000, 0x7FE00000, opuOpuOpuConstraints, InstName.AddAddsubExt, IsaVersion.v80, InstFlags.RdSPRnSPRm), + new(0x11000000, 0x7F800000, InstName.AddAddsubImm, IsaVersion.v80, InstFlags.RdSPRnSP), + new(0x0B000000, 0x7F200000, shiftSfimm6Constraints, InstName.AddAddsubShift, IsaVersion.v80, InstFlags.RdRnRm), + new(0x5EE08400, 0xFFE0FC00, InstName.AddAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E208400, 0xBF20FC00, qsizeConstraints, InstName.AddAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x10000000, 0x9F000000, InstName.Adr, IsaVersion.v80, InstFlags.Rd, AddressForm.Literal), + new(0x90000000, 0x9F000000, InstName.Adrp, IsaVersion.v80, InstFlags.Rd, AddressForm.Literal), + new(0x4E285800, 0xFFFFFC00, InstName.AesdAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x4E284800, 0xFFFFFC00, InstName.AeseAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x4E287800, 0xFFFFFC00, InstName.AesimcAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x4E286800, 0xFFFFFC00, InstName.AesmcAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x72000000, 0x7F800000, nimmsNimmsNimmsNimmsNimmsNimmsNimmsNimmsSfnConstraints, InstName.AndsLogImm, IsaVersion.v80, InstFlags.RdRnS), + new(0x6A000000, 0x7F200000, sfimm6Constraints, InstName.AndsLogShift, IsaVersion.v80, InstFlags.RdRnRmS), + new(0x0E201C00, 0xBFE0FC00, InstName.AndAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x12000000, 0x7F800000, nimmsNimmsNimmsNimmsNimmsNimmsNimmsNimmsSfnConstraints, InstName.AndLogImm, IsaVersion.v80, InstFlags.RdSPRn), + new(0x0A000000, 0x7F200000, sfimm6Constraints, InstName.AndLogShift, IsaVersion.v80, InstFlags.RdRnRm), + new(0x1AC02800, 0x7FE0FC00, InstName.Asrv, IsaVersion.v80, InstFlags.RdRnRm), + new(0xDAC11800, 0xFFFFDC00, InstName.Autda, IsaVersion.v83, InstFlags.RdRnSP), + new(0xDAC11C00, 0xFFFFDC00, InstName.Autdb, IsaVersion.v83, InstFlags.RdRnSP), + new(0xDAC11000, 0xFFFFDC00, InstName.AutiaGeneral, IsaVersion.v83, InstFlags.RdRnSP), + new(0xD503219F, 0xFFFFFDDF, InstName.AutiaSystem, IsaVersion.v83, InstFlags.None), + new(0xDAC11400, 0xFFFFDC00, InstName.AutibGeneral, IsaVersion.v83, InstFlags.RdRnSP), + new(0xD50321DF, 0xFFFFFDDF, InstName.AutibSystem, IsaVersion.v83, InstFlags.None), + new(0xD500405F, 0xFFFFFFFF, InstName.Axflag, IsaVersion.v85, InstFlags.C), + new(0xCE200000, 0xFFE08000, InstName.BcaxAdvsimd, IsaVersion.v82, InstFlags.RdRnRmRaFpSimd), + new(0x54000010, 0xFF000010, InstName.BcCond, IsaVersion.v88, InstFlags.Nzcv), + new(0x0EA16800, 0xBFFFFC00, InstName.BfcvtnAdvsimd, IsaVersion.v86, InstFlags.RdRnFpSimd), + new(0x1E634000, 0xFFFFFC00, InstName.BfcvtFloat, IsaVersion.v86, InstFlags.RdRnFpSimd), + new(0x0F40F000, 0xBFC0F400, InstName.BfdotAdvsimdElt, IsaVersion.v86, InstFlags.RdReadRdRnRmFpSimd), + new(0x2E40FC00, 0xBFE0FC00, InstName.BfdotAdvsimdVec, IsaVersion.v86, InstFlags.RdReadRdRnRmFpSimd), + new(0x33000000, 0x7F800000, sfnSfnSfimmr5Sfimms5Constraints, InstName.Bfm, IsaVersion.v80, InstFlags.RdReadRdRn), + new(0x0FC0F000, 0xBFC0F400, InstName.BfmlalAdvsimdElt, IsaVersion.v86, InstFlags.RdRnRmFpSimd), + new(0x2EC0FC00, 0xBFE0FC00, InstName.BfmlalAdvsimdVec, IsaVersion.v86, InstFlags.RdRnRmFpSimd), + new(0x6E40EC00, 0xFFE0FC00, InstName.BfmmlaAdvsimd, IsaVersion.v86, InstFlags.RdRnRmFpSimd), + new(0x6A200000, 0x7F200000, sfimm6Constraints, InstName.Bics, IsaVersion.v80, InstFlags.RdRnRmS), + new(0x2F001400, 0xBFF81C00, cmodeopqConstraints, InstName.BicAdvsimdImm, IsaVersion.v80, InstFlags.RdFpSimd), + new(0x0E601C00, 0xBFE0FC00, InstName.BicAdvsimdReg, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0A200000, 0x7F200000, sfimm6Constraints, InstName.BicLogShift, IsaVersion.v80, InstFlags.RdRnRm), + new(0x2EE01C00, 0xBFE0FC00, InstName.BifAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd), + new(0x2EA01C00, 0xBFE0FC00, InstName.BitAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd), + new(0x94000000, 0xFC000000, InstName.Bl, IsaVersion.v80, InstFlags.None), + new(0xD63F0000, 0xFFFFFC1F, InstName.Blr, IsaVersion.v80, InstFlags.Rn), + new(0xD63F0800, 0xFEFFF800, InstName.Blra, IsaVersion.v83, InstFlags.RnRm), + new(0xD61F0000, 0xFFFFFC1F, InstName.Br, IsaVersion.v80, InstFlags.Rn), + new(0xD61F0800, 0xFEFFF800, InstName.Bra, IsaVersion.v83, InstFlags.RnRm), + new(0xD4200000, 0xFFE0001F, InstName.Brk, IsaVersion.v80, InstFlags.None), + new(0x2E601C00, 0xBFE0FC00, InstName.BslAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd), + new(0xD503241F, 0xFFFFFF3F, InstName.Bti, IsaVersion.v85, InstFlags.None), + new(0x54000000, 0xFF000010, InstName.BCond, IsaVersion.v80, InstFlags.Nzcv), + new(0x14000000, 0xFC000000, InstName.BUncond, IsaVersion.v80, InstFlags.None), + new(0x88A07C00, 0xBFA07C00, InstName.Cas, IsaVersion.v81, InstFlags.RtReadRtRnSPRs, AddressForm.BaseRegister), + new(0x08A07C00, 0xFFA07C00, InstName.Casb, IsaVersion.v81, InstFlags.RtReadRtRnSPRs, AddressForm.BaseRegister), + new(0x48A07C00, 0xFFA07C00, InstName.Cash, IsaVersion.v81, InstFlags.RtReadRtRnSPRs, AddressForm.BaseRegister), + new(0x08207C00, 0xBFA07C00, rsRtConstraints, InstName.Casp, IsaVersion.v81, InstFlags.RtReadRtRnSPRs, AddressForm.BaseRegister), + new(0x35000000, 0x7F000000, InstName.Cbnz, IsaVersion.v80, InstFlags.RtReadRt), + new(0x34000000, 0x7F000000, InstName.Cbz, IsaVersion.v80, InstFlags.RtReadRt), + new(0x3A400800, 0x7FE00C10, InstName.CcmnImm, IsaVersion.v80, InstFlags.RnNzcvS), + new(0x3A400000, 0x7FE00C10, InstName.CcmnReg, IsaVersion.v80, InstFlags.RnRmNzcvS), + new(0x7A400800, 0x7FE00C10, InstName.CcmpImm, IsaVersion.v80, InstFlags.RnNzcvS), + new(0x7A400000, 0x7FE00C10, InstName.CcmpReg, IsaVersion.v80, InstFlags.RnRmNzcvS), + new(0xD500401F, 0xFFFFFFFF, InstName.Cfinv, IsaVersion.v84, InstFlags.C), + new(0xD503251F, 0xFFFFFFFF, InstName.Chkfeat, IsaVersion.None, InstFlags.None), + new(0xD50322DF, 0xFFFFFFFF, InstName.Clrbhb, IsaVersion.v89, InstFlags.None), + new(0xD503305F, 0xFFFFF0FF, InstName.Clrex, IsaVersion.v80, InstFlags.None), + new(0x0E204800, 0xBF3FFC00, sizeConstraints, InstName.ClsAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5AC01400, 0x7FFFFC00, InstName.ClsInt, IsaVersion.v80, InstFlags.RdRn), + new(0x2E204800, 0xBF3FFC00, sizeConstraints, InstName.ClzAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5AC01000, 0x7FFFFC00, InstName.ClzInt, IsaVersion.v80, InstFlags.RdRn), + new(0x7EE08C00, 0xFFE0FC00, InstName.CmeqAdvsimdRegS, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E208C00, 0xBF20FC00, qsizeConstraints, InstName.CmeqAdvsimdRegV, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5EE09800, 0xFFFFFC00, InstName.CmeqAdvsimdZeroS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0E209800, 0xBF3FFC00, qsizeConstraints, InstName.CmeqAdvsimdZeroV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5EE03C00, 0xFFE0FC00, InstName.CmgeAdvsimdRegS, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E203C00, 0xBF20FC00, qsizeConstraints, InstName.CmgeAdvsimdRegV, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x7EE08800, 0xFFFFFC00, InstName.CmgeAdvsimdZeroS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2E208800, 0xBF3FFC00, qsizeConstraints, InstName.CmgeAdvsimdZeroV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5EE03400, 0xFFE0FC00, InstName.CmgtAdvsimdRegS, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E203400, 0xBF20FC00, qsizeConstraints, InstName.CmgtAdvsimdRegV, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5EE08800, 0xFFFFFC00, InstName.CmgtAdvsimdZeroS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0E208800, 0xBF3FFC00, qsizeConstraints, InstName.CmgtAdvsimdZeroV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x7EE03400, 0xFFE0FC00, InstName.CmhiAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E203400, 0xBF20FC00, qsizeConstraints, InstName.CmhiAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x7EE03C00, 0xFFE0FC00, InstName.CmhsAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E203C00, 0xBF20FC00, qsizeConstraints, InstName.CmhsAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x7EE09800, 0xFFFFFC00, InstName.CmleAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2E209800, 0xBF3FFC00, qsizeConstraints, InstName.CmleAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5EE0A800, 0xFFFFFC00, InstName.CmltAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0E20A800, 0xBF3FFC00, qsizeConstraints, InstName.CmltAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5EE08C00, 0xFFE0FC00, InstName.CmtstAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E208C00, 0xBF20FC00, qsizeConstraints, InstName.CmtstAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5AC01C00, 0x7FFFFC00, InstName.Cnt, IsaVersion.v89, InstFlags.RdRn), + new(0x0E205800, 0xBFFFFC00, InstName.CntAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x19000400, 0x3F20FC00, InstName.Cpyfp, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1900C400, 0x3F20FC00, InstName.Cpyfpn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x19008400, 0x3F20FC00, InstName.Cpyfprn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x19002400, 0x3F20FC00, InstName.Cpyfprt, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1900E400, 0x3F20FC00, InstName.Cpyfprtn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1900A400, 0x3F20FC00, InstName.Cpyfprtrn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x19006400, 0x3F20FC00, InstName.Cpyfprtwn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x19003400, 0x3F20FC00, InstName.Cpyfpt, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1900F400, 0x3F20FC00, InstName.Cpyfptn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1900B400, 0x3F20FC00, InstName.Cpyfptrn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x19007400, 0x3F20FC00, InstName.Cpyfptwn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x19004400, 0x3F20FC00, InstName.Cpyfpwn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x19001400, 0x3F20FC00, InstName.Cpyfpwt, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1900D400, 0x3F20FC00, InstName.Cpyfpwtn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x19009400, 0x3F20FC00, InstName.Cpyfpwtrn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x19005400, 0x3F20FC00, InstName.Cpyfpwtwn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1D000400, 0x3F20FC00, InstName.Cpyp, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1D00C400, 0x3F20FC00, InstName.Cpypn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1D008400, 0x3F20FC00, InstName.Cpyprn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1D002400, 0x3F20FC00, InstName.Cpyprt, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1D00E400, 0x3F20FC00, InstName.Cpyprtn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1D00A400, 0x3F20FC00, InstName.Cpyprtrn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1D006400, 0x3F20FC00, InstName.Cpyprtwn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1D003400, 0x3F20FC00, InstName.Cpypt, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1D00F400, 0x3F20FC00, InstName.Cpyptn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1D00B400, 0x3F20FC00, InstName.Cpyptrn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1D007400, 0x3F20FC00, InstName.Cpyptwn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1D004400, 0x3F20FC00, InstName.Cpypwn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1D001400, 0x3F20FC00, InstName.Cpypwt, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1D00D400, 0x3F20FC00, InstName.Cpypwtn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1D009400, 0x3F20FC00, InstName.Cpypwtrn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1D005400, 0x3F20FC00, InstName.Cpypwtwn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1AC04000, 0x7FE0F000, sfszSfszSfszSfszConstraints, InstName.Crc32, IsaVersion.v80, InstFlags.RdRnRm), + new(0x1AC05000, 0x7FE0F000, sfszSfszSfszSfszConstraints, InstName.Crc32c, IsaVersion.v80, InstFlags.RdRnRm), + new(0xD503229F, 0xFFFFFFFF, InstName.Csdb, IsaVersion.v80, InstFlags.None), + new(0x1A800000, 0x7FE00C00, InstName.Csel, IsaVersion.v80, InstFlags.RdRnRmNzcv), + new(0x1A800400, 0x7FE00C00, InstName.Csinc, IsaVersion.v80, InstFlags.RdRnRmNzcv), + new(0x5A800000, 0x7FE00C00, InstName.Csinv, IsaVersion.v80, InstFlags.RdRnRmNzcv), + new(0x5A800400, 0x7FE00C00, InstName.Csneg, IsaVersion.v80, InstFlags.RdRnRmNzcv), + new(0x5AC01800, 0x7FFFFC00, InstName.Ctz, IsaVersion.v89, InstFlags.RdRn), + new(0xD4A00001, 0xFFE0001F, InstName.Dcps1, IsaVersion.v80, InstFlags.None), + new(0xD4A00002, 0xFFE0001F, InstName.Dcps2, IsaVersion.v80, InstFlags.None), + new(0xD4A00003, 0xFFE0001F, InstName.Dcps3, IsaVersion.v80, InstFlags.None), + new(0xD50320DF, 0xFFFFFFFF, InstName.Dgh, IsaVersion.v84, InstFlags.None), + new(0xD50330BF, 0xFFFFF0FF, InstName.Dmb, IsaVersion.v80, InstFlags.None), + new(0xD6BF03E0, 0xFFFFFFFF, InstName.Drps, IsaVersion.v80, InstFlags.None), + new(0xD503309F, 0xFFFFF0FF, InstName.DsbDsbMemory, IsaVersion.v80, InstFlags.None), + new(0xD503323F, 0xFFFFF3FF, InstName.DsbDsbNxs, IsaVersion.v87, InstFlags.None), + new(0x5E000400, 0xFFE0FC00, imm5Constraints, InstName.DupAdvsimdEltScalarFromElement, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0E000400, 0xBFE0FC00, imm5Imm5qConstraints, InstName.DupAdvsimdEltVectorFromElement, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0E000C00, 0xBFE0FC00, imm5Imm5qConstraints, InstName.DupAdvsimdGen, IsaVersion.v80, InstFlags.RdRnFpSimdFromGpr), + new(0x4A200000, 0x7F200000, sfimm6Constraints, InstName.Eon, IsaVersion.v80, InstFlags.RdRnRm), + new(0xCE000000, 0xFFE08000, InstName.Eor3Advsimd, IsaVersion.v82, InstFlags.RdRnRmRaFpSimd), + new(0x2E201C00, 0xBFE0FC00, InstName.EorAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x52000000, 0x7F800000, nimmsNimmsNimmsNimmsNimmsNimmsNimmsNimmsSfnConstraints, InstName.EorLogImm, IsaVersion.v80, InstFlags.RdSPRn), + new(0x4A000000, 0x7F200000, sfimm6Constraints, InstName.EorLogShift, IsaVersion.v80, InstFlags.RdRnRm), + new(0xD69F03E0, 0xFFFFFFFF, InstName.Eret, IsaVersion.v80, InstFlags.None), + new(0xD69F0BFF, 0xFFFFFBFF, InstName.Ereta, IsaVersion.v83, InstFlags.None), + new(0xD503221F, 0xFFFFFFFF, InstName.Esb, IsaVersion.v82, InstFlags.None), + new(0x13800000, 0x7FA00000, nsfNsfSfimmsConstraints, InstName.Extr, IsaVersion.v80, InstFlags.RdRnRm), + new(0x2E000000, 0xBFE08400, qimm4Constraints, InstName.ExtAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x7EC01400, 0xFFE0FC00, InstName.FabdAdvsimdSH, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x7EA0D400, 0xFFA0FC00, InstName.FabdAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2EC01400, 0xBFE0FC00, InstName.FabdAdvsimdVH, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x2EA0D400, 0xBFA0FC00, qszConstraints, InstName.FabdAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0EF8F800, 0xBFFFFC00, InstName.FabsAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x0EA0F800, 0xBFBFFC00, qszConstraints, InstName.FabsAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E20C000, 0xFFBFFC00, InstName.FabsFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1EE0C000, 0xFFFFFC00, InstName.FabsFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x7E402C00, 0xFFE0FC00, euacEuacEuacConstraints, InstName.FacgeAdvsimdSH, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x7E20EC00, 0xFFA0FC00, euacEuacEuacConstraints, InstName.FacgeAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E402C00, 0xBFE0FC00, euacEuacEuacConstraints, InstName.FacgeAdvsimdVH, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x2E20EC00, 0xBFA0FC00, qszEuacEuacEuacConstraints, InstName.FacgeAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x7EC02C00, 0xFFE0FC00, euacEuacEuacConstraints, InstName.FacgtAdvsimdSH, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x7EA0EC00, 0xFFA0FC00, euacEuacEuacConstraints, InstName.FacgtAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2EC02C00, 0xBFE0FC00, euacEuacEuacConstraints, InstName.FacgtAdvsimdVH, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x2EA0EC00, 0xBFA0FC00, qszEuacEuacEuacConstraints, InstName.FacgtAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5E30D800, 0xFFBFFC00, szConstraints, InstName.FaddpAdvsimdPairHalf, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x7E30D800, 0xFFBFFC00, InstName.FaddpAdvsimdPairSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2E401400, 0xBFE0FC00, InstName.FaddpAdvsimdVecHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x2E20D400, 0xBFA0FC00, qszConstraints, InstName.FaddpAdvsimdVecSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E401400, 0xBFE0FC00, InstName.FaddAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x0E20D400, 0xBFA0FC00, qszConstraints, InstName.FaddAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x1E202800, 0xFFA0FC00, InstName.FaddFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x1EE02800, 0xFFE0FC00, InstName.FaddFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E80E400, 0xBFA0EC00, sizeQsizeConstraints, InstName.FcaddAdvsimdVec, IsaVersion.v83, InstFlags.RdRnRmFpSimd), + new(0x2E40E400, 0xBFE0EC00, sizeQsizeConstraints, InstName.FcaddAdvsimdVec, IsaVersion.v83, InstFlags.RdRnRmFpSimd), + new(0x1E200410, 0xFFA00C10, InstName.FccmpeFloat, IsaVersion.v80, InstFlags.RnRmNzcvSFpSimd), + new(0x1EE00410, 0xFFE00C10, InstName.FccmpeFloat, IsaVersion.v80, InstFlags.RnRmNzcvSFpSimd), + new(0x1E200400, 0xFFA00C10, InstName.FccmpFloat, IsaVersion.v80, InstFlags.RnRmNzcvSFpSimd), + new(0x1EE00400, 0xFFE00C10, InstName.FccmpFloat, IsaVersion.v80, InstFlags.RnRmNzcvSFpSimd), + new(0x5E402400, 0xFFE0FC00, euacEuacEuacConstraints, InstName.FcmeqAdvsimdRegSH, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x5E20E400, 0xFFA0FC00, euacEuacEuacConstraints, InstName.FcmeqAdvsimdRegS, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E402400, 0xBFE0FC00, euacEuacEuacConstraints, InstName.FcmeqAdvsimdRegVH, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x0E20E400, 0xBFA0FC00, qszEuacEuacEuacConstraints, InstName.FcmeqAdvsimdRegV, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5EF8D800, 0xFFFFFC00, InstName.FcmeqAdvsimdZeroSH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x5EA0D800, 0xFFBFFC00, InstName.FcmeqAdvsimdZeroS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0EF8D800, 0xBFFFFC00, InstName.FcmeqAdvsimdZeroVH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x0EA0D800, 0xBFBFFC00, qszConstraints, InstName.FcmeqAdvsimdZeroV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x7E402400, 0xFFE0FC00, euacEuacEuacConstraints, InstName.FcmgeAdvsimdRegSH, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x7E20E400, 0xFFA0FC00, euacEuacEuacConstraints, InstName.FcmgeAdvsimdRegS, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E402400, 0xBFE0FC00, euacEuacEuacConstraints, InstName.FcmgeAdvsimdRegVH, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x2E20E400, 0xBFA0FC00, qszEuacEuacEuacConstraints, InstName.FcmgeAdvsimdRegV, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x7EF8C800, 0xFFFFFC00, InstName.FcmgeAdvsimdZeroSH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x7EA0C800, 0xFFBFFC00, InstName.FcmgeAdvsimdZeroS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2EF8C800, 0xBFFFFC00, InstName.FcmgeAdvsimdZeroVH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x2EA0C800, 0xBFBFFC00, qszConstraints, InstName.FcmgeAdvsimdZeroV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x7EC02400, 0xFFE0FC00, euacEuacEuacConstraints, InstName.FcmgtAdvsimdRegSH, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x7EA0E400, 0xFFA0FC00, euacEuacEuacConstraints, InstName.FcmgtAdvsimdRegS, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2EC02400, 0xBFE0FC00, euacEuacEuacConstraints, InstName.FcmgtAdvsimdRegVH, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x2EA0E400, 0xBFA0FC00, qszEuacEuacEuacConstraints, InstName.FcmgtAdvsimdRegV, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5EF8C800, 0xFFFFFC00, InstName.FcmgtAdvsimdZeroSH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x5EA0C800, 0xFFBFFC00, InstName.FcmgtAdvsimdZeroS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0EF8C800, 0xBFFFFC00, InstName.FcmgtAdvsimdZeroVH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x0EA0C800, 0xBFBFFC00, qszConstraints, InstName.FcmgtAdvsimdZeroV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2F801000, 0xBF809400, sizeSizeSizelSizeqSizehqConstraints, InstName.FcmlaAdvsimdElt, IsaVersion.v83, InstFlags.RdReadRdRnRmFpSimd), + new(0x2F401000, 0xBFC09400, sizeSizeSizelSizeqSizehqConstraints, InstName.FcmlaAdvsimdElt, IsaVersion.v83, InstFlags.RdReadRdRnRmFpSimd), + new(0x2E80C400, 0xBFA0E400, sizeQsizeConstraints, InstName.FcmlaAdvsimdVec, IsaVersion.v83, InstFlags.RdReadRdRnRmFpSimd), + new(0x2E40C400, 0xBFE0E400, sizeQsizeConstraints, InstName.FcmlaAdvsimdVec, IsaVersion.v83, InstFlags.RdReadRdRnRmFpSimd), + new(0x7EF8D800, 0xFFFFFC00, InstName.FcmleAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x7EA0D800, 0xFFBFFC00, InstName.FcmleAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2EF8D800, 0xBFFFFC00, InstName.FcmleAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x2EA0D800, 0xBFBFFC00, qszConstraints, InstName.FcmleAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5EF8E800, 0xFFFFFC00, InstName.FcmltAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x5EA0E800, 0xFFBFFC00, InstName.FcmltAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0EF8E800, 0xBFFFFC00, InstName.FcmltAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x0EA0E800, 0xBFBFFC00, qszConstraints, InstName.FcmltAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E202010, 0xFFA0FC17, InstName.FcmpeFloat, IsaVersion.v80, InstFlags.RnRmSFpSimd), + new(0x1EE02010, 0xFFE0FC17, InstName.FcmpeFloat, IsaVersion.v80, InstFlags.RnRmSFpSimd), + new(0x1E202000, 0xFFA0FC17, InstName.FcmpFloat, IsaVersion.v80, InstFlags.RnRmSFpSimd), + new(0x1EE02000, 0xFFE0FC17, InstName.FcmpFloat, IsaVersion.v80, InstFlags.RnRmSFpSimd), + new(0x1E200C00, 0xFFA00C00, InstName.FcselFloat, IsaVersion.v80, InstFlags.RdRnRmNzcvFpSimd), + new(0x1EE00C00, 0xFFE00C00, InstName.FcselFloat, IsaVersion.v80, InstFlags.RdRnRmNzcvFpSimd), + new(0x5E79C800, 0xFFFFFC00, InstName.FcvtasAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x5E21C800, 0xFFBFFC00, InstName.FcvtasAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0E79C800, 0xBFFFFC00, InstName.FcvtasAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x0E21C800, 0xBFBFFC00, qszConstraints, InstName.FcvtasAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E240000, 0x7FBFFC00, InstName.FcvtasFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x1EE40000, 0x7FFFFC00, InstName.FcvtasFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x7E79C800, 0xFFFFFC00, InstName.FcvtauAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x7E21C800, 0xFFBFFC00, InstName.FcvtauAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2E79C800, 0xBFFFFC00, InstName.FcvtauAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x2E21C800, 0xBFBFFC00, qszConstraints, InstName.FcvtauAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E250000, 0x7FBFFC00, InstName.FcvtauFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x1EE50000, 0x7FFFFC00, InstName.FcvtauFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x0E217800, 0xBFBFFC00, InstName.FcvtlAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5E79B800, 0xFFFFFC00, InstName.FcvtmsAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x5E21B800, 0xFFBFFC00, InstName.FcvtmsAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0E79B800, 0xBFFFFC00, InstName.FcvtmsAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x0E21B800, 0xBFBFFC00, qszConstraints, InstName.FcvtmsAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E300000, 0x7FBFFC00, InstName.FcvtmsFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x1EF00000, 0x7FFFFC00, InstName.FcvtmsFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x7E79B800, 0xFFFFFC00, InstName.FcvtmuAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x7E21B800, 0xFFBFFC00, InstName.FcvtmuAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2E79B800, 0xBFFFFC00, InstName.FcvtmuAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x2E21B800, 0xBFBFFC00, qszConstraints, InstName.FcvtmuAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E310000, 0x7FBFFC00, InstName.FcvtmuFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x1EF10000, 0x7FFFFC00, InstName.FcvtmuFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x5E79A800, 0xFFFFFC00, InstName.FcvtnsAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x5E21A800, 0xFFBFFC00, InstName.FcvtnsAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0E79A800, 0xBFFFFC00, InstName.FcvtnsAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x0E21A800, 0xBFBFFC00, qszConstraints, InstName.FcvtnsAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E200000, 0x7FBFFC00, InstName.FcvtnsFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x1EE00000, 0x7FFFFC00, InstName.FcvtnsFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x7E79A800, 0xFFFFFC00, InstName.FcvtnuAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x7E21A800, 0xFFBFFC00, InstName.FcvtnuAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2E79A800, 0xBFFFFC00, InstName.FcvtnuAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x2E21A800, 0xBFBFFC00, qszConstraints, InstName.FcvtnuAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E210000, 0x7FBFFC00, InstName.FcvtnuFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x1EE10000, 0x7FFFFC00, InstName.FcvtnuFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x0E216800, 0xBFBFFC00, InstName.FcvtnAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd), + new(0x5EF9A800, 0xFFFFFC00, InstName.FcvtpsAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x5EA1A800, 0xFFBFFC00, InstName.FcvtpsAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0EF9A800, 0xBFFFFC00, InstName.FcvtpsAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x0EA1A800, 0xBFBFFC00, qszConstraints, InstName.FcvtpsAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E280000, 0x7FBFFC00, InstName.FcvtpsFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x1EE80000, 0x7FFFFC00, InstName.FcvtpsFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x7EF9A800, 0xFFFFFC00, InstName.FcvtpuAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x7EA1A800, 0xFFBFFC00, InstName.FcvtpuAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2EF9A800, 0xBFFFFC00, InstName.FcvtpuAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x2EA1A800, 0xBFBFFC00, qszConstraints, InstName.FcvtpuAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E290000, 0x7FBFFC00, InstName.FcvtpuFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x1EE90000, 0x7FFFFC00, InstName.FcvtpuFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x7E216800, 0xFFBFFC00, szConstraints2, InstName.FcvtxnAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd), + new(0x2E216800, 0xBFBFFC00, szConstraints2, InstName.FcvtxnAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd), + new(0x5F40FC00, 0xFFC0FC00, immhConstraints, InstName.FcvtzsAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5F10FC00, 0xFFF0FC00, immhConstraints, InstName.FcvtzsAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5F20FC00, 0xFFE0FC00, immhConstraints, InstName.FcvtzsAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0F40FC00, 0xBFC0FC00, immhQimmhConstraints, InstName.FcvtzsAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0F10FC00, 0xBFF0FC00, immhQimmhConstraints, InstName.FcvtzsAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0F20FC00, 0xBFE0FC00, immhQimmhConstraints, InstName.FcvtzsAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5EF9B800, 0xFFFFFC00, InstName.FcvtzsAdvsimdIntSH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x5EA1B800, 0xFFBFFC00, InstName.FcvtzsAdvsimdIntS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0EF9B800, 0xBFFFFC00, InstName.FcvtzsAdvsimdIntVH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x0EA1B800, 0xBFBFFC00, qszConstraints, InstName.FcvtzsAdvsimdIntV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E180000, 0x7FBF0000, sfscaleConstraints, InstName.FcvtzsFloatFix, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x1ED80000, 0x7FFF0000, sfscaleConstraints, InstName.FcvtzsFloatFix, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x1E380000, 0x7FBFFC00, InstName.FcvtzsFloatInt, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x1EF80000, 0x7FFFFC00, InstName.FcvtzsFloatInt, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x7F40FC00, 0xFFC0FC00, immhConstraints, InstName.FcvtzuAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x7F10FC00, 0xFFF0FC00, immhConstraints, InstName.FcvtzuAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x7F20FC00, 0xFFE0FC00, immhConstraints, InstName.FcvtzuAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2F40FC00, 0xBFC0FC00, immhQimmhConstraints, InstName.FcvtzuAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2F10FC00, 0xBFF0FC00, immhQimmhConstraints, InstName.FcvtzuAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2F20FC00, 0xBFE0FC00, immhQimmhConstraints, InstName.FcvtzuAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x7EF9B800, 0xFFFFFC00, InstName.FcvtzuAdvsimdIntSH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x7EA1B800, 0xFFBFFC00, InstName.FcvtzuAdvsimdIntS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2EF9B800, 0xBFFFFC00, InstName.FcvtzuAdvsimdIntVH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x2EA1B800, 0xBFBFFC00, qszConstraints, InstName.FcvtzuAdvsimdIntV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E190000, 0x7FBF0000, sfscaleConstraints, InstName.FcvtzuFloatFix, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x1ED90000, 0x7FFF0000, sfscaleConstraints, InstName.FcvtzuFloatFix, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x1E390000, 0x7FBFFC00, InstName.FcvtzuFloatInt, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x1EF90000, 0x7FFFFC00, InstName.FcvtzuFloatInt, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x1E224000, 0xFF3E7C00, ftypeopcFtypeopcFtypeopcFtypeopcFtypeOpcConstraints, InstName.FcvtFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2E403C00, 0xBFE0FC00, InstName.FdivAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x2E20FC00, 0xBFA0FC00, qszConstraints, InstName.FdivAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x1E201800, 0xFFA0FC00, InstName.FdivFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x1EE01800, 0xFFE0FC00, InstName.FdivFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x1E7E0000, 0xFFFFFC00, InstName.Fjcvtzs, IsaVersion.v83, InstFlags.RdRnSFpSimd), + new(0x1F000000, 0xFFA08000, InstName.FmaddFloat, IsaVersion.v80, InstFlags.RdRnRmRaFpSimd), + new(0x1FC00000, 0xFFE08000, InstName.FmaddFloat, IsaVersion.v80, InstFlags.RdRnRmRaFpSimd), + new(0x5E30C800, 0xFFBFFC00, szConstraints, InstName.FmaxnmpAdvsimdPairHalf, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x7E30C800, 0xFFBFFC00, InstName.FmaxnmpAdvsimdPairSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2E400400, 0xBFE0FC00, InstName.FmaxnmpAdvsimdVecHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x2E20C400, 0xBFA0FC00, qszConstraints, InstName.FmaxnmpAdvsimdVecSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E30C800, 0xBFFFFC00, InstName.FmaxnmvAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x6E30C800, 0xFFFFFC00, InstName.FmaxnmvAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0E400400, 0xBFE0FC00, InstName.FmaxnmAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x0E20C400, 0xBFA0FC00, qszConstraints, InstName.FmaxnmAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x1E206800, 0xFFA0FC00, InstName.FmaxnmFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x1EE06800, 0xFFE0FC00, InstName.FmaxnmFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5E30F800, 0xFFBFFC00, szConstraints, InstName.FmaxpAdvsimdPairHalf, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x7E30F800, 0xFFBFFC00, InstName.FmaxpAdvsimdPairSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2E403400, 0xBFE0FC00, InstName.FmaxpAdvsimdVecHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x2E20F400, 0xBFA0FC00, qszConstraints, InstName.FmaxpAdvsimdVecSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E30F800, 0xBFFFFC00, InstName.FmaxvAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x6E30F800, 0xFFFFFC00, InstName.FmaxvAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0E403400, 0xBFE0FC00, InstName.FmaxAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x0E20F400, 0xBFA0FC00, qszConstraints, InstName.FmaxAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x1E204800, 0xFFA0FC00, InstName.FmaxFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x1EE04800, 0xFFE0FC00, InstName.FmaxFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5EB0C800, 0xFFBFFC00, szConstraints, InstName.FminnmpAdvsimdPairHalf, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x7EB0C800, 0xFFBFFC00, InstName.FminnmpAdvsimdPairSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2EC00400, 0xBFE0FC00, InstName.FminnmpAdvsimdVecHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x2EA0C400, 0xBFA0FC00, qszConstraints, InstName.FminnmpAdvsimdVecSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0EB0C800, 0xBFFFFC00, InstName.FminnmvAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x6EB0C800, 0xFFFFFC00, InstName.FminnmvAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0EC00400, 0xBFE0FC00, InstName.FminnmAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x0EA0C400, 0xBFA0FC00, qszConstraints, InstName.FminnmAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x1E207800, 0xFFA0FC00, InstName.FminnmFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x1EE07800, 0xFFE0FC00, InstName.FminnmFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5EB0F800, 0xFFBFFC00, szConstraints, InstName.FminpAdvsimdPairHalf, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x7EB0F800, 0xFFBFFC00, InstName.FminpAdvsimdPairSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2EC03400, 0xBFE0FC00, InstName.FminpAdvsimdVecHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x2EA0F400, 0xBFA0FC00, qszConstraints, InstName.FminpAdvsimdVecSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0EB0F800, 0xBFFFFC00, InstName.FminvAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x6EB0F800, 0xFFFFFC00, InstName.FminvAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0EC03400, 0xBFE0FC00, InstName.FminAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x0EA0F400, 0xBFA0FC00, qszConstraints, InstName.FminAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x1E205800, 0xFFA0FC00, InstName.FminFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x1EE05800, 0xFFE0FC00, InstName.FminFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0F800000, 0xBFC0F400, szConstraints, InstName.FmlalAdvsimdEltFmlal, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd), + new(0x2F808000, 0xBFC0F400, szConstraints, InstName.FmlalAdvsimdEltFmlal2, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd), + new(0x0E20EC00, 0xBFE0FC00, szConstraints, InstName.FmlalAdvsimdVecFmlal, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd), + new(0x2E20CC00, 0xBFE0FC00, szConstraints, InstName.FmlalAdvsimdVecFmlal2, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd), + new(0x5F001000, 0xFFC0F400, InstName.FmlaAdvsimdElt2regScalarHalf, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd), + new(0x5F801000, 0xFF80F400, szlConstraints, InstName.FmlaAdvsimdElt2regScalarSingleAndDouble, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd), + new(0x0F001000, 0xBFC0F400, InstName.FmlaAdvsimdElt2regElementHalf, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd), + new(0x0F801000, 0xBF80F400, szlQszConstraints, InstName.FmlaAdvsimdElt2regElementSingleAndDouble, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd), + new(0x0E400C00, 0xBFE0FC00, InstName.FmlaAdvsimdVecHalf, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd), + new(0x0E20CC00, 0xBFA0FC00, qszConstraints, InstName.FmlaAdvsimdVecSingleAndDouble, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd), + new(0x0F804000, 0xBFC0F400, szConstraints, InstName.FmlslAdvsimdEltFmlsl, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd), + new(0x2F80C000, 0xBFC0F400, szConstraints, InstName.FmlslAdvsimdEltFmlsl2, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd), + new(0x0EA0EC00, 0xBFE0FC00, szConstraints, InstName.FmlslAdvsimdVecFmlsl, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd), + new(0x2EA0CC00, 0xBFE0FC00, szConstraints, InstName.FmlslAdvsimdVecFmlsl2, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd), + new(0x5F005000, 0xFFC0F400, InstName.FmlsAdvsimdElt2regScalarHalf, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd), + new(0x5F805000, 0xFF80F400, szlConstraints, InstName.FmlsAdvsimdElt2regScalarSingleAndDouble, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd), + new(0x0F005000, 0xBFC0F400, InstName.FmlsAdvsimdElt2regElementHalf, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd), + new(0x0F805000, 0xBF80F400, szlQszConstraints, InstName.FmlsAdvsimdElt2regElementSingleAndDouble, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd), + new(0x0EC00C00, 0xBFE0FC00, InstName.FmlsAdvsimdVecHalf, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd), + new(0x0EA0CC00, 0xBFA0FC00, qszConstraints, InstName.FmlsAdvsimdVecSingleAndDouble, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd), + new(0x0F00FC00, 0xBFF8FC00, InstName.FmovAdvsimdPerHalf, IsaVersion.v82, InstFlags.RdFpSimd), + new(0x0F00F400, 0x9FF8FC00, qConstraints, InstName.FmovAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdFpSimd), + new(0x1E204000, 0xFFBFFC00, InstName.FmovFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1EE04000, 0xFFFFFC00, InstName.FmovFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E260000, 0xFFFEFC00, sfftypermodeSfftypermodeConstraints, InstName.FmovFloatGen, IsaVersion.v80, InstFlags.RdRnSFpSimdFromToGpr), + new(0x9E660000, 0xFFFEFC00, sfftypermodeSfftypermodeConstraints, InstName.FmovFloatGen, IsaVersion.v80, InstFlags.RdRnSFpSimdFromToGpr), + new(0x9EAE0000, 0xFFFEFC00, sfftypermodeSfftypermodeConstraints, InstName.FmovFloatGen, IsaVersion.v80, InstFlags.RdRnSFpSimdFromToGpr), + new(0x1EE60000, 0x7FFEFC00, sfftypermodeSfftypermodeConstraints, InstName.FmovFloatGen, IsaVersion.v80, InstFlags.RdRnSFpSimdFromToGpr), + new(0x1E201000, 0xFFA01FE0, InstName.FmovFloatImm, IsaVersion.v80, InstFlags.RdFpSimd), + new(0x1EE01000, 0xFFE01FE0, InstName.FmovFloatImm, IsaVersion.v80, InstFlags.RdFpSimd), + new(0x1F008000, 0xFFA08000, InstName.FmsubFloat, IsaVersion.v80, InstFlags.RdRnRmRaFpSimd), + new(0x1FC08000, 0xFFE08000, InstName.FmsubFloat, IsaVersion.v80, InstFlags.RdRnRmRaFpSimd), + new(0x7F009000, 0xFFC0F400, InstName.FmulxAdvsimdElt2regScalarHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x7F809000, 0xFF80F400, szlConstraints, InstName.FmulxAdvsimdElt2regScalarSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2F009000, 0xBFC0F400, InstName.FmulxAdvsimdElt2regElementHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x2F809000, 0xBF80F400, szlQszConstraints, InstName.FmulxAdvsimdElt2regElementSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5E401C00, 0xFFE0FC00, InstName.FmulxAdvsimdVecSH, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x5E20DC00, 0xFFA0FC00, InstName.FmulxAdvsimdVecS, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E401C00, 0xBFE0FC00, InstName.FmulxAdvsimdVecVH, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x0E20DC00, 0xBFA0FC00, qszConstraints, InstName.FmulxAdvsimdVecV, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5F009000, 0xFFC0F400, InstName.FmulAdvsimdElt2regScalarHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x5F809000, 0xFF80F400, szlConstraints, InstName.FmulAdvsimdElt2regScalarSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0F009000, 0xBFC0F400, InstName.FmulAdvsimdElt2regElementHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x0F809000, 0xBF80F400, szlQszConstraints, InstName.FmulAdvsimdElt2regElementSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E401C00, 0xBFE0FC00, InstName.FmulAdvsimdVecHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x2E20DC00, 0xBFA0FC00, qszConstraints, InstName.FmulAdvsimdVecSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x1E200800, 0xFFA0FC00, InstName.FmulFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x1EE00800, 0xFFE0FC00, InstName.FmulFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2EF8F800, 0xBFFFFC00, InstName.FnegAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x2EA0F800, 0xBFBFFC00, qszConstraints, InstName.FnegAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E214000, 0xFFBFFC00, InstName.FnegFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1EE14000, 0xFFFFFC00, InstName.FnegFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1F200000, 0xFFA08000, InstName.FnmaddFloat, IsaVersion.v80, InstFlags.RdRnRmRaFpSimd), + new(0x1FE00000, 0xFFE08000, InstName.FnmaddFloat, IsaVersion.v80, InstFlags.RdRnRmRaFpSimd), + new(0x1F208000, 0xFFA08000, InstName.FnmsubFloat, IsaVersion.v80, InstFlags.RdRnRmRaFpSimd), + new(0x1FE08000, 0xFFE08000, InstName.FnmsubFloat, IsaVersion.v80, InstFlags.RdRnRmRaFpSimd), + new(0x1E208800, 0xFFA0FC00, InstName.FnmulFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x1EE08800, 0xFFE0FC00, InstName.FnmulFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5EF9D800, 0xFFFFFC00, InstName.FrecpeAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x5EA1D800, 0xFFBFFC00, InstName.FrecpeAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0EF9D800, 0xBFFFFC00, InstName.FrecpeAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x0EA1D800, 0xBFBFFC00, qszConstraints, InstName.FrecpeAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5E403C00, 0xFFE0FC00, InstName.FrecpsAdvsimdSH, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x5E20FC00, 0xFFA0FC00, InstName.FrecpsAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E403C00, 0xBFE0FC00, InstName.FrecpsAdvsimdVH, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x0E20FC00, 0xBFA0FC00, qszConstraints, InstName.FrecpsAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5EF9F800, 0xFFFFFC00, InstName.FrecpxAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x5EA1F800, 0xFFBFFC00, InstName.FrecpxAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2E21E800, 0xBFBFFC00, qszConstraints, InstName.Frint32xAdvsimd, IsaVersion.v85, InstFlags.RdRnFpSimd), + new(0x1E28C000, 0xFFBFFC00, InstName.Frint32xFloat, IsaVersion.v85, InstFlags.RdRnFpSimd), + new(0x0E21E800, 0xBFBFFC00, qszConstraints, InstName.Frint32zAdvsimd, IsaVersion.v85, InstFlags.RdRnFpSimd), + new(0x1E284000, 0xFFBFFC00, InstName.Frint32zFloat, IsaVersion.v85, InstFlags.RdRnFpSimd), + new(0x2E21F800, 0xBFBFFC00, qszConstraints, InstName.Frint64xAdvsimd, IsaVersion.v85, InstFlags.RdRnFpSimd), + new(0x1E29C000, 0xFFBFFC00, InstName.Frint64xFloat, IsaVersion.v85, InstFlags.RdRnFpSimd), + new(0x0E21F800, 0xBFBFFC00, qszConstraints, InstName.Frint64zAdvsimd, IsaVersion.v85, InstFlags.RdRnFpSimd), + new(0x1E294000, 0xFFBFFC00, InstName.Frint64zFloat, IsaVersion.v85, InstFlags.RdRnFpSimd), + new(0x2E798800, 0xBFFFFC00, uo1o2Constraints, InstName.FrintaAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x2E218800, 0xBFBFFC00, qszUo1o2Constraints, InstName.FrintaAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E264000, 0xFFBFFC00, InstName.FrintaFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1EE64000, 0xFFFFFC00, InstName.FrintaFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2EF99800, 0xBFFFFC00, uo1o2Constraints, InstName.FrintiAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x2EA19800, 0xBFBFFC00, qszUo1o2Constraints, InstName.FrintiAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E27C000, 0xFFBFFC00, InstName.FrintiFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1EE7C000, 0xFFFFFC00, InstName.FrintiFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0E799800, 0xBFFFFC00, uo1o2Constraints, InstName.FrintmAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x0E219800, 0xBFBFFC00, qszUo1o2Constraints, InstName.FrintmAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E254000, 0xFFBFFC00, InstName.FrintmFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1EE54000, 0xFFFFFC00, InstName.FrintmFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0E798800, 0xBFFFFC00, uo1o2Constraints, InstName.FrintnAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x0E218800, 0xBFBFFC00, qszUo1o2Constraints, InstName.FrintnAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E244000, 0xFFBFFC00, InstName.FrintnFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1EE44000, 0xFFFFFC00, InstName.FrintnFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0EF98800, 0xBFFFFC00, uo1o2Constraints, InstName.FrintpAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x0EA18800, 0xBFBFFC00, qszUo1o2Constraints, InstName.FrintpAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E24C000, 0xFFBFFC00, InstName.FrintpFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1EE4C000, 0xFFFFFC00, InstName.FrintpFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2E799800, 0xBFFFFC00, uo1o2Constraints, InstName.FrintxAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x2E219800, 0xBFBFFC00, qszUo1o2Constraints, InstName.FrintxAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E274000, 0xFFBFFC00, InstName.FrintxFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1EE74000, 0xFFFFFC00, InstName.FrintxFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0EF99800, 0xBFFFFC00, uo1o2Constraints, InstName.FrintzAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x0EA19800, 0xBFBFFC00, qszUo1o2Constraints, InstName.FrintzAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E25C000, 0xFFBFFC00, InstName.FrintzFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1EE5C000, 0xFFFFFC00, InstName.FrintzFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x7EF9D800, 0xFFFFFC00, InstName.FrsqrteAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x7EA1D800, 0xFFBFFC00, InstName.FrsqrteAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2EF9D800, 0xBFFFFC00, InstName.FrsqrteAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x2EA1D800, 0xBFBFFC00, qszConstraints, InstName.FrsqrteAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5EC03C00, 0xFFE0FC00, InstName.FrsqrtsAdvsimdSH, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x5EA0FC00, 0xFFA0FC00, InstName.FrsqrtsAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0EC03C00, 0xBFE0FC00, InstName.FrsqrtsAdvsimdVH, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x0EA0FC00, 0xBFA0FC00, qszConstraints, InstName.FrsqrtsAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2EF9F800, 0xBFFFFC00, InstName.FsqrtAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x2EA1F800, 0xBFBFFC00, qszConstraints, InstName.FsqrtAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E21C000, 0xFFBFFC00, InstName.FsqrtFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1EE1C000, 0xFFFFFC00, InstName.FsqrtFloat, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0EC01400, 0xBFE0FC00, InstName.FsubAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x0EA0D400, 0xBFA0FC00, qszConstraints, InstName.FsubAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x1E203800, 0xFFA0FC00, InstName.FsubFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x1EE03800, 0xFFE0FC00, InstName.FsubFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0xD503227F, 0xFFFFFFFF, InstName.Gcsb, IsaVersion.None, InstFlags.None), + new(0xD91F0C00, 0xFFFFFC00, InstName.Gcsstr, IsaVersion.None, InstFlags.RtReadRtRnSP), + new(0xD91F1C00, 0xFFFFFC00, InstName.Gcssttr, IsaVersion.None, InstFlags.RtReadRtRnSP), + new(0x9AC01400, 0xFFE0FC00, InstName.Gmi, IsaVersion.v85, InstFlags.None), + new(0xD503201F, 0xFFFFF01F, InstName.Hint, IsaVersion.v80, InstFlags.None), + new(0xD4400000, 0xFFE0001F, InstName.Hlt, IsaVersion.v80, InstFlags.None), + new(0xD4000002, 0xFFE0001F, InstName.Hvc, IsaVersion.v80, InstFlags.None), + new(0x6E000400, 0xFFE08400, imm5Constraints, InstName.InsAdvsimdElt, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd), + new(0x4E001C00, 0xFFE0FC00, imm5Constraints, InstName.InsAdvsimdGen, IsaVersion.v80, InstFlags.RdReadRdRnFpSimdFromGpr), + new(0x9AC01000, 0xFFE0FC00, InstName.Irg, IsaVersion.v85, InstFlags.None), + new(0xD50330DF, 0xFFFFF0FF, InstName.Isb, IsaVersion.v80, InstFlags.None), + new(0x0D40C000, 0xBFFFF000, sConstraints, InstName.Ld1rAdvsimdAsNoPostIndex, IsaVersion.v80, InstFlags.RtRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0DC0C000, 0xBFE0F000, sConstraints, InstName.Ld1rAdvsimdAsPostIndex, IsaVersion.v80, InstFlags.RtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0C402000, 0xBFFFF000, InstName.Ld1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0C406000, 0xBFFFF000, InstName.Ld1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0C407000, 0xBFFFF000, InstName.Ld1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0C40A000, 0xBFFFF000, InstName.Ld1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0C406000, 0xBFFFF000, InstName.Ld1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0C407000, 0xBFFFF000, InstName.Ld1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0C40A000, 0xBFFFF000, InstName.Ld1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0CC02000, 0xBFE0F000, InstName.Ld1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0CC06000, 0xBFE0F000, InstName.Ld1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0CC07000, 0xBFE0F000, InstName.Ld1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0CC0A000, 0xBFE0F000, InstName.Ld1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0CC06000, 0xBFE0F000, InstName.Ld1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0CC07000, 0xBFE0F000, InstName.Ld1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0CC0A000, 0xBFE0F000, InstName.Ld1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0D400000, 0xBFFF2000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.Ld1AdvsimdSnglAsNoPostIndex, IsaVersion.v80, InstFlags.RtReadRtRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0DC00000, 0xBFE02000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.Ld1AdvsimdSnglAsPostIndex, IsaVersion.v80, InstFlags.RtReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0D60C000, 0xBFFFF000, sConstraints, InstName.Ld2rAdvsimdAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0DE0C000, 0xBFE0F000, sConstraints, InstName.Ld2rAdvsimdAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0C408000, 0xBFFFF000, qsizeConstraints2, InstName.Ld2AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0CC08000, 0xBFE0F000, qsizeConstraints2, InstName.Ld2AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0D600000, 0xBFFF2000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.Ld2AdvsimdSnglAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0DE00000, 0xBFE02000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.Ld2AdvsimdSnglAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0D40E000, 0xBFFFF000, sConstraints, InstName.Ld3rAdvsimdAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0DC0E000, 0xBFE0F000, sConstraints, InstName.Ld3rAdvsimdAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0C404000, 0xBFFFF000, qsizeConstraints2, InstName.Ld3AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0CC04000, 0xBFE0F000, qsizeConstraints2, InstName.Ld3AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0D402000, 0xBFFF2000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.Ld3AdvsimdSnglAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0DC02000, 0xBFE02000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.Ld3AdvsimdSnglAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0D60E000, 0xBFFFF000, sConstraints, InstName.Ld4rAdvsimdAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0DE0E000, 0xBFE0F000, sConstraints, InstName.Ld4rAdvsimdAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0C400000, 0xBFFFF000, qsizeConstraints2, InstName.Ld4AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0CC00000, 0xBFE0F000, qsizeConstraints2, InstName.Ld4AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0D602000, 0xBFFF2000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.Ld4AdvsimdSnglAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0DE02000, 0xBFE02000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.Ld4AdvsimdSnglAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0xF83FD000, 0xFFFFFC00, rtRtConstraints, InstName.Ld64b, IsaVersion.v87, InstFlags.RtRnSP), + new(0xB8200000, 0xBF20FC00, InstName.Ldadd, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0x38200000, 0xFF20FC00, InstName.Ldaddb, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0x78200000, 0xFF20FC00, InstName.Ldaddh, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0x0D418400, 0xBFFFFC00, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.Ldap1AdvsimdSngl, IsaVersion.v82, InstFlags.RtReadRtRnSPFpSimd, AddressForm.StructNoOffset), + new(0xB8BFC000, 0xBFFFFC00, InstName.LdaprBaseRegister, IsaVersion.v83, InstFlags.RtRnSP, AddressForm.BaseRegister), + new(0x99C00800, 0xBFFFFC00, InstName.LdaprPostIndexed, IsaVersion.v82, InstFlags.RtRnSPMemWBack, AddressForm.PostIndexed), + new(0x38BFC000, 0xFFFFFC00, InstName.Ldaprb, IsaVersion.v83, InstFlags.RtRnSP), + new(0x78BFC000, 0xFFFFFC00, InstName.Ldaprh, IsaVersion.v83, InstFlags.RtRnSP), + new(0x19400000, 0xFFE00C00, InstName.Ldapurb, IsaVersion.v84, InstFlags.RtRnSP, AddressForm.BasePlusOffset), + new(0x59400000, 0xFFE00C00, InstName.Ldapurh, IsaVersion.v84, InstFlags.RtRnSP, AddressForm.BasePlusOffset), + new(0x19800000, 0xFFA00C00, InstName.Ldapursb, IsaVersion.v84, InstFlags.RtRnSP, AddressForm.BasePlusOffset), + new(0x59800000, 0xFFA00C00, InstName.Ldapursh, IsaVersion.v84, InstFlags.RtRnSP, AddressForm.BasePlusOffset), + new(0x99800000, 0xFFE00C00, InstName.Ldapursw, IsaVersion.v84, InstFlags.RtRnSP, AddressForm.BasePlusOffset), + new(0x1D400800, 0x3F600C00, opc1sizeOpc1sizeOpc1sizeConstraints, InstName.LdapurFpsimd, IsaVersion.v82, InstFlags.RtRnSPFpSimd, AddressForm.BasePlusOffset), + new(0x99400000, 0xBFE00C00, InstName.LdapurGen, IsaVersion.v84, InstFlags.RtRnSP, AddressForm.BasePlusOffset), + new(0x88DFFC00, 0xBFFFFC00, InstName.Ldar, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BaseRegister), + new(0x08DFFC00, 0xFFFFFC00, InstName.Ldarb, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BaseRegister), + new(0x48DFFC00, 0xFFFFFC00, InstName.Ldarh, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BaseRegister), + new(0x887F8000, 0xBFFF8000, InstName.Ldaxp, IsaVersion.v80, InstFlags.RtRt2RnSP, AddressForm.BaseRegister), + new(0x885FFC00, 0xBFFFFC00, InstName.Ldaxr, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BaseRegister), + new(0x085FFC00, 0xFFFFFC00, InstName.Ldaxrb, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BaseRegister), + new(0x485FFC00, 0xFFFFFC00, InstName.Ldaxrh, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BaseRegister), + new(0xB8201000, 0xBF20FC00, InstName.Ldclr, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0x38201000, 0xFF20FC00, InstName.Ldclrb, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0x78201000, 0xFF20FC00, InstName.Ldclrh, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0x19201000, 0xFF20FC00, rtRt2Constraints, InstName.Ldclrp, IsaVersion.None, InstFlags.RtRt2RnSP), + new(0xB8202000, 0xBF20FC00, InstName.Ldeor, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0x38202000, 0xFF20FC00, InstName.Ldeorb, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0x78202000, 0xFF20FC00, InstName.Ldeorh, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0xD9600000, 0xFFE00C00, InstName.Ldg, IsaVersion.v85, InstFlags.None), + new(0xD9E00000, 0xFFFFFC00, InstName.Ldgm, IsaVersion.v85, InstFlags.None), + new(0x99400800, 0xBFE0EC00, InstName.Ldiapp, IsaVersion.v82, InstFlags.RtRt2RnSP), + new(0x88DF7C00, 0xBFFFFC00, InstName.Ldlar, IsaVersion.v81, InstFlags.RtRnSP, AddressForm.BaseRegister), + new(0x08DF7C00, 0xFFFFFC00, InstName.Ldlarb, IsaVersion.v81, InstFlags.RtRnSP, AddressForm.BaseRegister), + new(0x48DF7C00, 0xFFFFFC00, InstName.Ldlarh, IsaVersion.v81, InstFlags.RtRnSP, AddressForm.BaseRegister), + new(0x2C400000, 0x3FC00000, opcConstraints, InstName.LdnpFpsimd, IsaVersion.v80, InstFlags.RtRt2RnSPFpSimd, AddressForm.SignedScaled), + new(0x28400000, 0x7FC00000, opcConstraints2, InstName.LdnpGen, IsaVersion.v80, InstFlags.RtRt2RnSP, AddressForm.SignedScaled), + new(0x68C00000, 0xFFC00000, InstName.LdpswPostIndexed, IsaVersion.v80, InstFlags.RtRt2RnSPMemWBack, AddressForm.PostIndexed), + new(0x69C00000, 0xFFC00000, InstName.LdpswPreIndexed, IsaVersion.v80, InstFlags.RtRt2RnSPMemWBack, AddressForm.PreIndexed), + new(0x69400000, 0xFFC00000, InstName.LdpswSignedScaledOffset, IsaVersion.v80, InstFlags.RtRt2RnSP, AddressForm.SignedScaled), + new(0x2CC00000, 0x3FC00000, opcConstraints, InstName.LdpFpsimdPostIndexed, IsaVersion.v80, InstFlags.RtRt2RnSPFpSimdMemWBack, AddressForm.PostIndexed), + new(0x2DC00000, 0x3FC00000, opcConstraints, InstName.LdpFpsimdPreIndexed, IsaVersion.v80, InstFlags.RtRt2RnSPFpSimdMemWBack, AddressForm.PreIndexed), + new(0x2D400000, 0x3FC00000, opcConstraints, InstName.LdpFpsimdSignedScaledOffset, IsaVersion.v80, InstFlags.RtRt2RnSPFpSimd, AddressForm.SignedScaled), + new(0x28C00000, 0x7FC00000, opclOpcConstraints, InstName.LdpGenPostIndexed, IsaVersion.v80, InstFlags.RtRt2RnSPMemWBack, AddressForm.PostIndexed), + new(0x29C00000, 0x7FC00000, opclOpcConstraints, InstName.LdpGenPreIndexed, IsaVersion.v80, InstFlags.RtRt2RnSPMemWBack, AddressForm.PreIndexed), + new(0x29400000, 0x7FC00000, opclOpcConstraints, InstName.LdpGenSignedScaledOffset, IsaVersion.v80, InstFlags.RtRt2RnSP, AddressForm.SignedScaled), + new(0xF8200400, 0xFF200400, InstName.Ldra, IsaVersion.v83, InstFlags.RtRnSP, AddressForm.BasePlusOffset), + new(0x38400400, 0xFFE00C00, InstName.LdrbImmPostIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PostIndexed), + new(0x38400C00, 0xFFE00C00, InstName.LdrbImmPreIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PreIndexed), + new(0x39400000, 0xFFC00000, InstName.LdrbImmUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.UnsignedScaled), + new(0x38600800, 0xFFE00C00, optionConstraints, InstName.LdrbReg, IsaVersion.v80, InstFlags.RtRnSPRm, AddressForm.OffsetReg), + new(0x78400400, 0xFFE00C00, InstName.LdrhImmPostIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PostIndexed), + new(0x78400C00, 0xFFE00C00, InstName.LdrhImmPreIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PreIndexed), + new(0x79400000, 0xFFC00000, InstName.LdrhImmUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.UnsignedScaled), + new(0x78600800, 0xFFE00C00, optionConstraints, InstName.LdrhReg, IsaVersion.v80, InstFlags.RtRnSPRm, AddressForm.OffsetReg), + new(0x38800400, 0xFFA00C00, InstName.LdrsbImmPostIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PostIndexed), + new(0x38800C00, 0xFFA00C00, InstName.LdrsbImmPreIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PreIndexed), + new(0x39800000, 0xFF800000, InstName.LdrsbImmUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.UnsignedScaled), + new(0x38A00800, 0xFFA00C00, optionConstraints, InstName.LdrsbReg, IsaVersion.v80, InstFlags.RtRnSPRm, AddressForm.OffsetReg), + new(0x78800400, 0xFFA00C00, InstName.LdrshImmPostIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PostIndexed), + new(0x78800C00, 0xFFA00C00, InstName.LdrshImmPreIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PreIndexed), + new(0x79800000, 0xFF800000, InstName.LdrshImmUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.UnsignedScaled), + new(0x78A00800, 0xFFA00C00, optionConstraints, InstName.LdrshReg, IsaVersion.v80, InstFlags.RtRnSPRm, AddressForm.OffsetReg), + new(0xB8800400, 0xFFE00C00, InstName.LdrswImmPostIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PostIndexed), + new(0xB8800C00, 0xFFE00C00, InstName.LdrswImmPreIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PreIndexed), + new(0xB9800000, 0xFFC00000, InstName.LdrswImmUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.UnsignedScaled), + new(0x98000000, 0xFF000000, InstName.LdrswLit, IsaVersion.v80, InstFlags.Rt, AddressForm.Literal), + new(0xB8A00800, 0xFFE00C00, optionConstraints, InstName.LdrswReg, IsaVersion.v80, InstFlags.RtRnSPRm, AddressForm.OffsetReg), + new(0x3C400400, 0x3F600C00, opc1sizeOpc1sizeOpc1sizeConstraints, InstName.LdrImmFpsimdPostIndexed, IsaVersion.v80, InstFlags.RtRnSPFpSimdMemWBack, AddressForm.PostIndexed), + new(0x3C400C00, 0x3F600C00, opc1sizeOpc1sizeOpc1sizeConstraints, InstName.LdrImmFpsimdPreIndexed, IsaVersion.v80, InstFlags.RtRnSPFpSimdMemWBack, AddressForm.PreIndexed), + new(0x3D400000, 0x3F400000, opc1sizeOpc1sizeOpc1sizeConstraints, InstName.LdrImmFpsimdUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtRnSPFpSimd, AddressForm.UnsignedScaled), + new(0xB8400400, 0xBFE00C00, InstName.LdrImmGenPostIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PostIndexed), + new(0xB8400C00, 0xBFE00C00, InstName.LdrImmGenPreIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PreIndexed), + new(0xB9400000, 0xBFC00000, InstName.LdrImmGenUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.UnsignedScaled), + new(0x1C000000, 0x3F000000, opcConstraints, InstName.LdrLitFpsimd, IsaVersion.v80, InstFlags.RtFpSimd, AddressForm.Literal), + new(0x18000000, 0xBF000000, InstName.LdrLitGen, IsaVersion.v80, InstFlags.Rt, AddressForm.Literal), + new(0x3C600800, 0x3F600C00, opc1sizeOpc1sizeOpc1sizeOptionConstraints, InstName.LdrRegFpsimd, IsaVersion.v80, InstFlags.RtRnSPRmFpSimd, AddressForm.OffsetReg), + new(0xB8600800, 0xBFE00C00, optionConstraints, InstName.LdrRegGen, IsaVersion.v80, InstFlags.RtRnSPRm, AddressForm.OffsetReg), + new(0xB8203000, 0xBF20FC00, InstName.Ldset, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0x38203000, 0xFF20FC00, InstName.Ldsetb, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0x78203000, 0xFF20FC00, InstName.Ldseth, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0x19203000, 0xFF20FC00, rtRt2Constraints, InstName.Ldsetp, IsaVersion.None, InstFlags.RtRt2RnSP), + new(0xB8204000, 0xBF20FC00, InstName.Ldsmax, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0x38204000, 0xFF20FC00, InstName.Ldsmaxb, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0x78204000, 0xFF20FC00, InstName.Ldsmaxh, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0xB8205000, 0xBF20FC00, InstName.Ldsmin, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0x38205000, 0xFF20FC00, InstName.Ldsminb, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0x78205000, 0xFF20FC00, InstName.Ldsminh, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0xB8400800, 0xBFE00C00, InstName.Ldtr, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset), + new(0x38400800, 0xFFE00C00, InstName.Ldtrb, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset), + new(0x78400800, 0xFFE00C00, InstName.Ldtrh, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset), + new(0x38800800, 0xFFA00C00, InstName.Ldtrsb, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset), + new(0x78800800, 0xFFA00C00, InstName.Ldtrsh, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset), + new(0xB8800800, 0xFFE00C00, InstName.Ldtrsw, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset), + new(0xB8206000, 0xBF20FC00, InstName.Ldumax, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0x38206000, 0xFF20FC00, InstName.Ldumaxb, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0x78206000, 0xFF20FC00, InstName.Ldumaxh, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0xB8207000, 0xBF20FC00, InstName.Ldumin, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0x38207000, 0xFF20FC00, InstName.Lduminb, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0x78207000, 0xFF20FC00, InstName.Lduminh, IsaVersion.v81, InstFlags.RtRnSPRs), + new(0x38400000, 0xFFE00C00, InstName.Ldurb, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset), + new(0x78400000, 0xFFE00C00, InstName.Ldurh, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset), + new(0x38800000, 0xFFA00C00, InstName.Ldursb, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset), + new(0x78800000, 0xFFA00C00, InstName.Ldursh, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset), + new(0xB8800000, 0xFFE00C00, InstName.Ldursw, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset), + new(0x3C400000, 0x3F600C00, opc1sizeOpc1sizeOpc1sizeConstraints, InstName.LdurFpsimd, IsaVersion.v80, InstFlags.RtRnSPFpSimd, AddressForm.BasePlusOffset), + new(0xB8400000, 0xBFE00C00, InstName.LdurGen, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset), + new(0x887F0000, 0xBFFF8000, InstName.Ldxp, IsaVersion.v80, InstFlags.RtRt2RnSP, AddressForm.BaseRegister), + new(0x885F7C00, 0xBFFFFC00, InstName.Ldxr, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BaseRegister), + new(0x085F7C00, 0xFFFFFC00, InstName.Ldxrb, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BaseRegister), + new(0x485F7C00, 0xFFFFFC00, InstName.Ldxrh, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BaseRegister), + new(0x1AC02000, 0x7FE0FC00, InstName.Lslv, IsaVersion.v80, InstFlags.RdRnRm), + new(0x1AC02400, 0x7FE0FC00, InstName.Lsrv, IsaVersion.v80, InstFlags.RdRnRm), + new(0x1B000000, 0x7FE08000, InstName.Madd, IsaVersion.v80, InstFlags.RdRnRmRa), + new(0x2F000000, 0xBF00F400, sizeSizeConstraints, InstName.MlaAdvsimdElt, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd), + new(0x0E209400, 0xBF20FC00, sizeConstraints, InstName.MlaAdvsimdVec, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd), + new(0x2F004000, 0xBF00F400, sizeSizeConstraints, InstName.MlsAdvsimdElt, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd), + new(0x2E209400, 0xBF20FC00, sizeConstraints, InstName.MlsAdvsimdVec, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd), + new(0x0F000400, 0x9FF80C00, cmodeopqConstraints, InstName.MoviAdvsimd, IsaVersion.v80, InstFlags.RdFpSimd), + new(0x72800000, 0x7F800000, sfhwConstraints, InstName.Movk, IsaVersion.v80, InstFlags.RdReadRd), + new(0x12800000, 0x7F800000, sfhwConstraints, InstName.Movn, IsaVersion.v80, InstFlags.Rd), + new(0x52800000, 0x7F800000, sfhwConstraints, InstName.Movz, IsaVersion.v80, InstFlags.Rd), + new(0xD5700000, 0xFFF00000, rtConstraints, InstName.Mrrs, IsaVersion.None, InstFlags.RtReadRt), + new(0xD5300000, 0xFFF00000, InstName.Mrs, IsaVersion.v80, InstFlags.Rt), + new(0xD5500000, 0xFFF00000, rtConstraints, InstName.Msrr, IsaVersion.None, InstFlags.RtReadRt), + new(0xD500401F, 0xFFF8F01F, InstName.MsrImm, IsaVersion.v80, InstFlags.None), + new(0xD5100000, 0xFFF00000, InstName.MsrReg, IsaVersion.v80, InstFlags.RtReadRt), + new(0x1B008000, 0x7FE08000, InstName.Msub, IsaVersion.v80, InstFlags.RdRnRmRa), + new(0x0F008000, 0xBF00F400, sizeSizeConstraints, InstName.MulAdvsimdElt, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E209C00, 0xBF20FC00, usizeUsizeUsizeSizeConstraints, InstName.MulAdvsimdVec, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2F000400, 0xBFF80C00, cmodeopqConstraints, InstName.MvniAdvsimd, IsaVersion.v80, InstFlags.RdFpSimd), + new(0x7EE0B800, 0xFFFFFC00, InstName.NegAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2E20B800, 0xBF3FFC00, qsizeConstraints, InstName.NegAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0xD503201F, 0xFFFFFFFF, InstName.Nop, IsaVersion.v80, InstFlags.None), + new(0x2E205800, 0xBFFFFC00, InstName.NotAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0EE01C00, 0xBFE0FC00, InstName.OrnAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2A200000, 0x7F200000, sfimm6Constraints, InstName.OrnLogShift, IsaVersion.v80, InstFlags.RdRnRm), + new(0x0F001400, 0xBFF81C00, InstName.OrrAdvsimdImm, IsaVersion.v80, InstFlags.RdFpSimd), + new(0x0EA01C00, 0xBFE0FC00, InstName.OrrAdvsimdReg, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x32000000, 0x7F800000, nimmsNimmsNimmsNimmsNimmsNimmsNimmsNimmsSfnConstraints, InstName.OrrLogImm, IsaVersion.v80, InstFlags.RdSPRn), + new(0x2A000000, 0x7F200000, sfimm6Constraints, InstName.OrrLogShift, IsaVersion.v80, InstFlags.RdRnRm), + new(0xDAC10800, 0xFFFFDC00, InstName.Pacda, IsaVersion.v83, InstFlags.RdRnSP), + new(0xDAC10C00, 0xFFFFDC00, InstName.Pacdb, IsaVersion.v83, InstFlags.RdRnSP), + new(0x9AC03000, 0xFFE0FC00, InstName.Pacga, IsaVersion.v83, InstFlags.RdRnRm), + new(0xDAC10000, 0xFFFFDC00, InstName.PaciaGeneral, IsaVersion.v83, InstFlags.RdRnSP), + new(0xD503211F, 0xFFFFFDDF, InstName.PaciaSystem, IsaVersion.v83, InstFlags.None), + new(0xDAC10400, 0xFFFFDC00, InstName.PacibGeneral, IsaVersion.v83, InstFlags.RdRnSP), + new(0xD503215F, 0xFFFFFDDF, InstName.PacibSystem, IsaVersion.v83, InstFlags.None), + new(0x0E20E000, 0xBFE0FC00, sizeSizeConstraints2, InstName.PmullAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0EE0E000, 0xBFE0FC00, sizeSizeConstraints2, InstName.PmullAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E209C00, 0xBF20FC00, usizeUsizeUsizeSizeConstraints, InstName.PmulAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0xF9800000, 0xFFC00000, InstName.PrfmImm, IsaVersion.v80, InstFlags.RnSP, AddressForm.UnsignedScaled), + new(0xD8000000, 0xFF000000, InstName.PrfmLit, IsaVersion.v80, InstFlags.None, AddressForm.Literal), + new(0xF8A04800, 0xFFE04C00, rtConstraints2, InstName.PrfmReg, IsaVersion.v80, InstFlags.RnSPRm, AddressForm.OffsetReg), + new(0xF8800000, 0xFFE00C00, InstName.Prfum, IsaVersion.v80, InstFlags.RnSP, AddressForm.BasePlusOffset), + new(0xD503223F, 0xFFFFFFFF, InstName.Psb, IsaVersion.v82, InstFlags.None), + new(0x2E204000, 0xBF20FC00, sizeConstraints, InstName.RaddhnAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd), + new(0xCE608C00, 0xFFE0FC00, InstName.Rax1Advsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x2E605800, 0xBFFFFC00, InstName.RbitAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5AC00000, 0x7FFFFC00, InstName.RbitInt, IsaVersion.v80, InstFlags.RdRn), + new(0x19200800, 0xFF20FC00, InstName.Rcwcas, IsaVersion.v89, InstFlags.RtReadRtRnSPRsS), + new(0x19200C00, 0xFF20FC00, rsRtConstraints, InstName.Rcwcasp, IsaVersion.None, InstFlags.RtReadRtRnSPRsS), + new(0x38209000, 0xFF20FC00, InstName.Rcwclr, IsaVersion.v89, InstFlags.RtReadRtRnSPRsS), + new(0x19209000, 0xFF20FC00, rtRt2Constraints, InstName.Rcwclrp, IsaVersion.None, InstFlags.RtReadRtRt2RnSPS), + new(0x59200800, 0xFF20FC00, InstName.Rcwscas, IsaVersion.v89, InstFlags.RtReadRtRnSPRsS), + new(0x59200C00, 0xFF20FC00, rsRtConstraints, InstName.Rcwscasp, IsaVersion.None, InstFlags.RtReadRtRnSPRsS), + new(0x78209000, 0xFF20FC00, InstName.Rcwsclr, IsaVersion.v89, InstFlags.RtReadRtRnSPRsS), + new(0x59209000, 0xFF20FC00, rtRt2Constraints, InstName.Rcwsclrp, IsaVersion.None, InstFlags.RtReadRtRt2RnSPS), + new(0x3820B000, 0xFF20FC00, InstName.Rcwset, IsaVersion.v89, InstFlags.RtReadRtRnSPRsS), + new(0x1920B000, 0xFF20FC00, rtRt2Constraints, InstName.Rcwsetp, IsaVersion.None, InstFlags.RtReadRtRt2RnSPS), + new(0x7820B000, 0xFF20FC00, InstName.Rcwsset, IsaVersion.v89, InstFlags.RtReadRtRnSPRsS), + new(0x5920B000, 0xFF20FC00, rtRt2Constraints, InstName.Rcwssetp, IsaVersion.None, InstFlags.RtReadRtRt2RnSPS), + new(0x7820A000, 0xFF20FC00, InstName.Rcwsswp, IsaVersion.v89, InstFlags.RtReadRtRnSPRsS), + new(0x5920A000, 0xFF20FC00, rtRt2Constraints, InstName.Rcwsswpp, IsaVersion.None, InstFlags.RtReadRtRt2RnSPS), + new(0x3820A000, 0xFF20FC00, InstName.Rcwswp, IsaVersion.v89, InstFlags.RtReadRtRnSPRsS), + new(0x1920A000, 0xFF20FC00, rtRt2Constraints, InstName.Rcwswpp, IsaVersion.None, InstFlags.RtReadRtRt2RnSPS), + new(0xD65F0000, 0xFFFFFC1F, InstName.Ret, IsaVersion.v80, InstFlags.Rn), + new(0xD65F0BFF, 0xFFFFFBFF, InstName.Reta, IsaVersion.v83, InstFlags.None), + new(0x5AC00800, 0x7FFFF800, sfopcConstraints, InstName.Rev, IsaVersion.v80, InstFlags.RdRn), + new(0x0E201800, 0xBF3FFC00, sizeSizeSizeConstraints, InstName.Rev16Advsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5AC00400, 0x7FFFFC00, InstName.Rev16Int, IsaVersion.v80, InstFlags.RdRn), + new(0x2E200800, 0xBF3FFC00, sizeSizeConstraints3, InstName.Rev32Advsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0xDAC00800, 0xFFFFFC00, sfConstraints, InstName.Rev32Int, IsaVersion.v80, InstFlags.RdRn), + new(0x0E200800, 0xBF3FFC00, sizeConstraints, InstName.Rev64Advsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0xBA000400, 0xFFE07C10, InstName.Rmif, IsaVersion.v84, InstFlags.RnC), + new(0x1AC02C00, 0x7FE0FC00, InstName.Rorv, IsaVersion.v80, InstFlags.RdRnRm), + new(0xF8A04818, 0xFFE04C18, InstName.RprfmReg, IsaVersion.v80, InstFlags.RnSPRm, AddressForm.OffsetReg), + new(0x0F008C00, 0xBF80FC00, immhImmhConstraints, InstName.RshrnAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd), + new(0x2E206000, 0xBF20FC00, sizeConstraints, InstName.RsubhnAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd), + new(0x0E205000, 0xBF20FC00, sizeConstraints, InstName.SabalAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E207C00, 0xBF20FC00, sizeConstraints, InstName.SabaAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E207000, 0xBF20FC00, sizeConstraints, InstName.SabdlAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E207400, 0xBF20FC00, sizeConstraints, InstName.SabdAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E206800, 0xBF3FFC00, sizeConstraints, InstName.SadalpAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd), + new(0x0E202800, 0xBF3FFC00, sizeConstraints, InstName.SaddlpAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd), + new(0x0E303800, 0xBF3FFC00, qsizeSizeConstraints, InstName.SaddlvAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0E200000, 0xBF20FC00, sizeConstraints, InstName.SaddlAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E201000, 0xBF20FC00, sizeConstraints, InstName.SaddwAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0xD50330FF, 0xFFFFFFFF, InstName.Sb, IsaVersion.v85, InstFlags.None), + new(0x5A000000, 0x7FE0FC00, InstName.Sbc, IsaVersion.v80, InstFlags.RdRnRmC), + new(0x7A000000, 0x7FE0FC00, InstName.Sbcs, IsaVersion.v80, InstFlags.RdRnRmCS), + new(0x13000000, 0x7F800000, sfnSfnSfimmr5Sfimms5Constraints, InstName.Sbfm, IsaVersion.v80, InstFlags.RdRn), + new(0x5F40E400, 0xFFC0FC00, immhConstraints, InstName.ScvtfAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5F10E400, 0xFFF0FC00, immhConstraints, InstName.ScvtfAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5F20E400, 0xFFE0FC00, immhConstraints, InstName.ScvtfAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0F40E400, 0xBFC0FC00, immhQimmhConstraints, InstName.ScvtfAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0F10E400, 0xBFF0FC00, immhQimmhConstraints, InstName.ScvtfAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0F20E400, 0xBFE0FC00, immhQimmhConstraints, InstName.ScvtfAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5E79D800, 0xFFFFFC00, InstName.ScvtfAdvsimdIntSH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x5E21D800, 0xFFBFFC00, InstName.ScvtfAdvsimdIntS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0E79D800, 0xBFFFFC00, InstName.ScvtfAdvsimdIntVH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x0E21D800, 0xBFBFFC00, qszConstraints, InstName.ScvtfAdvsimdIntV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E020000, 0x7FBF0000, sfscaleConstraints, InstName.ScvtfFloatFix, IsaVersion.v80, InstFlags.RdRnFpSimdFromGpr), + new(0x1EC20000, 0x7FFF0000, sfscaleConstraints, InstName.ScvtfFloatFix, IsaVersion.v80, InstFlags.RdRnFpSimdFromGpr), + new(0x1E220000, 0x7FBFFC00, InstName.ScvtfFloatInt, IsaVersion.v80, InstFlags.RdRnFpSimdFromGpr), + new(0x1EE20000, 0x7FFFFC00, InstName.ScvtfFloatInt, IsaVersion.v80, InstFlags.RdRnFpSimdFromGpr), + new(0x1AC00C00, 0x7FE0FC00, InstName.Sdiv, IsaVersion.v80, InstFlags.RdRnRm), + new(0x0F80E000, 0xBFC0F400, InstName.SdotAdvsimdElt, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd), + new(0x0E809400, 0xBFE0FC00, InstName.SdotAdvsimdVec, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd), + new(0x3A00080D, 0xFFFFBC1F, InstName.Setf, IsaVersion.v84, InstFlags.RnC), + new(0x1DC00400, 0x3FE03C00, InstName.Setgp, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1DC02400, 0x3FE03C00, InstName.Setgpn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1DC01400, 0x3FE03C00, InstName.Setgpt, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x1DC03400, 0x3FE03C00, InstName.Setgptn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x19C00400, 0x3FE03C00, InstName.Setp, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x19C02400, 0x3FE03C00, InstName.Setpn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x19C01400, 0x3FE03C00, InstName.Setpt, IsaVersion.v88, InstFlags.RdRnRsS), + new(0x19C03400, 0x3FE03C00, InstName.Setptn, IsaVersion.v88, InstFlags.RdRnRsS), + new(0xD503209F, 0xFFFFFFFF, InstName.Sev, IsaVersion.v80, InstFlags.None), + new(0xD50320BF, 0xFFFFFFFF, InstName.Sevl, IsaVersion.v80, InstFlags.None), + new(0x5E000000, 0xFFE0FC00, InstName.Sha1cAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5E280800, 0xFFFFFC00, InstName.Sha1hAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5E002000, 0xFFE0FC00, InstName.Sha1mAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5E001000, 0xFFE0FC00, InstName.Sha1pAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5E003000, 0xFFE0FC00, InstName.Sha1su0Advsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5E281800, 0xFFFFFC00, InstName.Sha1su1Advsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5E005000, 0xFFE0FC00, InstName.Sha256h2Advsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5E004000, 0xFFE0FC00, InstName.Sha256hAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5E282800, 0xFFFFFC00, InstName.Sha256su0Advsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5E006000, 0xFFE0FC00, InstName.Sha256su1Advsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0xCE608400, 0xFFE0FC00, InstName.Sha512h2Advsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0xCE608000, 0xFFE0FC00, InstName.Sha512hAdvsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0xCEC08000, 0xFFFFFC00, InstName.Sha512su0Advsimd, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0xCE608800, 0xFFE0FC00, InstName.Sha512su1Advsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0x0E200400, 0xBF20FC00, sizeConstraints, InstName.ShaddAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E213800, 0xBF3FFC00, sizeConstraints, InstName.ShllAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5F405400, 0xFFC0FC00, immhConstraints, InstName.ShlAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0F005400, 0xBF80FC00, immhQimmhConstraints, InstName.ShlAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0F008400, 0xBF80FC00, immhImmhConstraints, InstName.ShrnAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd), + new(0x0E202400, 0xBF20FC00, sizeConstraints, InstName.ShsubAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x7F405400, 0xFFC0FC00, immhConstraints, InstName.SliAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd), + new(0x2F005400, 0xBF80FC00, immhQimmhConstraints, InstName.SliAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd), + new(0xCE60C000, 0xFFE0FC00, InstName.Sm3partw1Advsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0xCE60C400, 0xFFE0FC00, InstName.Sm3partw2Advsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0xCE400000, 0xFFE08000, InstName.Sm3ss1Advsimd, IsaVersion.v82, InstFlags.RdRnRmRaFpSimd), + new(0xCE408000, 0xFFE0CC00, InstName.Sm3tt1aAdvsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0xCE408400, 0xFFE0CC00, InstName.Sm3tt1bAdvsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0xCE408800, 0xFFE0CC00, InstName.Sm3tt2aAdvsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0xCE408C00, 0xFFE0CC00, InstName.Sm3tt2bAdvsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0xCE60C800, 0xFFE0FC00, InstName.Sm4ekeyAdvsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0xCEC08400, 0xFFFFFC00, InstName.Sm4eAdvsimd, IsaVersion.v82, InstFlags.RdReadRdRnFpSimd), + new(0x9B200000, 0xFFE08000, InstName.Smaddl, IsaVersion.v80, InstFlags.RdRnRmRa), + new(0x0E20A400, 0xBF20FC00, sizeConstraints, InstName.SmaxpAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E30A800, 0xBF3FFC00, qsizeSizeConstraints, InstName.SmaxvAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0E206400, 0xBF20FC00, sizeConstraints, InstName.SmaxAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x11C00000, 0x7FFC0000, InstName.SmaxImm, IsaVersion.v89, InstFlags.RdRn), + new(0x1AC06000, 0x7FE0FC00, InstName.SmaxReg, IsaVersion.v89, InstFlags.RdRnRm), + new(0xD4000003, 0xFFE0001F, InstName.Smc, IsaVersion.v80, InstFlags.None), + new(0x0E20AC00, 0xBF20FC00, sizeConstraints, InstName.SminpAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E31A800, 0xBF3FFC00, qsizeSizeConstraints, InstName.SminvAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0E206C00, 0xBF20FC00, sizeConstraints, InstName.SminAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x11C80000, 0x7FFC0000, InstName.SminImm, IsaVersion.v89, InstFlags.RdRn), + new(0x1AC06800, 0x7FE0FC00, InstName.SminReg, IsaVersion.v89, InstFlags.RdRnRm), + new(0x0F002000, 0xBF00F400, sizeSizeConstraints, InstName.SmlalAdvsimdElt, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E208000, 0xBF20FC00, sizeConstraints, InstName.SmlalAdvsimdVec, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0F006000, 0xBF00F400, sizeSizeConstraints, InstName.SmlslAdvsimdElt, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E20A000, 0xBF20FC00, sizeConstraints, InstName.SmlslAdvsimdVec, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x4E80A400, 0xFFE0FC00, InstName.SmmlaAdvsimdVec, IsaVersion.v86, InstFlags.RdRnRmFpSimd), + new(0x0E012C00, 0xBFE1FC00, InstName.SmovAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x0E022C00, 0xBFE3FC00, InstName.SmovAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x4E042C00, 0xFFE7FC00, InstName.SmovAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x9B208000, 0xFFE08000, InstName.Smsubl, IsaVersion.v80, InstFlags.RdRnRmRa), + new(0x9B407C00, 0xFFE0FC00, InstName.Smulh, IsaVersion.v80, InstFlags.RdRnRm), + new(0x0F00A000, 0xBF00F400, sizeSizeConstraints, InstName.SmullAdvsimdElt, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E20C000, 0xBF20FC00, sizeConstraints, InstName.SmullAdvsimdVec, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5E207800, 0xFF3FFC00, InstName.SqabsAdvsimdS, IsaVersion.v80, InstFlags.RdRnQcFpSimd), + new(0x0E207800, 0xBF3FFC00, qsizeConstraints, InstName.SqabsAdvsimdV, IsaVersion.v80, InstFlags.RdRnQcFpSimd), + new(0x5E200C00, 0xFF20FC00, InstName.SqaddAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x0E200C00, 0xBF20FC00, qsizeConstraints, InstName.SqaddAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x5F003000, 0xFF00F400, sizeSizeConstraints, InstName.SqdmlalAdvsimdElt2regScalar, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x0F003000, 0xBF00F400, sizeSizeConstraints, InstName.SqdmlalAdvsimdElt2regElement, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x5E209000, 0xFF20FC00, sizeSizeConstraints, InstName.SqdmlalAdvsimdVecS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x0E209000, 0xBF20FC00, sizeSizeConstraints, InstName.SqdmlalAdvsimdVecV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x5F007000, 0xFF00F400, sizeSizeConstraints, InstName.SqdmlslAdvsimdElt2regScalar, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x0F007000, 0xBF00F400, sizeSizeConstraints, InstName.SqdmlslAdvsimdElt2regElement, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x5E20B000, 0xFF20FC00, sizeSizeConstraints, InstName.SqdmlslAdvsimdVecS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x0E20B000, 0xBF20FC00, sizeSizeConstraints, InstName.SqdmlslAdvsimdVecV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x5F00C000, 0xFF00F400, sizeSizeConstraints, InstName.SqdmulhAdvsimdElt2regScalar, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0F00C000, 0xBF00F400, sizeSizeConstraints, InstName.SqdmulhAdvsimdElt2regElement, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5E20B400, 0xFF20FC00, sizeSizeConstraints4, InstName.SqdmulhAdvsimdVecS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x0E20B400, 0xBF20FC00, sizeSizeConstraints4, InstName.SqdmulhAdvsimdVecV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x5F00B000, 0xFF00F400, sizeSizeConstraints, InstName.SqdmullAdvsimdElt2regScalar, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x0F00B000, 0xBF00F400, sizeSizeConstraints, InstName.SqdmullAdvsimdElt2regElement, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x5E20D000, 0xFF20FC00, sizeSizeConstraints, InstName.SqdmullAdvsimdVecS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x0E20D000, 0xBF20FC00, sizeSizeConstraints, InstName.SqdmullAdvsimdVecV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x7E207800, 0xFF3FFC00, InstName.SqnegAdvsimdS, IsaVersion.v80, InstFlags.RdRnQcFpSimd), + new(0x2E207800, 0xBF3FFC00, qsizeConstraints, InstName.SqnegAdvsimdV, IsaVersion.v80, InstFlags.RdRnQcFpSimd), + new(0x7F00D000, 0xFF00F400, sizeSizeConstraints, InstName.SqrdmlahAdvsimdElt2regScalar, IsaVersion.v81, InstFlags.RdReadRdRnRmQcFpSimd), + new(0x2F00D000, 0xBF00F400, sizeSizeConstraints, InstName.SqrdmlahAdvsimdElt2regElement, IsaVersion.v81, InstFlags.RdReadRdRnRmQcFpSimd), + new(0x7E008400, 0xFF20FC00, sizeSizeConstraints4, InstName.SqrdmlahAdvsimdVecS, IsaVersion.v81, InstFlags.RdReadRdRnRmQcFpSimd), + new(0x2E008400, 0xBF20FC00, sizeSizeConstraints4, InstName.SqrdmlahAdvsimdVecV, IsaVersion.v81, InstFlags.RdReadRdRnRmQcFpSimd), + new(0x7F00F000, 0xFF00F400, sizeSizeConstraints, InstName.SqrdmlshAdvsimdElt2regScalar, IsaVersion.v81, InstFlags.RdReadRdRnRmQcFpSimd), + new(0x2F00F000, 0xBF00F400, sizeSizeConstraints, InstName.SqrdmlshAdvsimdElt2regElement, IsaVersion.v81, InstFlags.RdReadRdRnRmQcFpSimd), + new(0x7E008C00, 0xFF20FC00, sizeSizeConstraints4, InstName.SqrdmlshAdvsimdVecS, IsaVersion.v81, InstFlags.RdReadRdRnRmQcFpSimd), + new(0x2E008C00, 0xBF20FC00, sizeSizeConstraints4, InstName.SqrdmlshAdvsimdVecV, IsaVersion.v81, InstFlags.RdReadRdRnRmQcFpSimd), + new(0x5F00D000, 0xFF00F400, sizeSizeConstraints, InstName.SqrdmulhAdvsimdElt2regScalar, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x0F00D000, 0xBF00F400, sizeSizeConstraints, InstName.SqrdmulhAdvsimdElt2regElement, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x7E20B400, 0xFF20FC00, sizeSizeConstraints4, InstName.SqrdmulhAdvsimdVecS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x2E20B400, 0xBF20FC00, sizeSizeConstraints4, InstName.SqrdmulhAdvsimdVecV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x5E205C00, 0xFF20FC00, ssizeSsizeSsizeConstraints, InstName.SqrshlAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x0E205C00, 0xBF20FC00, qsizeConstraints, InstName.SqrshlAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x5F009C00, 0xFF80FC00, immhImmhConstraints, InstName.SqrshrnAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0x0F009C00, 0xBF80FC00, immhImmhConstraints, InstName.SqrshrnAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0x7F008C00, 0xFF80FC00, immhImmhConstraints, InstName.SqrshrunAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0x2F008C00, 0xBF80FC00, immhImmhConstraints, InstName.SqrshrunAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0x7F006400, 0xFF80FC00, immhOpuConstraints, InstName.SqshluAdvsimdS, IsaVersion.v80, InstFlags.RdRnQcFpSimd), + new(0x2F006400, 0xBF80FC00, immhQimmhOpuConstraints, InstName.SqshluAdvsimdV, IsaVersion.v80, InstFlags.RdRnQcFpSimd), + new(0x5F007400, 0xFF80FC00, immhOpuConstraints, InstName.SqshlAdvsimdImmS, IsaVersion.v80, InstFlags.RdRnQcFpSimd), + new(0x0F007400, 0xBF80FC00, immhQimmhOpuConstraints, InstName.SqshlAdvsimdImmV, IsaVersion.v80, InstFlags.RdRnQcFpSimd), + new(0x5E204C00, 0xFF20FC00, ssizeSsizeSsizeConstraints, InstName.SqshlAdvsimdRegS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x0E204C00, 0xBF20FC00, qsizeConstraints, InstName.SqshlAdvsimdRegV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x5F009400, 0xFF80FC00, immhImmhConstraints, InstName.SqshrnAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0x0F009400, 0xBF80FC00, immhImmhConstraints, InstName.SqshrnAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0x7F008400, 0xFF80FC00, immhImmhConstraints, InstName.SqshrunAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0x2F008400, 0xBF80FC00, immhImmhConstraints, InstName.SqshrunAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0x5E202C00, 0xFF20FC00, InstName.SqsubAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x0E202C00, 0xBF20FC00, qsizeConstraints, InstName.SqsubAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x5E214800, 0xFF3FFC00, sizeConstraints, InstName.SqxtnAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0x0E214800, 0xBF3FFC00, sizeConstraints, InstName.SqxtnAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0x7E212800, 0xFF3FFC00, sizeConstraints, InstName.SqxtunAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0x2E212800, 0xBF3FFC00, sizeConstraints, InstName.SqxtunAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0x0E201400, 0xBF20FC00, sizeConstraints, InstName.SrhaddAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x7F404400, 0xFFC0FC00, immhConstraints, InstName.SriAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd), + new(0x2F004400, 0xBF80FC00, immhQimmhConstraints, InstName.SriAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd), + new(0x5E205400, 0xFF20FC00, ssizeSsizeSsizeConstraints, InstName.SrshlAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E205400, 0xBF20FC00, qsizeConstraints, InstName.SrshlAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5F402400, 0xFFC0FC00, immhConstraints, InstName.SrshrAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0F002400, 0xBF80FC00, immhQimmhConstraints, InstName.SrshrAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5F403400, 0xFFC0FC00, immhConstraints, InstName.SrsraAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0F003400, 0xBF80FC00, immhQimmhConstraints, InstName.SrsraAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0F00A400, 0xBF80FC00, immhImmhConstraints, InstName.SshllAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5E204400, 0xFF20FC00, ssizeSsizeSsizeConstraints, InstName.SshlAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E204400, 0xBF20FC00, qsizeConstraints, InstName.SshlAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x5F400400, 0xFFC0FC00, immhConstraints, InstName.SshrAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0F000400, 0xBF80FC00, immhQimmhConstraints, InstName.SshrAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x5F401400, 0xFFC0FC00, immhConstraints, InstName.SsraAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0F001400, 0xBF80FC00, immhQimmhConstraints, InstName.SsraAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0E202000, 0xBF20FC00, sizeConstraints, InstName.SsublAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E203000, 0xBF20FC00, sizeConstraints, InstName.SsubwAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0C002000, 0xBFFFF000, InstName.St1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0C006000, 0xBFFFF000, InstName.St1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0C007000, 0xBFFFF000, InstName.St1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0C00A000, 0xBFFFF000, InstName.St1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0C006000, 0xBFFFF000, InstName.St1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0C007000, 0xBFFFF000, InstName.St1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0C00A000, 0xBFFFF000, InstName.St1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0C802000, 0xBFE0F000, InstName.St1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0C806000, 0xBFE0F000, InstName.St1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0C807000, 0xBFE0F000, InstName.St1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0C80A000, 0xBFE0F000, InstName.St1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0C806000, 0xBFE0F000, InstName.St1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0C807000, 0xBFE0F000, InstName.St1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0C80A000, 0xBFE0F000, InstName.St1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0D000000, 0xBFFF2000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.St1AdvsimdSnglAsNoPostIndex, IsaVersion.v80, InstFlags.RtReadRtRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0D800000, 0xBFE02000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.St1AdvsimdSnglAsPostIndex, IsaVersion.v80, InstFlags.RtReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0xD9A00400, 0xFFE00C00, InstName.St2gPostIndexed, IsaVersion.v85, InstFlags.MemWBack, AddressForm.PostIndexed), + new(0xD9A00C00, 0xFFE00C00, InstName.St2gPreIndexed, IsaVersion.v85, InstFlags.MemWBack, AddressForm.PreIndexed), + new(0xD9A00800, 0xFFE00C00, InstName.St2gSignedScaledOffset, IsaVersion.v85, InstFlags.None, AddressForm.SignedScaled), + new(0x0C008000, 0xBFFFF000, qsizeConstraints2, InstName.St2AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0C808000, 0xBFE0F000, qsizeConstraints2, InstName.St2AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0D200000, 0xBFFF2000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.St2AdvsimdSnglAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0DA00000, 0xBFE02000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.St2AdvsimdSnglAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0C004000, 0xBFFFF000, qsizeConstraints2, InstName.St3AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0C804000, 0xBFE0F000, qsizeConstraints2, InstName.St3AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0D002000, 0xBFFF2000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.St3AdvsimdSnglAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0D802000, 0xBFE02000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.St3AdvsimdSnglAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0C000000, 0xBFFFF000, qsizeConstraints2, InstName.St4AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0C800000, 0xBFE0F000, qsizeConstraints2, InstName.St4AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0x0D202000, 0xBFFF2000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.St4AdvsimdSnglAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset), + new(0x0DA02000, 0xBFE02000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.St4AdvsimdSnglAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg), + new(0xF83F9000, 0xFFFFFC00, rtRtConstraints, InstName.St64b, IsaVersion.v87, InstFlags.RtReadRtRnSP), + new(0xF820B000, 0xFFE0FC00, rtRtConstraints, InstName.St64bv, IsaVersion.v87, InstFlags.RtReadRtRnSPRs), + new(0xF820A000, 0xFFE0FC00, rtRtConstraints, InstName.St64bv0, IsaVersion.v87, InstFlags.RtReadRtRnSPRs), + new(0xD9200400, 0xFFE00C00, InstName.StgPostIndexed, IsaVersion.v85, InstFlags.MemWBack, AddressForm.PostIndexed), + new(0xD9200C00, 0xFFE00C00, InstName.StgPreIndexed, IsaVersion.v85, InstFlags.MemWBack, AddressForm.PreIndexed), + new(0xD9200800, 0xFFE00C00, InstName.StgSignedScaledOffset, IsaVersion.v85, InstFlags.None, AddressForm.SignedScaled), + new(0xD9A00000, 0xFFFFFC00, InstName.Stgm, IsaVersion.v85, InstFlags.None), + new(0x68800000, 0xFFC00000, InstName.StgpPostIndexed, IsaVersion.v85, InstFlags.MemWBack, AddressForm.PostIndexed), + new(0x69800000, 0xFFC00000, InstName.StgpPreIndexed, IsaVersion.v85, InstFlags.MemWBack, AddressForm.PreIndexed), + new(0x69000000, 0xFFC00000, InstName.StgpSignedScaledOffset, IsaVersion.v85, InstFlags.None, AddressForm.SignedScaled), + new(0x99000800, 0xBFE0EC00, InstName.Stilp, IsaVersion.v82, InstFlags.RtReadRtRt2RnSP), + new(0x0D018400, 0xBFFFFC00, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.Stl1AdvsimdSngl, IsaVersion.v82, InstFlags.RtReadRtRnSPFpSimd, AddressForm.StructNoOffset), + new(0x889F7C00, 0xBFFFFC00, InstName.Stllr, IsaVersion.v81, InstFlags.RtReadRtRnSP, AddressForm.BaseRegister), + new(0x089F7C00, 0xFFFFFC00, InstName.Stllrb, IsaVersion.v81, InstFlags.RtReadRtRnSP, AddressForm.BaseRegister), + new(0x489F7C00, 0xFFFFFC00, InstName.Stllrh, IsaVersion.v81, InstFlags.RtReadRtRnSP, AddressForm.BaseRegister), + new(0x889FFC00, 0xBFFFFC00, InstName.StlrBaseRegister, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.BaseRegister), + new(0x99800800, 0xBFFFFC00, InstName.StlrPreIndexed, IsaVersion.v82, InstFlags.RtReadRtRnSPMemWBack, AddressForm.PreIndexed), + new(0x089FFC00, 0xFFFFFC00, InstName.Stlrb, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.BaseRegister), + new(0x489FFC00, 0xFFFFFC00, InstName.Stlrh, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.BaseRegister), + new(0x19000000, 0xFFE00C00, InstName.Stlurb, IsaVersion.v84, InstFlags.RtReadRtRnSP, AddressForm.BasePlusOffset), + new(0x59000000, 0xFFE00C00, InstName.Stlurh, IsaVersion.v84, InstFlags.RtReadRtRnSP, AddressForm.BasePlusOffset), + new(0x1D000800, 0x3F600C00, opc1sizeOpc1sizeOpc1sizeConstraints, InstName.StlurFpsimd, IsaVersion.v82, InstFlags.RtReadRtRnSPFpSimd, AddressForm.BasePlusOffset), + new(0x99000000, 0xBFE00C00, InstName.StlurGen, IsaVersion.v84, InstFlags.RtReadRtRnSP, AddressForm.BasePlusOffset), + new(0x88208000, 0xBFE08000, InstName.Stlxp, IsaVersion.v80, InstFlags.RtReadRtRt2RnSPRs, AddressForm.BaseRegister), + new(0x8800FC00, 0xBFE0FC00, InstName.Stlxr, IsaVersion.v80, InstFlags.RtReadRtRnSPRs, AddressForm.BaseRegister), + new(0x0800FC00, 0xFFE0FC00, InstName.Stlxrb, IsaVersion.v80, InstFlags.RtReadRtRnSPRs, AddressForm.BaseRegister), + new(0x4800FC00, 0xFFE0FC00, InstName.Stlxrh, IsaVersion.v80, InstFlags.RtReadRtRnSPRs, AddressForm.BaseRegister), + new(0x2C000000, 0x3FC00000, opcConstraints, InstName.StnpFpsimd, IsaVersion.v80, InstFlags.RtReadRtRt2RnSPFpSimd, AddressForm.SignedScaled), + new(0x28000000, 0x7FC00000, opcConstraints2, InstName.StnpGen, IsaVersion.v80, InstFlags.RtReadRtRt2RnSP, AddressForm.SignedScaled), + new(0x2C800000, 0x3FC00000, opcConstraints, InstName.StpFpsimdPostIndexed, IsaVersion.v80, InstFlags.RtReadRtRt2RnSPFpSimdMemWBack, AddressForm.PostIndexed), + new(0x2D800000, 0x3FC00000, opcConstraints, InstName.StpFpsimdPreIndexed, IsaVersion.v80, InstFlags.RtReadRtRt2RnSPFpSimdMemWBack, AddressForm.PreIndexed), + new(0x2D000000, 0x3FC00000, opcConstraints, InstName.StpFpsimdSignedScaledOffset, IsaVersion.v80, InstFlags.RtReadRtRt2RnSPFpSimd, AddressForm.SignedScaled), + new(0x28800000, 0x7FC00000, opclOpcConstraints, InstName.StpGenPostIndexed, IsaVersion.v80, InstFlags.RtReadRtRt2RnSPMemWBack, AddressForm.PostIndexed), + new(0x29800000, 0x7FC00000, opclOpcConstraints, InstName.StpGenPreIndexed, IsaVersion.v80, InstFlags.RtReadRtRt2RnSPMemWBack, AddressForm.PreIndexed), + new(0x29000000, 0x7FC00000, opclOpcConstraints, InstName.StpGenSignedScaledOffset, IsaVersion.v80, InstFlags.RtReadRtRt2RnSP, AddressForm.SignedScaled), + new(0x38000400, 0xFFE00C00, InstName.StrbImmPostIndexed, IsaVersion.v80, InstFlags.RtReadRtRnSPMemWBack, AddressForm.PostIndexed), + new(0x38000C00, 0xFFE00C00, InstName.StrbImmPreIndexed, IsaVersion.v80, InstFlags.RtReadRtRnSPMemWBack, AddressForm.PreIndexed), + new(0x39000000, 0xFFC00000, InstName.StrbImmUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.UnsignedScaled), + new(0x38200800, 0xFFE00C00, optionConstraints, InstName.StrbReg, IsaVersion.v80, InstFlags.RtReadRtRnSPRm, AddressForm.OffsetReg), + new(0x78000400, 0xFFE00C00, InstName.StrhImmPostIndexed, IsaVersion.v80, InstFlags.RtReadRtRnSPMemWBack, AddressForm.PostIndexed), + new(0x78000C00, 0xFFE00C00, InstName.StrhImmPreIndexed, IsaVersion.v80, InstFlags.RtReadRtRnSPMemWBack, AddressForm.PreIndexed), + new(0x79000000, 0xFFC00000, InstName.StrhImmUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.UnsignedScaled), + new(0x78200800, 0xFFE00C00, optionConstraints, InstName.StrhReg, IsaVersion.v80, InstFlags.RtReadRtRnSPRm, AddressForm.OffsetReg), + new(0x3C000400, 0x3F600C00, opc1sizeOpc1sizeOpc1sizeConstraints, InstName.StrImmFpsimdPostIndexed, IsaVersion.v80, InstFlags.RtReadRtRnSPFpSimdMemWBack, AddressForm.PostIndexed), + new(0x3C000C00, 0x3F600C00, opc1sizeOpc1sizeOpc1sizeConstraints, InstName.StrImmFpsimdPreIndexed, IsaVersion.v80, InstFlags.RtReadRtRnSPFpSimdMemWBack, AddressForm.PreIndexed), + new(0x3D000000, 0x3F400000, opc1sizeOpc1sizeOpc1sizeConstraints, InstName.StrImmFpsimdUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtReadRtRnSPFpSimd, AddressForm.UnsignedScaled), + new(0xB8000400, 0xBFE00C00, InstName.StrImmGenPostIndexed, IsaVersion.v80, InstFlags.RtReadRtRnSPMemWBack, AddressForm.PostIndexed), + new(0xB8000C00, 0xBFE00C00, InstName.StrImmGenPreIndexed, IsaVersion.v80, InstFlags.RtReadRtRnSPMemWBack, AddressForm.PreIndexed), + new(0xB9000000, 0xBFC00000, InstName.StrImmGenUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.UnsignedScaled), + new(0x3C200800, 0x3F600C00, opc1sizeOpc1sizeOpc1sizeOptionConstraints, InstName.StrRegFpsimd, IsaVersion.v80, InstFlags.RtReadRtRnSPRmFpSimd, AddressForm.OffsetReg), + new(0xB8200800, 0xBFE00C00, optionConstraints, InstName.StrRegGen, IsaVersion.v80, InstFlags.RtReadRtRnSPRm, AddressForm.OffsetReg), + new(0xB8000800, 0xBFE00C00, InstName.Sttr, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.BasePlusOffset), + new(0x38000800, 0xFFE00C00, InstName.Sttrb, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.BasePlusOffset), + new(0x78000800, 0xFFE00C00, InstName.Sttrh, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.BasePlusOffset), + new(0x38000000, 0xFFE00C00, InstName.Sturb, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.BasePlusOffset), + new(0x78000000, 0xFFE00C00, InstName.Sturh, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.BasePlusOffset), + new(0x3C000000, 0x3F600C00, opc1sizeOpc1sizeOpc1sizeConstraints, InstName.SturFpsimd, IsaVersion.v80, InstFlags.RtReadRtRnSPFpSimd, AddressForm.BasePlusOffset), + new(0xB8000000, 0xBFE00C00, InstName.SturGen, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.BasePlusOffset), + new(0x88200000, 0xBFE08000, InstName.Stxp, IsaVersion.v80, InstFlags.RtReadRtRt2RnSPRs, AddressForm.BaseRegister), + new(0x88007C00, 0xBFE0FC00, InstName.Stxr, IsaVersion.v80, InstFlags.RtReadRtRnSPRs, AddressForm.BaseRegister), + new(0x08007C00, 0xFFE0FC00, InstName.Stxrb, IsaVersion.v80, InstFlags.RtReadRtRnSPRs, AddressForm.BaseRegister), + new(0x48007C00, 0xFFE0FC00, InstName.Stxrh, IsaVersion.v80, InstFlags.RtReadRtRnSPRs, AddressForm.BaseRegister), + new(0xD9E00400, 0xFFE00C00, InstName.Stz2gPostIndexed, IsaVersion.v85, InstFlags.MemWBack, AddressForm.PostIndexed), + new(0xD9E00C00, 0xFFE00C00, InstName.Stz2gPreIndexed, IsaVersion.v85, InstFlags.MemWBack, AddressForm.PreIndexed), + new(0xD9E00800, 0xFFE00C00, InstName.Stz2gSignedScaledOffset, IsaVersion.v85, InstFlags.None, AddressForm.SignedScaled), + new(0xD9600400, 0xFFE00C00, InstName.StzgPostIndexed, IsaVersion.v85, InstFlags.MemWBack, AddressForm.PostIndexed), + new(0xD9600C00, 0xFFE00C00, InstName.StzgPreIndexed, IsaVersion.v85, InstFlags.MemWBack, AddressForm.PreIndexed), + new(0xD9600800, 0xFFE00C00, InstName.StzgSignedScaledOffset, IsaVersion.v85, InstFlags.None, AddressForm.SignedScaled), + new(0xD9200000, 0xFFFFFC00, InstName.Stzgm, IsaVersion.v85, InstFlags.None), + new(0xD1800000, 0xFFC0C000, InstName.Subg, IsaVersion.v85, InstFlags.None), + new(0x0E206000, 0xBF20FC00, sizeConstraints, InstName.SubhnAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd), + new(0x9AC00000, 0xFFE0FC00, InstName.Subp, IsaVersion.v85, InstFlags.None), + new(0xBAC00000, 0xFFE0FC00, InstName.Subps, IsaVersion.v85, InstFlags.S), + new(0x6B200000, 0x7FE00000, opuOpuOpuConstraints, InstName.SubsAddsubExt, IsaVersion.v80, InstFlags.RdRnSPRmS), + new(0x71000000, 0x7F800000, InstName.SubsAddsubImm, IsaVersion.v80, InstFlags.RdRnSPS), + new(0x6B000000, 0x7F200000, shiftSfimm6Constraints, InstName.SubsAddsubShift, IsaVersion.v80, InstFlags.RdRnRmS), + new(0x4B200000, 0x7FE00000, opuOpuOpuConstraints, InstName.SubAddsubExt, IsaVersion.v80, InstFlags.RdSPRnSPRm), + new(0x51000000, 0x7F800000, InstName.SubAddsubImm, IsaVersion.v80, InstFlags.RdSPRnSP), + new(0x4B000000, 0x7F200000, shiftSfimm6Constraints, InstName.SubAddsubShift, IsaVersion.v80, InstFlags.RdRnRm), + new(0x7EE08400, 0xFFE0FC00, InstName.SubAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E208400, 0xBF20FC00, qsizeConstraints, InstName.SubAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0F00F000, 0xBFC0F400, InstName.SudotAdvsimdElt, IsaVersion.v86, InstFlags.RdReadRdRnRmFpSimd), + new(0x5E203800, 0xFF3FFC00, InstName.SuqaddAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0x0E203800, 0xBF3FFC00, qsizeConstraints, InstName.SuqaddAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0xD4000001, 0xFFE0001F, InstName.Svc, IsaVersion.v80, InstFlags.None), + new(0xB8208000, 0xBF20FC00, InstName.Swp, IsaVersion.v81, InstFlags.RtReadRtRnSPRs), + new(0x38208000, 0xFF20FC00, InstName.Swpb, IsaVersion.v81, InstFlags.RtReadRtRnSPRs), + new(0x78208000, 0xFF20FC00, InstName.Swph, IsaVersion.v81, InstFlags.RtReadRtRnSPRs), + new(0x19208000, 0xFF20FC00, rtRt2Constraints, InstName.Swpp, IsaVersion.None, InstFlags.RtReadRtRt2RnSP), + new(0xD5080000, 0xFFF80000, InstName.Sys, IsaVersion.v80, InstFlags.RtReadRt), + new(0xD5280000, 0xFFF80000, InstName.Sysl, IsaVersion.v80, InstFlags.Rt), + new(0xD5480000, 0xFFF80000, InstName.Sysp, IsaVersion.None, InstFlags.RtReadRt), + new(0x0E000000, 0xBFE09C00, InstName.TblAdvsimd, IsaVersion.v80, InstFlags.RdRnSeqRmFpSimd), + new(0x37000000, 0x7F000000, InstName.Tbnz, IsaVersion.v80, InstFlags.RtReadRt), + new(0x0E001000, 0xBFE09C00, InstName.TbxAdvsimd, IsaVersion.v80, InstFlags.RdRnSeqRmFpSimd), + new(0x36000000, 0x7F000000, InstName.Tbz, IsaVersion.v80, InstFlags.RtReadRt), + new(0xD4600000, 0xFFE0001F, InstName.Tcancel, IsaVersion.None, InstFlags.None), + new(0xD503307F, 0xFFFFFFFF, InstName.Tcommit, IsaVersion.None, InstFlags.None), + new(0x0E002800, 0xBF20FC00, qsizeConstraints, InstName.Trn1Advsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E006800, 0xBF20FC00, qsizeConstraints, InstName.Trn2Advsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0xD503225F, 0xFFFFFFFF, InstName.Tsb, IsaVersion.v84, InstFlags.None), + new(0xD5233060, 0xFFFFFFE0, InstName.Tstart, IsaVersion.None, InstFlags.RtReadRt), + new(0xD5233160, 0xFFFFFFE0, InstName.Ttest, IsaVersion.None, InstFlags.RtReadRt), + new(0x2E205000, 0xBF20FC00, sizeConstraints, InstName.UabalAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E207C00, 0xBF20FC00, sizeConstraints, InstName.UabaAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E207000, 0xBF20FC00, sizeConstraints, InstName.UabdlAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E207400, 0xBF20FC00, sizeConstraints, InstName.UabdAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E206800, 0xBF3FFC00, sizeConstraints, InstName.UadalpAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd), + new(0x2E202800, 0xBF3FFC00, sizeConstraints, InstName.UaddlpAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd), + new(0x2E303800, 0xBF3FFC00, qsizeSizeConstraints, InstName.UaddlvAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2E200000, 0xBF20FC00, sizeConstraints, InstName.UaddlAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E201000, 0xBF20FC00, sizeConstraints, InstName.UaddwAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x53000000, 0x7F800000, sfnSfnSfimmr5Sfimms5Constraints, InstName.Ubfm, IsaVersion.v80, InstFlags.RdRn), + new(0x7F40E400, 0xFFC0FC00, immhConstraints, InstName.UcvtfAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x7F10E400, 0xFFF0FC00, immhConstraints, InstName.UcvtfAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x7F20E400, 0xFFE0FC00, immhConstraints, InstName.UcvtfAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2F40E400, 0xBFC0FC00, immhQimmhConstraints, InstName.UcvtfAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2F10E400, 0xBFF0FC00, immhQimmhConstraints, InstName.UcvtfAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2F20E400, 0xBFE0FC00, immhQimmhConstraints, InstName.UcvtfAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x7E79D800, 0xFFFFFC00, InstName.UcvtfAdvsimdIntSH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x7E21D800, 0xFFBFFC00, InstName.UcvtfAdvsimdIntS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2E79D800, 0xBFFFFC00, InstName.UcvtfAdvsimdIntVH, IsaVersion.v82, InstFlags.RdRnFpSimd), + new(0x2E21D800, 0xBFBFFC00, qszConstraints, InstName.UcvtfAdvsimdIntV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x1E030000, 0x7FBF0000, sfscaleConstraints, InstName.UcvtfFloatFix, IsaVersion.v80, InstFlags.RdRnFpSimdFromGpr), + new(0x1EC30000, 0x7FFF0000, sfscaleConstraints, InstName.UcvtfFloatFix, IsaVersion.v80, InstFlags.RdRnFpSimdFromGpr), + new(0x1E230000, 0x7FBFFC00, InstName.UcvtfFloatInt, IsaVersion.v80, InstFlags.RdRnFpSimdFromGpr), + new(0x1EE30000, 0x7FFFFC00, InstName.UcvtfFloatInt, IsaVersion.v80, InstFlags.RdRnFpSimdFromGpr), + new(0x00000000, 0xFFFF0000, InstName.UdfPermUndef, IsaVersion.v80, InstFlags.None), + new(0x1AC00800, 0x7FE0FC00, InstName.Udiv, IsaVersion.v80, InstFlags.RdRnRm), + new(0x2F80E000, 0xBFC0F400, InstName.UdotAdvsimdElt, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd), + new(0x2E809400, 0xBFE0FC00, InstName.UdotAdvsimdVec, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd), + new(0x2E200400, 0xBF20FC00, sizeConstraints, InstName.UhaddAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E202400, 0xBF20FC00, sizeConstraints, InstName.UhsubAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x9BA00000, 0xFFE08000, InstName.Umaddl, IsaVersion.v80, InstFlags.RdRnRmRa), + new(0x2E20A400, 0xBF20FC00, sizeConstraints, InstName.UmaxpAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E30A800, 0xBF3FFC00, qsizeSizeConstraints, InstName.UmaxvAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2E206400, 0xBF20FC00, sizeConstraints, InstName.UmaxAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x11C40000, 0x7FFC0000, InstName.UmaxImm, IsaVersion.v89, InstFlags.RdRn), + new(0x1AC06400, 0x7FE0FC00, InstName.UmaxReg, IsaVersion.v89, InstFlags.RdRnRm), + new(0x2E20AC00, 0xBF20FC00, sizeConstraints, InstName.UminpAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E31A800, 0xBF3FFC00, qsizeSizeConstraints, InstName.UminvAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2E206C00, 0xBF20FC00, sizeConstraints, InstName.UminAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x11CC0000, 0x7FFC0000, InstName.UminImm, IsaVersion.v89, InstFlags.RdRn), + new(0x1AC06C00, 0x7FE0FC00, InstName.UminReg, IsaVersion.v89, InstFlags.RdRnRm), + new(0x2F002000, 0xBF00F400, sizeSizeConstraints, InstName.UmlalAdvsimdElt, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E208000, 0xBF20FC00, sizeConstraints, InstName.UmlalAdvsimdVec, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2F006000, 0xBF00F400, sizeSizeConstraints, InstName.UmlslAdvsimdElt, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E20A000, 0xBF20FC00, sizeConstraints, InstName.UmlslAdvsimdVec, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x6E80A400, 0xFFE0FC00, InstName.UmmlaAdvsimdVec, IsaVersion.v86, InstFlags.RdRnRmFpSimd), + new(0x0E013C00, 0xFFE1FC00, InstName.UmovAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x0E023C00, 0xFFE3FC00, InstName.UmovAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x0E043C00, 0xFFE7FC00, InstName.UmovAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x4E083C00, 0xFFEFFC00, InstName.UmovAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr), + new(0x9BA08000, 0xFFE08000, InstName.Umsubl, IsaVersion.v80, InstFlags.RdRnRmRa), + new(0x9BC07C00, 0xFFE0FC00, InstName.Umulh, IsaVersion.v80, InstFlags.RdRnRm), + new(0x2F00A000, 0xBF00F400, sizeSizeConstraints, InstName.UmullAdvsimdElt, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E20C000, 0xBF20FC00, sizeConstraints, InstName.UmullAdvsimdVec, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x7E200C00, 0xFF20FC00, InstName.UqaddAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x2E200C00, 0xBF20FC00, qsizeConstraints, InstName.UqaddAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x7E205C00, 0xFF20FC00, ssizeSsizeSsizeConstraints, InstName.UqrshlAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x2E205C00, 0xBF20FC00, qsizeConstraints, InstName.UqrshlAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x7F009C00, 0xFF80FC00, immhImmhConstraints, InstName.UqrshrnAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0x2F009C00, 0xBF80FC00, immhImmhConstraints, InstName.UqrshrnAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0x7F007400, 0xFF80FC00, immhOpuConstraints, InstName.UqshlAdvsimdImmS, IsaVersion.v80, InstFlags.RdRnQcFpSimd), + new(0x2F007400, 0xBF80FC00, immhQimmhOpuConstraints, InstName.UqshlAdvsimdImmV, IsaVersion.v80, InstFlags.RdRnQcFpSimd), + new(0x7E204C00, 0xFF20FC00, ssizeSsizeSsizeConstraints, InstName.UqshlAdvsimdRegS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x2E204C00, 0xBF20FC00, qsizeConstraints, InstName.UqshlAdvsimdRegV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x7F009400, 0xFF80FC00, immhImmhConstraints, InstName.UqshrnAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0x2F009400, 0xBF80FC00, immhImmhConstraints, InstName.UqshrnAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0x7E202C00, 0xFF20FC00, InstName.UqsubAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x2E202C00, 0xBF20FC00, qsizeConstraints, InstName.UqsubAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd), + new(0x7E214800, 0xFF3FFC00, sizeConstraints, InstName.UqxtnAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0x2E214800, 0xBF3FFC00, sizeConstraints, InstName.UqxtnAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0x0EA1C800, 0xBFBFFC00, szConstraints, InstName.UrecpeAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2E201400, 0xBF20FC00, sizeConstraints, InstName.UrhaddAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x7E205400, 0xFF20FC00, ssizeSsizeSsizeConstraints, InstName.UrshlAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E205400, 0xBF20FC00, qsizeConstraints, InstName.UrshlAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x7F402400, 0xFFC0FC00, immhConstraints, InstName.UrshrAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2F002400, 0xBF80FC00, immhQimmhConstraints, InstName.UrshrAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2EA1C800, 0xBFBFFC00, szConstraints, InstName.UrsqrteAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x7F403400, 0xFFC0FC00, immhConstraints, InstName.UrsraAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2F003400, 0xBF80FC00, immhQimmhConstraints, InstName.UrsraAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x0F80F000, 0xBFC0F400, InstName.UsdotAdvsimdElt, IsaVersion.v86, InstFlags.RdReadRdRnRmFpSimd), + new(0x0E809C00, 0xBFE0FC00, InstName.UsdotAdvsimdVec, IsaVersion.v86, InstFlags.RdReadRdRnRmFpSimd), + new(0x2F00A400, 0xBF80FC00, immhImmhConstraints, InstName.UshllAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x7E204400, 0xFF20FC00, ssizeSsizeSsizeConstraints, InstName.UshlAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E204400, 0xBF20FC00, qsizeConstraints, InstName.UshlAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x7F400400, 0xFFC0FC00, immhConstraints, InstName.UshrAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2F000400, 0xBF80FC00, immhQimmhConstraints, InstName.UshrAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x4E80AC00, 0xFFE0FC00, InstName.UsmmlaAdvsimdVec, IsaVersion.v86, InstFlags.RdRnRmFpSimd), + new(0x7E203800, 0xFF3FFC00, InstName.UsqaddAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0x2E203800, 0xBF3FFC00, qsizeConstraints, InstName.UsqaddAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd), + new(0x7F401400, 0xFFC0FC00, immhConstraints, InstName.UsraAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2F001400, 0xBF80FC00, immhQimmhConstraints, InstName.UsraAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd), + new(0x2E202000, 0xBF20FC00, sizeConstraints, InstName.UsublAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x2E203000, 0xBF20FC00, sizeConstraints, InstName.UsubwAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E001800, 0xBF20FC00, qsizeConstraints, InstName.Uzp1Advsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E005800, 0xBF20FC00, qsizeConstraints, InstName.Uzp2Advsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0xD503205F, 0xFFFFFFFF, InstName.Wfe, IsaVersion.v80, InstFlags.None), + new(0xD5031000, 0xFFFFFFE0, InstName.Wfet, IsaVersion.v87, InstFlags.Rd), + new(0xD503207F, 0xFFFFFFFF, InstName.Wfi, IsaVersion.v80, InstFlags.None), + new(0xD5031020, 0xFFFFFFE0, InstName.Wfit, IsaVersion.v87, InstFlags.Rd), + new(0xD500403F, 0xFFFFFFFF, InstName.Xaflag, IsaVersion.v85, InstFlags.C), + new(0xCE800000, 0xFFE00000, InstName.XarAdvsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd), + new(0xDAC143E0, 0xFFFFFBE0, InstName.XpacGeneral, IsaVersion.v83, InstFlags.Rd), + new(0xD50320FF, 0xFFFFFFFF, InstName.XpacSystem, IsaVersion.v83, InstFlags.None), + new(0x0E212800, 0xBF3FFC00, sizeConstraints, InstName.XtnAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd), + new(0xD503203F, 0xFFFFFFFF, InstName.Yield, IsaVersion.v80, InstFlags.None), + new(0x0E003800, 0xBF20FC00, qsizeConstraints, InstName.Zip1Advsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + new(0x0E007800, 0xBF20FC00, qsizeConstraints, InstName.Zip2Advsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd), + }; + + _table = new(insts); + } + + public static (InstName, InstFlags, AddressForm) GetInstNameAndFlags(uint encoding, IsaVersion version, IsaFeature features) + { + if (_table.TryFind(encoding, version, features, out InstInfo info)) + { + return (info.Name, info.Flags, info.AddressForm); + } + + return new(InstName.UdfPermUndef, InstFlags.None, AddressForm.None); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Cache/CacheEntry.cs b/src/Ryujinx.Cpu/LightningJit/Cache/CacheEntry.cs new file mode 100644 index 000000000..0249e24b8 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Cache/CacheEntry.cs @@ -0,0 +1,22 @@ +using System; +using System.Diagnostics.CodeAnalysis; + +namespace Ryujinx.Cpu.LightningJit.Cache +{ + readonly struct CacheEntry : IComparable + { + public int Offset { get; } + public int Size { get; } + + public CacheEntry(int offset, int size) + { + Offset = offset; + Size = size; + } + + public int CompareTo([AllowNull] CacheEntry other) + { + return Offset.CompareTo(other.Offset); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Cache/CacheMemoryAllocator.cs b/src/Ryujinx.Cpu/LightningJit/Cache/CacheMemoryAllocator.cs new file mode 100644 index 000000000..8ba3a6dcd --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Cache/CacheMemoryAllocator.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; + +namespace Ryujinx.Cpu.LightningJit.Cache +{ + class CacheMemoryAllocator + { + private readonly struct MemoryBlock : IComparable + { + public int Offset { get; } + public int Size { get; } + + public MemoryBlock(int offset, int size) + { + Offset = offset; + Size = size; + } + + public int CompareTo([AllowNull] MemoryBlock other) + { + return Offset.CompareTo(other.Offset); + } + } + + private readonly List _blocks = new(); + + public CacheMemoryAllocator(int capacity) + { + _blocks.Add(new MemoryBlock(0, capacity)); + } + + public int Allocate(int size) + { + for (int i = 0; i < _blocks.Count; i++) + { + MemoryBlock block = _blocks[i]; + + if (block.Size > size) + { + _blocks[i] = new(block.Offset + size, block.Size - size); + return block.Offset; + } + else if (block.Size == size) + { + _blocks.RemoveAt(i); + return block.Offset; + } + } + + // We don't have enough free memory to perform the allocation. + return -1; + } + + public void ForceAllocation(int offset, int size) + { + int index = _blocks.BinarySearch(new(offset, size)); + + if (index < 0) + { + index = ~index; + } + + int endOffset = offset + size; + + MemoryBlock block = _blocks[index]; + + Debug.Assert(block.Offset <= offset && block.Offset + block.Size >= endOffset); + + if (offset > block.Offset && endOffset < block.Offset + block.Size) + { + _blocks[index] = new(block.Offset, offset - block.Offset); + _blocks.Insert(index + 1, new(endOffset, (block.Offset + block.Size) - endOffset)); + } + else if (offset > block.Offset) + { + _blocks[index] = new(block.Offset, offset - block.Offset); + } + else if (endOffset < block.Offset + block.Size) + { + _blocks[index] = new(endOffset, (block.Offset + block.Size) - endOffset); + } + else + { + _blocks.RemoveAt(index); + } + } + + public void Free(int offset, int size) + { + Insert(new MemoryBlock(offset, size)); + } + + private void Insert(MemoryBlock block) + { + int index = _blocks.BinarySearch(block); + + if (index < 0) + { + index = ~index; + } + + if (index < _blocks.Count) + { + MemoryBlock next = _blocks[index]; + + int endOffs = block.Offset + block.Size; + + if (next.Offset == endOffs) + { + block = new MemoryBlock(block.Offset, block.Size + next.Size); + _blocks.RemoveAt(index); + } + } + + if (index > 0) + { + MemoryBlock prev = _blocks[index - 1]; + + if (prev.Offset + prev.Size == block.Offset) + { + block = new MemoryBlock(block.Offset - prev.Size, block.Size + prev.Size); + _blocks.RemoveAt(--index); + } + } + + _blocks.Insert(index, block); + } + + public void Clear() + { + _blocks.Clear(); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Cache/JitCache.cs b/src/Ryujinx.Cpu/LightningJit/Cache/JitCache.cs new file mode 100644 index 000000000..6f1191ca5 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Cache/JitCache.cs @@ -0,0 +1,197 @@ +using ARMeilleure.Memory; +using Ryujinx.Memory; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; + +namespace Ryujinx.Cpu.LightningJit.Cache +{ + static partial class JitCache + { + private static readonly int _pageSize = (int)MemoryBlock.GetPageSize(); + private static readonly int _pageMask = _pageSize - 1; + + private const int CodeAlignment = 4; // Bytes. + private const int CacheSize = 2047 * 1024 * 1024; + + private static ReservedRegion _jitRegion; + private static JitCacheInvalidation _jitCacheInvalidator; + + private static CacheMemoryAllocator _cacheAllocator; + + private static readonly List _cacheEntries = new(); + + private static readonly object _lock = new(); + private static bool _initialized; + + [SupportedOSPlatform("windows")] + [LibraryImport("kernel32.dll", SetLastError = true)] + public static partial IntPtr FlushInstructionCache(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize); + + public static void Initialize(IJitMemoryAllocator allocator) + { + if (_initialized) + { + return; + } + + lock (_lock) + { + if (_initialized) + { + return; + } + + _jitRegion = new ReservedRegion(allocator, CacheSize); + + if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS()) + { + _jitCacheInvalidator = new JitCacheInvalidation(allocator); + } + + _cacheAllocator = new CacheMemoryAllocator(CacheSize); + + _initialized = true; + } + } + + public unsafe static IntPtr Map(ReadOnlySpan code) + { + lock (_lock) + { + Debug.Assert(_initialized); + + int funcOffset = Allocate(code.Length); + + IntPtr funcPtr = _jitRegion.Pointer + funcOffset; + + if (OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64) + { + unsafe + { + fixed (byte* codePtr = code) + { + JitSupportDarwin.Copy(funcPtr, (IntPtr)codePtr, (ulong)code.Length); + } + } + } + else + { + ReprotectAsWritable(funcOffset, code.Length); + code.CopyTo(new Span((void*)funcPtr, code.Length)); + ReprotectAsExecutable(funcOffset, code.Length); + + if (OperatingSystem.IsWindows() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64) + { + FlushInstructionCache(Process.GetCurrentProcess().Handle, funcPtr, (UIntPtr)code.Length); + } + else + { + _jitCacheInvalidator?.Invalidate(funcPtr, (ulong)code.Length); + } + } + + Add(funcOffset, code.Length); + + return funcPtr; + } + } + + public static void Unmap(IntPtr pointer) + { + lock (_lock) + { + Debug.Assert(_initialized); + + int funcOffset = (int)(pointer.ToInt64() - _jitRegion.Pointer.ToInt64()); + + if (TryFind(funcOffset, out CacheEntry entry, out int entryIndex) && entry.Offset == funcOffset) + { + _cacheAllocator.Free(funcOffset, AlignCodeSize(entry.Size)); + _cacheEntries.RemoveAt(entryIndex); + } + } + } + + private static void ReprotectAsWritable(int offset, int size) + { + int endOffs = offset + size; + + int regionStart = offset & ~_pageMask; + int regionEnd = (endOffs + _pageMask) & ~_pageMask; + + _jitRegion.Block.MapAsRwx((ulong)regionStart, (ulong)(regionEnd - regionStart)); + } + + private static void ReprotectAsExecutable(int offset, int size) + { + int endOffs = offset + size; + + int regionStart = offset & ~_pageMask; + int regionEnd = (endOffs + _pageMask) & ~_pageMask; + + _jitRegion.Block.MapAsRx((ulong)regionStart, (ulong)(regionEnd - regionStart)); + } + + private static int Allocate(int codeSize) + { + codeSize = AlignCodeSize(codeSize); + + int allocOffset = _cacheAllocator.Allocate(codeSize); + + if (allocOffset < 0) + { + throw new OutOfMemoryException("JIT Cache exhausted."); + } + + _jitRegion.ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize); + + return allocOffset; + } + + private static int AlignCodeSize(int codeSize) + { + return checked(codeSize + (CodeAlignment - 1)) & ~(CodeAlignment - 1); + } + + private static void Add(int offset, int size) + { + CacheEntry entry = new(offset, size); + + int index = _cacheEntries.BinarySearch(entry); + + if (index < 0) + { + index = ~index; + } + + _cacheEntries.Insert(index, entry); + } + + public static bool TryFind(int offset, out CacheEntry entry, out int entryIndex) + { + lock (_lock) + { + int index = _cacheEntries.BinarySearch(new CacheEntry(offset, 0)); + + if (index < 0) + { + index = ~index - 1; + } + + if (index >= 0) + { + entry = _cacheEntries[index]; + entryIndex = index; + return true; + } + } + + entry = default; + entryIndex = 0; + return false; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Cache/JitCacheInvalidation.cs b/src/Ryujinx.Cpu/LightningJit/Cache/JitCacheInvalidation.cs new file mode 100644 index 000000000..cd5f3ede4 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Cache/JitCacheInvalidation.cs @@ -0,0 +1,79 @@ +using ARMeilleure.Memory; +using System; +using System.Runtime.InteropServices; + +namespace Ryujinx.Cpu.LightningJit.Cache +{ + class JitCacheInvalidation + { + private static readonly int[] _invalidationCode = new int[] + { + unchecked((int)0xd53b0022), // mrs x2, ctr_el0 + unchecked((int)0xd3504c44), // ubfx x4, x2, #16, #4 + unchecked((int)0x52800083), // mov w3, #0x4 + unchecked((int)0x12000c45), // and w5, w2, #0xf + unchecked((int)0x1ac42064), // lsl w4, w3, w4 + unchecked((int)0x51000482), // sub w2, w4, #0x1 + unchecked((int)0x8a220002), // bic x2, x0, x2 + unchecked((int)0x1ac52063), // lsl w3, w3, w5 + unchecked((int)0xeb01005f), // cmp x2, x1 + unchecked((int)0x93407c84), // sxtw x4, w4 + unchecked((int)0x540000a2), // b.cs 3c + unchecked((int)0xd50b7b22), // dc cvau, x2 + unchecked((int)0x8b040042), // add x2, x2, x4 + unchecked((int)0xeb02003f), // cmp x1, x2 + unchecked((int)0x54ffffa8), // b.hi 2c + unchecked((int)0xd5033b9f), // dsb ish + unchecked((int)0x51000462), // sub w2, w3, #0x1 + unchecked((int)0x93407c63), // sxtw x3, w3 + unchecked((int)0x8a220000), // bic x0, x0, x2 + unchecked((int)0xeb00003f), // cmp x1, x0 + unchecked((int)0x540000a9), // b.ls 64 + unchecked((int)0xd50b7520), // ic ivau, x0 + unchecked((int)0x8b030000), // add x0, x0, x3 + unchecked((int)0xeb00003f), // cmp x1, x0 + unchecked((int)0x54ffffa8), // b.hi 54 + unchecked((int)0xd5033b9f), // dsb ish + unchecked((int)0xd5033fdf), // isb + unchecked((int)0xd65f03c0), // ret + }; + + private delegate void InvalidateCache(ulong start, ulong end); + + private readonly InvalidateCache _invalidateCache; + private readonly ReservedRegion _invalidateCacheCodeRegion; + + private readonly bool _needsInvalidation; + + public JitCacheInvalidation(IJitMemoryAllocator allocator) + { + // On macOS and Windows, a different path is used to write to the JIT cache, which does the invalidation. + if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64) + { + ulong size = (ulong)_invalidationCode.Length * sizeof(int); + ulong mask = (ulong)ReservedRegion.DefaultGranularity - 1; + + size = (size + mask) & ~mask; + + _invalidateCacheCodeRegion = new ReservedRegion(allocator, size); + _invalidateCacheCodeRegion.ExpandIfNeeded(size); + + Marshal.Copy(_invalidationCode, 0, _invalidateCacheCodeRegion.Pointer, _invalidationCode.Length); + + _invalidateCacheCodeRegion.Block.MapAsRx(0, size); + + _invalidateCache = Marshal.GetDelegateForFunctionPointer(_invalidateCacheCodeRegion.Pointer); + + _needsInvalidation = true; + } + } + + public void Invalidate(IntPtr basePointer, ulong size) + { + if (_needsInvalidation) + { + _invalidateCache((ulong)basePointer, (ulong)basePointer + size); + } + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Cache/JitSupportDarwin.cs b/src/Ryujinx.Cpu/LightningJit/Cache/JitSupportDarwin.cs new file mode 100644 index 000000000..06c81045d --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Cache/JitSupportDarwin.cs @@ -0,0 +1,16 @@ +using System; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; + +namespace Ryujinx.Cpu.LightningJit.Cache +{ + [SupportedOSPlatform("macos")] + static partial class JitSupportDarwin + { + [LibraryImport("libarmeilleure-jitsupport", EntryPoint = "armeilleure_jit_memcpy")] + public static partial void Copy(IntPtr dst, IntPtr src, ulong n); + + [LibraryImport("libc", EntryPoint = "sys_icache_invalidate", SetLastError = true)] + public static partial void SysIcacheInvalidate(IntPtr start, IntPtr len); + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Cache/NoWxCache.cs b/src/Ryujinx.Cpu/LightningJit/Cache/NoWxCache.cs new file mode 100644 index 000000000..a71074995 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Cache/NoWxCache.cs @@ -0,0 +1,340 @@ +using ARMeilleure.Memory; +using Ryujinx.Common; +using Ryujinx.Memory; +using System; +using System.Collections.Generic; +using System.Diagnostics; + +namespace Ryujinx.Cpu.LightningJit.Cache +{ + class NoWxCache : IDisposable + { + private const int CodeAlignment = 4; // Bytes. + private const int SharedCacheSize = 2047 * 1024 * 1024; + private const int LocalCacheSize = 128 * 1024 * 1024; + + // How many calls to the same function we allow until we pad the shared cache to force the function to become available there + // and allow the guest to take the fast path. + private const int MinCallsForPad = 8; + + private class MemoryCache : IDisposable + { + private readonly ReservedRegion _region; + private readonly CacheMemoryAllocator _cacheAllocator; + + public CacheMemoryAllocator Allocator => _cacheAllocator; + public IntPtr Pointer => _region.Block.Pointer; + + public MemoryCache(IJitMemoryAllocator allocator, ulong size) + { + _region = new(allocator, size); + _cacheAllocator = new((int)size); + } + + public int Allocate(int codeSize) + { + codeSize = AlignCodeSize(codeSize); + + int allocOffset = _cacheAllocator.Allocate(codeSize); + + if (allocOffset < 0) + { + throw new OutOfMemoryException("JIT Cache exhausted."); + } + + _region.ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize); + + return allocOffset; + } + + public void Free(int offset, int size) + { + _cacheAllocator.Free(offset, size); + } + + public void ReprotectAsRw(int offset, int size) + { + Debug.Assert(offset >= 0 && (offset & (int)(MemoryBlock.GetPageSize() - 1)) == 0); + Debug.Assert(size > 0 && (size & (int)(MemoryBlock.GetPageSize() - 1)) == 0); + + _region.Block.MapAsRw((ulong)offset, (ulong)size); + } + + public void ReprotectAsRx(int offset, int size) + { + Debug.Assert(offset >= 0 && (offset & (int)(MemoryBlock.GetPageSize() - 1)) == 0); + Debug.Assert(size > 0 && (size & (int)(MemoryBlock.GetPageSize() - 1)) == 0); + + _region.Block.MapAsRx((ulong)offset, (ulong)size); + + if (OperatingSystem.IsMacOS() || OperatingSystem.IsIOS()) + { + JitSupportDarwin.SysIcacheInvalidate(_region.Block.Pointer + offset, size); + } + else + { + throw new PlatformNotSupportedException(); + } + } + + private static int AlignCodeSize(int codeSize) + { + return checked(codeSize + (CodeAlignment - 1)) & ~(CodeAlignment - 1); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + _region.Dispose(); + _cacheAllocator.Clear(); + } + } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + } + + private readonly IStackWalker _stackWalker; + private readonly Translator _translator; + private readonly MemoryCache _sharedCache; + private readonly MemoryCache _localCache; + private readonly PageAlignedRangeList _pendingMap; + private readonly object _lock; + + class ThreadLocalCacheEntry + { + public readonly int Offset; + public readonly int Size; + public readonly IntPtr FuncPtr; + private int _useCount; + + public ThreadLocalCacheEntry(int offset, int size, IntPtr funcPtr) + { + Offset = offset; + Size = size; + FuncPtr = funcPtr; + _useCount = 0; + } + + public int IncrementUseCount() + { + return ++_useCount; + } + } + + [ThreadStatic] + private static Dictionary _threadLocalCache; + + public NoWxCache(IJitMemoryAllocator allocator, IStackWalker stackWalker, Translator translator) + { + _stackWalker = stackWalker; + _translator = translator; + _sharedCache = new(allocator, SharedCacheSize); + _localCache = new(allocator, LocalCacheSize); + _pendingMap = new(_sharedCache.ReprotectAsRx, RegisterFunction); + _lock = new(); + } + + public unsafe IntPtr Map(IntPtr framePointer, ReadOnlySpan code, ulong guestAddress, ulong guestSize) + { + if (TryGetThreadLocalFunction(guestAddress, out IntPtr funcPtr)) + { + return funcPtr; + } + + lock (_lock) + { + if (!_pendingMap.Has(guestAddress) && !_translator.Functions.ContainsKey(guestAddress)) + { + int funcOffset = _sharedCache.Allocate(code.Length); + + funcPtr = _sharedCache.Pointer + funcOffset; + code.CopyTo(new Span((void*)funcPtr, code.Length)); + + TranslatedFunction function = new(funcPtr, guestSize); + + _pendingMap.Add(funcOffset, code.Length, guestAddress, function); + } + + ClearThreadLocalCache(framePointer); + + return AddThreadLocalFunction(code, guestAddress); + } + } + + public unsafe IntPtr MapPageAligned(ReadOnlySpan code) + { + lock (_lock) + { + // Ensure we will get an aligned offset from the allocator. + _pendingMap.Pad(_sharedCache.Allocator); + + int sizeAligned = BitUtils.AlignUp(code.Length, (int)MemoryBlock.GetPageSize()); + int funcOffset = _sharedCache.Allocate(sizeAligned); + + Debug.Assert((funcOffset & ((int)MemoryBlock.GetPageSize() - 1)) == 0); + + IntPtr funcPtr = _sharedCache.Pointer + funcOffset; + code.CopyTo(new Span((void*)funcPtr, code.Length)); + + _sharedCache.ReprotectAsRx(funcOffset, sizeAligned); + + return funcPtr; + } + } + + private bool TryGetThreadLocalFunction(ulong guestAddress, out IntPtr funcPtr) + { + if ((_threadLocalCache ??= new()).TryGetValue(guestAddress, out var entry)) + { + if (entry.IncrementUseCount() >= MinCallsForPad) + { + // Function is being called often, let's make it available in the shared cache so that the guest code + // can take the fast path and stop calling the emulator to get the function from the thread local cache. + // To do that we pad all "pending" function until they complete a page of memory, allowing us to reprotect them as RX. + + lock (_lock) + { + _pendingMap.Pad(_sharedCache.Allocator); + } + } + + funcPtr = entry.FuncPtr; + + return true; + } + + funcPtr = IntPtr.Zero; + + return false; + } + + private void ClearThreadLocalCache(IntPtr framePointer) + { + // Try to delete functions that are already on the shared cache + // and no longer being executed. + + if (_threadLocalCache == null) + { + return; + } + + IEnumerable callStack = _stackWalker.GetCallStack( + framePointer, + _localCache.Pointer, + LocalCacheSize, + _sharedCache.Pointer, + SharedCacheSize); + + List<(ulong, ThreadLocalCacheEntry)> toDelete = new(); + + foreach ((ulong address, ThreadLocalCacheEntry entry) in _threadLocalCache) + { + // We only want to delete if the function is already on the shared cache, + // otherwise we will keep translating the same function over and over again. + bool canDelete = !_pendingMap.Has(address); + if (!canDelete) + { + continue; + } + + // We can only delete if the function is not part of the current thread call stack, + // otherwise we will crash the program when the thread returns to it. + foreach (ulong funcAddress in callStack) + { + if (funcAddress >= (ulong)entry.FuncPtr && funcAddress < (ulong)entry.FuncPtr + (ulong)entry.Size) + { + canDelete = false; + break; + } + } + + if (canDelete) + { + toDelete.Add((address, entry)); + } + } + + int pageSize = (int)MemoryBlock.GetPageSize(); + + foreach ((ulong address, ThreadLocalCacheEntry entry) in toDelete) + { + _threadLocalCache.Remove(address); + + int sizeAligned = BitUtils.AlignUp(entry.Size, pageSize); + + _localCache.Free(entry.Offset, sizeAligned); + _localCache.ReprotectAsRw(entry.Offset, sizeAligned); + } + } + + public void ClearEntireThreadLocalCache() + { + // Thread is exiting, delete everything. + + if (_threadLocalCache == null) + { + return; + } + + int pageSize = (int)MemoryBlock.GetPageSize(); + + foreach ((_, ThreadLocalCacheEntry entry) in _threadLocalCache) + { + int sizeAligned = BitUtils.AlignUp(entry.Size, pageSize); + + _localCache.Free(entry.Offset, sizeAligned); + _localCache.ReprotectAsRw(entry.Offset, sizeAligned); + } + + _threadLocalCache.Clear(); + _threadLocalCache = null; + } + + private unsafe IntPtr AddThreadLocalFunction(ReadOnlySpan code, ulong guestAddress) + { + int alignedSize = BitUtils.AlignUp(code.Length, (int)MemoryBlock.GetPageSize()); + int funcOffset = _localCache.Allocate(alignedSize); + + Debug.Assert((funcOffset & (int)(MemoryBlock.GetPageSize() - 1)) == 0); + + IntPtr funcPtr = _localCache.Pointer + funcOffset; + code.CopyTo(new Span((void*)funcPtr, code.Length)); + + (_threadLocalCache ??= new()).Add(guestAddress, new(funcOffset, code.Length, funcPtr)); + + _localCache.ReprotectAsRx(funcOffset, alignedSize); + + return funcPtr; + } + + private void RegisterFunction(ulong address, TranslatedFunction func) + { + TranslatedFunction oldFunc = _translator.Functions.GetOrAdd(address, func.GuestSize, func); + + Debug.Assert(oldFunc == func); + + _translator.RegisterFunction(address, func); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + _localCache.Dispose(); + _sharedCache.Dispose(); + } + } + + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Cache/PageAlignedRangeList.cs b/src/Ryujinx.Cpu/LightningJit/Cache/PageAlignedRangeList.cs new file mode 100644 index 000000000..b6b386714 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Cache/PageAlignedRangeList.cs @@ -0,0 +1,218 @@ +using Ryujinx.Common; +using Ryujinx.Memory; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; + +namespace Ryujinx.Cpu.LightningJit.Cache +{ + class PageAlignedRangeList + { + private readonly struct Range : IComparable + { + public int Offset { get; } + public int Size { get; } + + public Range(int offset, int size) + { + Offset = offset; + Size = size; + } + + public int CompareTo([AllowNull] Range other) + { + return Offset.CompareTo(other.Offset); + } + } + + private readonly Action _alignedRangeAction; + private readonly Action _alignedFunctionAction; + private readonly List<(Range, ulong, TranslatedFunction)> _pendingFunctions; + private readonly List _ranges; + + public PageAlignedRangeList(Action alignedRangeAction, Action alignedFunctionAction) + { + _alignedRangeAction = alignedRangeAction; + _alignedFunctionAction = alignedFunctionAction; + _pendingFunctions = new(); + _ranges = new(); + } + + public bool Has(ulong address) + { + foreach ((_, ulong guestAddress, _) in _pendingFunctions) + { + if (guestAddress == address) + { + return true; + } + } + + return false; + } + + public void Add(int offset, int size, ulong address, TranslatedFunction function) + { + Range range = new(offset, size); + + Insert(range); + _pendingFunctions.Add((range, address, function)); + ProcessAlignedRanges(); + } + + public void Pad(CacheMemoryAllocator allocator) + { + int pageSize = (int)MemoryBlock.GetPageSize(); + + for (int index = 0; index < _ranges.Count; index++) + { + Range range = _ranges[index]; + + int endOffset = range.Offset + range.Size; + + int alignedStart = BitUtils.AlignDown(range.Offset, pageSize); + int alignedEnd = BitUtils.AlignUp(endOffset, pageSize); + int alignedSize = alignedEnd - alignedStart; + + if (alignedStart < range.Offset) + { + allocator.ForceAllocation(alignedStart, range.Offset - alignedStart); + } + + if (alignedEnd > endOffset) + { + allocator.ForceAllocation(endOffset, alignedEnd - endOffset); + } + + _alignedRangeAction(alignedStart, alignedSize); + _ranges.RemoveAt(index--); + ProcessPendingFunctions(index, alignedEnd); + } + } + + private void ProcessAlignedRanges() + { + int pageSize = (int)MemoryBlock.GetPageSize(); + + for (int index = 0; index < _ranges.Count; index++) + { + Range range = _ranges[index]; + + int alignedStart = BitUtils.AlignUp(range.Offset, pageSize); + int alignedEnd = BitUtils.AlignDown(range.Offset + range.Size, pageSize); + int alignedSize = alignedEnd - alignedStart; + + if (alignedSize <= 0) + { + continue; + } + + _alignedRangeAction(alignedStart, alignedSize); + SplitAt(ref index, alignedStart, alignedEnd); + ProcessPendingFunctions(index, alignedEnd); + } + } + + private void ProcessPendingFunctions(int rangeIndex, int alignedEnd) + { + if ((rangeIndex > 0 && rangeIndex == _ranges.Count) || + (rangeIndex >= 0 && rangeIndex < _ranges.Count && _ranges[rangeIndex].Offset >= alignedEnd)) + { + rangeIndex--; + } + + int alignedStart; + + if (rangeIndex >= 0) + { + alignedStart = _ranges[rangeIndex].Offset + _ranges[rangeIndex].Size; + } + else + { + alignedStart = 0; + } + + if (rangeIndex < _ranges.Count - 1) + { + alignedEnd = _ranges[rangeIndex + 1].Offset; + } + else + { + alignedEnd = int.MaxValue; + } + + for (int index = 0; index < _pendingFunctions.Count; index++) + { + (Range range, ulong address, TranslatedFunction function) = _pendingFunctions[index]; + + if (range.Offset >= alignedStart && range.Offset + range.Size <= alignedEnd) + { + _alignedFunctionAction(address, function); + _pendingFunctions.RemoveAt(index--); + } + } + } + + private void Insert(Range range) + { + int index = _ranges.BinarySearch(range); + + if (index < 0) + { + index = ~index; + } + + if (index < _ranges.Count) + { + Range next = _ranges[index]; + + int endOffs = range.Offset + range.Size; + + if (next.Offset == endOffs) + { + range = new Range(range.Offset, range.Size + next.Size); + _ranges.RemoveAt(index); + } + } + + if (index > 0) + { + Range prev = _ranges[index - 1]; + + if (prev.Offset + prev.Size == range.Offset) + { + range = new Range(range.Offset - prev.Size, range.Size + prev.Size); + _ranges.RemoveAt(--index); + } + } + + _ranges.Insert(index, range); + } + + private void SplitAt(ref int index, int alignedStart, int alignedEnd) + { + Range range = _ranges[index]; + + if (range.Offset < alignedStart) + { + _ranges[index++] = new(range.Offset, alignedStart - range.Offset); + + if (range.Offset + range.Size > alignedEnd) + { + _ranges.Insert(index, new(alignedEnd, (range.Offset + range.Size) - alignedEnd)); + } + } + else if (range.Offset + range.Size > alignedEnd) + { + _ranges[index] = new(alignedEnd, (range.Offset + range.Size) - alignedEnd); + } + else if (range.Offset == alignedStart && range.Offset + range.Size == alignedEnd) + { + Debug.Assert(range.Offset == alignedStart && range.Offset + range.Size == alignedEnd); + + _ranges.RemoveAt(index--); + } + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/AbiConstants.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/AbiConstants.cs new file mode 100644 index 000000000..24a646ca9 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/AbiConstants.cs @@ -0,0 +1,15 @@ +namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64 +{ + static class AbiConstants + { + // Some of those register have specific roles and can't be used as general purpose registers. + // X18 - Reserved for platform specific usage. + // X29 - Frame pointer. + // X30 - Return address. + // X31 - Not an actual register, in some cases maps to SP, and in others to ZR. + public const uint ReservedRegsMask = (1u << 18) | (1u << 29) | (1u << 30) | (1u << 31); + + public const uint GprCalleeSavedRegsMask = 0x1ff80000; // X19 to X28 + public const uint FpSimdCalleeSavedRegsMask = 0xff00; // D8 to D15 + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/ArmCondition.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/ArmCondition.cs new file mode 100644 index 000000000..caa2e593b --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/ArmCondition.cs @@ -0,0 +1,30 @@ +namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64 +{ + enum ArmCondition + { + Eq = 0, + Ne = 1, + GeUn = 2, + LtUn = 3, + Mi = 4, + Pl = 5, + Vs = 6, + Vc = 7, + GtUn = 8, + LeUn = 9, + Ge = 10, + Lt = 11, + Gt = 12, + Le = 13, + Al = 14, + Nv = 15, + } + + static class ArmConditionExtensions + { + public static ArmCondition Invert(this ArmCondition condition) + { + return (ArmCondition)((int)condition ^ 1); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/ArmExtensionType.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/ArmExtensionType.cs new file mode 100644 index 000000000..abcf76785 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/ArmExtensionType.cs @@ -0,0 +1,14 @@ +namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64 +{ + enum ArmExtensionType + { + Uxtb = 0, + Uxth = 1, + Uxtw = 2, + Uxtx = 3, + Sxtb = 4, + Sxth = 5, + Sxtw = 6, + Sxtx = 7, + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/ArmShiftType.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/ArmShiftType.cs new file mode 100644 index 000000000..348edd483 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/ArmShiftType.cs @@ -0,0 +1,11 @@ + +namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64 +{ + enum ArmShiftType + { + Lsl = 0, + Lsr = 1, + Asr = 2, + Ror = 3, + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/Assembler.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/Assembler.cs new file mode 100644 index 000000000..28539707f --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/Assembler.cs @@ -0,0 +1,4777 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; + +namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64 +{ + struct Assembler + { + private const uint SfFlag = 1u << 31; + + public const int SpRegister = 31; + public const int ZrRegister = 31; + + private readonly List _code; + + private class LabelState + { + public int BranchIndex; + public int TargetIndex; + public bool HasBranch; + public bool HasTarget; + } + + private readonly List _labels; + + public Assembler(CodeWriter writer) + { + _code = writer.GetList(); + _labels = new List(); + } + + public readonly Operand CreateLabel() + { + int labelIndex = _labels.Count; + _labels.Add(new LabelState()); + + return new Operand(OperandKind.Label, OperandType.None, (ulong)labelIndex); + } + + public readonly void MarkLabel(Operand label) + { + int targetIndex = _code.Count; + + var state = _labels[label.AsInt32()]; + + state.TargetIndex = targetIndex; + state.HasTarget = true; + + if (state.HasBranch) + { + int imm = (targetIndex - state.BranchIndex) * sizeof(uint); + uint code = _code[state.BranchIndex]; + + if ((code & 0xfc000000u) == 0x14000000u) + { + _code[state.BranchIndex] = code | EncodeSImm26_2(imm); + } + else + { + _code[state.BranchIndex] = code | (EncodeSImm19_2(imm) << 5); + } + } + } + + // Base + + public readonly void B(Operand label, ArmCondition condition = ArmCondition.Al) + { + int branchIndex = _code.Count; + + var state = _labels[label.AsInt32()]; + + state.BranchIndex = branchIndex; + state.HasBranch = true; + + int imm = 0; + + if (state.HasTarget) + { + imm = (state.TargetIndex - branchIndex) * sizeof(uint); + } + + if (condition == ArmCondition.Al) + { + B(imm); + } + else + { + B(condition, imm); + } + } + + public readonly void Cbz(Operand rt, Operand label) + { + int branchIndex = _code.Count; + + var state = _labels[label.AsInt32()]; + + state.BranchIndex = branchIndex; + state.HasBranch = true; + + int imm = 0; + + if (state.HasTarget) + { + imm = (state.TargetIndex - branchIndex) * sizeof(uint); + } + + Cbz(rt, imm); + } + + public readonly void Cbnz(Operand rt, Operand label) + { + int branchIndex = _code.Count; + + var state = _labels[label.AsInt32()]; + + state.BranchIndex = branchIndex; + state.HasBranch = true; + + int imm = 0; + + if (state.HasTarget) + { + imm = (state.TargetIndex - branchIndex) * sizeof(uint); + } + + Cbnz(rt, imm); + } + + public readonly void Adc(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x1a000000u, rd, rn, rm); + } + + public readonly void Adcs(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x3a000000u, rd, rn, rm); + } + + public readonly void Add(Operand rd, Operand rn, Operand rm, ArmExtensionType extensionType, int shiftAmount = 0) + { + WriteInstructionAuto(0x0b200000u, rd, rn, rm, extensionType, shiftAmount); + } + + public readonly void Add(Operand rd, Operand rn, Operand rm) + { + Add(rd, rn, rm, ArmShiftType.Lsl, 0); + } + + public readonly void Add(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount) + { + Add(rd, rn, rm, shiftType, shiftAmount, false); + } + + public readonly void Add(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount, bool immForm) + { + WriteInstructionAuto(0x11000000u, 0x0b000000u, rd, rn, rm, shiftType, shiftAmount, immForm); + } + + public readonly void Adds(Operand rd, Operand rn, Operand rm) + { + Adds(rd, rn, rm, ArmShiftType.Lsl, 0); + } + + public readonly void Adds(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount) + { + Adds(rd, rn, rm, shiftType, shiftAmount, false); + } + + public readonly void Adds(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount, bool immForm) + { + WriteInstructionAuto(0x31000000u, 0x2b000000u, rd, rn, rm, shiftType, shiftAmount, immForm); + } + + public readonly void And(Operand rd, Operand rn, Operand rm) + { + And(rd, rn, rm, ArmShiftType.Lsl, 0); + } + + public readonly void And(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount) + { + WriteInstructionBitwiseAuto(0x12000000u, 0x0a000000u, rd, rn, rm, shiftType, shiftAmount); + } + + public readonly void Ands(Operand rd, Operand rn, Operand rm) + { + Ands(rd, rn, rm, ArmShiftType.Lsl, 0); + } + + public readonly void Ands(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount) + { + WriteInstructionBitwiseAuto(0x72000000u, 0x6a000000u, rd, rn, rm, shiftType, shiftAmount); + } + + public readonly void Asr(Operand rd, Operand rn, Operand rm) + { + if (rm.Kind == OperandKind.Constant) + { + int shift = rm.AsInt32(); + int mask = rd.Type == OperandType.I64 ? 63 : 31; + shift &= mask; + Sbfm(rd, rn, shift, mask); + } + else + { + Asrv(rd, rn, rm); + } + } + + public readonly void Asrv(Operand rd, Operand rn, Operand rm) + { + WriteInstructionBitwiseAuto(0x1ac02800u, rd, rn, rm); + } + + public readonly void B(int imm) + { + WriteUInt32(0x14000000u | EncodeSImm26_2(imm)); + } + + public readonly void B(ArmCondition condition, int imm) + { + WriteUInt32(0x54000000u | (uint)condition | (EncodeSImm19_2(imm) << 5)); + } + + public readonly void Bfc(Operand rd, int lsb, int width) + { + Bfi(rd, new Operand(ZrRegister, RegisterType.Integer, OperandType.I32), lsb, width); + } + + public readonly void Bfi(Operand rd, Operand rn, int lsb, int width) + { + Bfm(rd, rn, -lsb & 31, width - 1); + } + + public readonly void Bfm(Operand rd, Operand rn, int immr, int imms) + { + WriteInstruction(0x33000000u | (EncodeUImm6(imms) << 10) | (EncodeUImm6(immr) << 16), rd, rn); + } + + public readonly void Bfxil(Operand rd, Operand rn, int lsb, int width) + { + Bfm(rd, rn, lsb, lsb + width - 1); + } + + public readonly void Bic(Operand rd, Operand rn, Operand rm) + { + Bic(rd, rn, rm, ArmShiftType.Lsl, 0); + } + + public readonly void Bic(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount) + { + WriteInstructionAuto(0x0a200000u, rd, rn, rm, shiftType, shiftAmount); + } + + public readonly void Bics(Operand rd, Operand rn, Operand rm) + { + Bics(rd, rn, rm, ArmShiftType.Lsl, 0); + } + + public readonly void Bics(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount) + { + WriteInstructionAuto(0x6a200000u, rd, rn, rm, shiftType, shiftAmount); + } + + public readonly void Blr(Operand rn) + { + WriteUInt32(0xd63f0000u | (EncodeReg(rn) << 5)); + } + + public readonly void Br(Operand rn) + { + WriteUInt32(0xd61f0000u | (EncodeReg(rn) << 5)); + } + + public readonly void Brk() + { + WriteUInt32(0xd4200000u); + } + + public readonly void Cbz(Operand rt, int imm) + { + WriteInstructionAuto(0x34000000u | (EncodeSImm19_2(imm) << 5), rt); + } + + public readonly void Cbnz(Operand rt, int imm) + { + WriteInstructionAuto(0x35000000u | (EncodeSImm19_2(imm) << 5), rt); + } + + public readonly void Crc32(Operand rd, Operand rn, Operand rm, uint sz) + { + Debug.Assert(sz <= 3); + WriteInstructionRm16(0x1ac04000u | (sz << 10), rd, rn, rm); + } + + public readonly void Crc32c(Operand rd, Operand rn, Operand rm, uint sz) + { + Debug.Assert(sz <= 3); + WriteInstructionRm16(0x1ac05000u | (sz << 10), rd, rn, rm); + } + + public readonly void Clrex(int crm = 15) + { + WriteUInt32(0xd503305fu | (EncodeUImm4(crm) << 8)); + } + + public readonly void Clz(Operand rd, Operand rn) + { + WriteInstructionAuto(0x5ac01000u, rd, rn); + } + + public readonly void Cmn(Operand rn, Operand rm) + { + Cmn(rn, rm, ArmShiftType.Lsl, 0); + } + + public readonly void Cmn(Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount) + { + Adds(new Operand(ZrRegister, RegisterType.Integer, rn.Type), rn, rm, shiftType, shiftAmount); + } + + public readonly void Cmp(Operand rn, Operand rm) + { + Cmp(rn, rm, ArmShiftType.Lsl, 0); + } + + public readonly void Cmp(Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount) + { + Subs(new Operand(ZrRegister, RegisterType.Integer, rn.Type), rn, rm, shiftType, shiftAmount); + } + + public readonly void Csdb() + { + WriteUInt32(0xd503229fu); + } + + public readonly void Csel(Operand rd, Operand rn, Operand rm, ArmCondition condition) + { + WriteInstructionBitwiseAuto(0x1a800000u | ((uint)condition << 12), rd, rn, rm); + } + + public readonly void Cset(Operand rd, ArmCondition condition) + { + var zr = new Operand(ZrRegister, RegisterType.Integer, rd.Type); + Csinc(rd, zr, zr, (ArmCondition)((int)condition ^ 1)); + } + + public readonly void Csinc(Operand rd, Operand rn, Operand rm, ArmCondition condition) + { + WriteInstructionBitwiseAuto(0x1a800400u | ((uint)condition << 12), rd, rn, rm); + } + + public readonly void Dmb(uint option) + { + WriteUInt32(0xd50330bfu | (option << 8)); + } + + public readonly void Dsb(uint option) + { + WriteUInt32(0xd503309fu | (option << 8)); + } + + public readonly void Eor(Operand rd, Operand rn, Operand rm) + { + Eor(rd, rn, rm, ArmShiftType.Lsl, 0); + } + + public readonly void Eor(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount) + { + WriteInstructionBitwiseAuto(0x52000000u, 0x4a000000u, rd, rn, rm, shiftType, shiftAmount); + } + + public readonly void Eors(Operand rd, Operand rn, Operand rm) + { + Eors(rd, rn, rm, ArmShiftType.Lsl, 0); + } + + public readonly void Eors(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount) + { + Eor(rd, rn, rm, shiftType, shiftAmount); + Tst(rd, rd); + } + + public readonly void Esb() + { + WriteUInt32(0xd503221fu); + } + + public readonly void Extr(Operand rd, Operand rn, Operand rm, int imms) + { + uint n = rd.Type == OperandType.I64 ? 1u << 22 : 0u; + WriteInstructionBitwiseAuto(0x13800000u | n | (EncodeUImm6(imms) << 10), rd, rn, rm); + } + + public readonly void Isb(uint option) + { + WriteUInt32(0xd50330dfu | (option << 8)); + } + + public readonly void Ldar(Operand rt, Operand rn) + { + WriteInstruction(0x88dffc00u | ((rt.Type == OperandType.I64 ? 3u : 2u) << 30), rt, rn); + } + + public readonly void Ldarb(Operand rt, Operand rn) + { + WriteInstruction(0x08dffc00u, rt, rn); + } + + public readonly void Ldarh(Operand rt, Operand rn) + { + WriteInstruction(0x48dffc00u, rt, rn); + } + + public readonly void Ldaxp(Operand rt, Operand rt2, Operand rn) + { + WriteInstruction(0x887f8000u | ((rt.Type == OperandType.I64 ? 3u : 2u) << 30), rt, rn, rt2); + } + + public readonly void Ldaxr(Operand rt, Operand rn) + { + WriteInstruction(0x885ffc00u | ((rt.Type == OperandType.I64 ? 3u : 2u) << 30), rt, rn); + } + + public readonly void Ldaxrb(Operand rt, Operand rn) + { + WriteInstruction(0x085ffc00u, rt, rn); + } + + public readonly void Ldaxrh(Operand rt, Operand rn) + { + WriteInstruction(0x485ffc00u, rt, rn); + } + + public readonly void LdpRiPost(Operand rt, Operand rt2, Operand rn, int imm) + { + uint instruction = GetLdpStpInstruction(0x28c00000u, 0x2cc00000u, imm, rt.Type); + WriteInstruction(instruction, rt, rn, rt2); + } + + public readonly void LdpRiPre(Operand rt, Operand rt2, Operand rn, int imm) + { + uint instruction = GetLdpStpInstruction(0x29c00000u, 0x2dc00000u, imm, rt.Type); + WriteInstruction(instruction, rt, rn, rt2); + } + + public readonly void LdpRiUn(Operand rt, Operand rt2, Operand rn, int imm) + { + uint instruction = GetLdpStpInstruction(0x29400000u, 0x2d400000u, imm, rt.Type); + WriteInstruction(instruction, rt, rn, rt2); + } + + public readonly void LdrLit(Operand rt, int offset) + { + uint instruction = 0x18000000u | (EncodeSImm19_2(offset) << 5); + + if (rt.Type == OperandType.I64) + { + instruction |= 1u << 30; + } + + WriteInstruction(instruction, rt); + } + + public readonly void LdrRiPost(Operand rt, Operand rn, int imm) + { + uint instruction = GetLdrStrInstruction(0xb8400400u, 0x3c400400u, rt.Type) | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void LdrRiPre(Operand rt, Operand rn, int imm) + { + uint instruction = GetLdrStrInstruction(0xb8400c00u, 0x3c400c00u, rt.Type) | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void LdrRiUn(Operand rt, Operand rn, int imm) + { + uint instruction = GetLdrStrInstruction(0xb9400000u, 0x3d400000u, rt.Type) | (EncodeUImm12(imm, rt.Type) << 10); + WriteInstruction(instruction, rt, rn); + } + + public readonly void LdrRiUn(Operand rt, Operand rn, int imm, uint size) + { + uint instruction = GetLdrStrInstruction(0xb9400000u, 0x3d400000u, rt.Type, size) | (EncodeUImm12(imm, (int)size) << 10); + WriteInstruction(instruction, rt, rn); + } + + public readonly void LdrRr(Operand rt, Operand rn, Operand rm, ArmExtensionType extensionType, bool shift) + { + uint instruction = GetLdrStrInstruction(0xb8600800u, 0x3ce00800u, rt.Type); + WriteInstructionLdrStrAuto(instruction, rt, rn, rm, extensionType, shift); + } + + public readonly void LdrbRiPost(Operand rt, Operand rn, int imm) + { + uint instruction = 0x38400400u | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void LdrbRiPre(Operand rt, Operand rn, int imm) + { + uint instruction = 0x38400c00u | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void LdrbRiUn(Operand rt, Operand rn, int imm) + { + uint instruction = 0x39400000u | (EncodeUImm12(imm, 0) << 10); + WriteInstruction(instruction, rt, rn); + } + + public readonly void LdrhRiPost(Operand rt, Operand rn, int imm) + { + uint instruction = 0x78400400u | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void LdrhRiPre(Operand rt, Operand rn, int imm) + { + uint instruction = 0x78400c00u | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void LdrhRiUn(Operand rt, Operand rn, int imm) + { + uint instruction = 0x79400000u | (EncodeUImm12(imm, 1) << 10); + WriteInstruction(instruction, rt, rn); + } + + public readonly void LdrsbRiPost(Operand rt, Operand rn, int imm) + { + WriteInstruction(0x38800400u | (EncodeSImm9(imm) << 12), rt, rn); + } + + public readonly void LdrsbRiPre(Operand rt, Operand rn, int imm) + { + WriteInstruction(0x38800c00u | (EncodeSImm9(imm) << 12), rt, rn); + } + + public readonly void LdrsbRiUn(Operand rt, Operand rn, int imm) + { + WriteInstruction(0x39800000u | (EncodeUImm12(imm, 0) << 10), rt, rn); + } + + public readonly void LdrshRiPost(Operand rt, Operand rn, int imm) + { + WriteInstruction(0x78800400u | (EncodeSImm9(imm) << 12), rt, rn); + } + + public readonly void LdrshRiPre(Operand rt, Operand rn, int imm) + { + WriteInstruction(0x78800c00u | (EncodeSImm9(imm) << 12), rt, rn); + } + + public readonly void LdrshRiUn(Operand rt, Operand rn, int imm) + { + WriteInstruction(0x79800000u | (EncodeUImm12(imm, 1) << 10), rt, rn); + } + + public readonly void LdrswRiPost(Operand rt, Operand rn, int imm) + { + WriteInstruction(0xb8800400u | (EncodeSImm9(imm) << 12), rt, rn); + } + + public readonly void LdrswRiPre(Operand rt, Operand rn, int imm) + { + WriteInstruction(0xb8800c00u | (EncodeSImm9(imm) << 12), rt, rn); + } + + public readonly void LdrswRiUn(Operand rt, Operand rn, int imm) + { + WriteInstruction(0xb9800000u | (EncodeUImm12(imm, 2) << 10), rt, rn); + } + + public readonly void Ldur(Operand rt, Operand rn, int imm) + { + uint instruction = GetLdrStrInstruction(0xb8400000u, 0x3c400000u, rt.Type) | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void Ldur(Operand rt, Operand rn, int imm, uint size) + { + uint instruction = GetLdrStrInstruction(0xb8400000u, 0x3c400000u, rt.Type, size) | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void Ldurb(Operand rt, Operand rn, int imm) + { + uint instruction = 0x38400000u | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void Ldurh(Operand rt, Operand rn, int imm) + { + uint instruction = 0x78400000u | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void Ldursb(Operand rt, Operand rn, int imm) + { + uint instruction = 0x38800000u | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void Ldursh(Operand rt, Operand rn, int imm) + { + uint instruction = 0x78800000u | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void Ldursw(Operand rt, Operand rn, int imm) + { + uint instruction = 0xb8800000u | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void Lsl(Operand rd, Operand rn, Operand rm) + { + if (rm.Kind == OperandKind.Constant) + { + int shift = rm.AsInt32(); + int mask = rd.Type == OperandType.I64 ? 63 : 31; + shift &= mask; + Ubfm(rd, rn, -shift & mask, mask - shift); + } + else + { + Lslv(rd, rn, rm); + } + } + + public readonly void Lslv(Operand rd, Operand rn, Operand rm) + { + WriteInstructionBitwiseAuto(0x1ac02000u, rd, rn, rm); + } + + public readonly void Lsr(Operand rd, Operand rn, Operand rm) + { + if (rm.Kind == OperandKind.Constant) + { + int shift = rm.AsInt32(); + int mask = rd.Type == OperandType.I64 ? 63 : 31; + shift &= mask; + Ubfm(rd, rn, shift, mask); + } + else + { + Lsrv(rd, rn, rm); + } + } + + public readonly void Lsrv(Operand rd, Operand rn, Operand rm) + { + WriteInstructionBitwiseAuto(0x1ac02400u, rd, rn, rm); + } + + public readonly void Madd(Operand rd, Operand rn, Operand rm, Operand ra) + { + WriteInstructionAuto(0x1b000000u, rd, rn, rm, ra); + } + + public readonly void Msub(Operand rd, Operand rn, Operand rm, Operand ra) + { + WriteInstructionAuto(0x1b008000u, rd, rn, rm, ra); + } + + public readonly void Mul(Operand rd, Operand rn, Operand rm) + { + Madd(rd, rn, rm, new Operand(ZrRegister, RegisterType.Integer, rd.Type)); + } + + public readonly void Mov(Operand rd, Operand rn) + { + Debug.Assert(rd.Type.IsInteger()); + Orr(rd, new Operand(ZrRegister, RegisterType.Integer, rd.Type), rn); + } + + public readonly void MovSp(Operand rd, Operand rn) + { + if (rd.GetRegister().Index == SpRegister || + rn.GetRegister().Index == SpRegister) + { + Add(rd, rn, new Operand(rd.Type, 0), ArmShiftType.Lsl, 0, immForm: true); + } + else + { + Mov(rd, rn); + } + } + + public readonly void Mov(Operand rd, ulong value) + { + if (value == 0) + { + Mov(rd, new Operand(ZrRegister, RegisterType.Integer, rd.Type)); + } + else if (CodeGenCommon.TryEncodeBitMask(rd.Type, value, out _, out _, out _)) + { + Orr(rd, new Operand(ZrRegister, RegisterType.Integer, rd.Type), new Operand(OperandKind.Constant, rd.Type, value)); + } + else if (value == ulong.MaxValue || (value == uint.MaxValue && rd.Type == OperandType.I32)) + { + Mvn(rd, new Operand(ZrRegister, RegisterType.Integer, rd.Type)); + } + else + { + int hw = 0; + bool first = true; + + while (value != 0) + { + int valueLow = (ushort)value; + if (valueLow != 0) + { + if (first) + { + Movz(rd, valueLow, hw); + first = false; + } + else + { + Movk(rd, valueLow, hw); + } + } + + hw++; + value >>= 16; + } + } + } + + public readonly void Mov(Operand rd, int imm) + { + Movz(rd, imm, 0); + } + + public readonly void Movz(Operand rd, int imm, int hw) + { + Debug.Assert((hw & (rd.Type == OperandType.I64 ? 3 : 1)) == hw); + WriteInstructionAuto(0x52800000u | (EncodeUImm16(imm) << 5) | ((uint)hw << 21), rd); + } + + public readonly void Movk(Operand rd, int imm, int hw) + { + Debug.Assert((hw & (rd.Type == OperandType.I64 ? 3 : 1)) == hw); + WriteInstructionAuto(0x72800000u | (EncodeUImm16(imm) << 5) | ((uint)hw << 21), rd); + } + + public readonly void Mrs(Operand rt, uint o0, uint op1, uint crn, uint crm, uint op2) + { + WriteSysRegInstruction(0xd5300000u, rt, o0, op1, crn, crm, op2); + } + + public readonly void MrsNzcv(Operand rt) + { + WriteInstruction(0xd53b4200u, rt); + } + + public readonly void MrsFpcr(Operand rt) + { + WriteInstruction(0xd53b4400u, rt); + } + + public readonly void MrsFpsr(Operand rt) + { + WriteInstruction(0xd53b4420u, rt); + } + + public readonly void MrsTpidrEl0(Operand rt) + { + WriteInstruction(0xd53bd040u, rt); + } + + public readonly void MrsTpidrroEl0(Operand rt) + { + WriteInstruction(0xd53bd060u, rt); + } + + public readonly void Msr(Operand rt, uint o0, uint op1, uint crn, uint crm, uint op2) + { + WriteSysRegInstruction(0xd5100000u, rt, o0, op1, crn, crm, op2); + } + + public readonly void MsrNzcv(Operand rt) + { + WriteInstruction(0xd51b4200u, rt); + } + + public readonly void MsrFpcr(Operand rt) + { + WriteInstruction(0xd51b4400, rt); + } + + public readonly void MsrFpsr(Operand rt) + { + WriteInstruction(0xd51b4420, rt); + } + + public readonly void Mvn(Operand rd, Operand rn, ArmShiftType shiftType = ArmShiftType.Lsl, int shiftAmount = 0) + { + Orn(rd, new Operand(ZrRegister, RegisterType.Integer, rd.Type), rn, shiftType, shiftAmount); + } + + public readonly void Neg(Operand rd, Operand rn, ArmShiftType shiftType = ArmShiftType.Lsl, int shiftAmount = 0) + { + Sub(rd, new Operand(ZrRegister, RegisterType.Integer, rd.Type), rn, shiftType, shiftAmount); + } + + public readonly void Negs(Operand rd, Operand rn, ArmShiftType shiftType = ArmShiftType.Lsl, int shiftAmount = 0) + { + Subs(rd, new Operand(ZrRegister, RegisterType.Integer, rd.Type), rn, shiftType, shiftAmount); + } + + public readonly void Orn(Operand rd, Operand rn, Operand rm) + { + Orn(rd, rn, rm, ArmShiftType.Lsl, 0); + } + + public readonly void Orn(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount) + { + WriteInstructionBitwiseAuto(0x2a200000u, rd, rn, rm, shiftType, shiftAmount); + } + + public readonly void Orns(Operand rd, Operand rn, Operand rm) + { + Orns(rd, rn, rm, ArmShiftType.Lsl, 0); + } + + public readonly void Orns(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount) + { + Orn(rd, rn, rm, shiftType, shiftAmount); + Tst(rd, rd); + } + + public readonly void Orr(Operand rd, Operand rn, Operand rm) + { + Orr(rd, rn, rm, ArmShiftType.Lsl, 0); + } + + public readonly void Orr(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount) + { + WriteInstructionBitwiseAuto(0x32000000u, 0x2a000000u, rd, rn, rm, shiftType, shiftAmount); + } + + public readonly void Orrs(Operand rd, Operand rn, Operand rm) + { + Orrs(rd, rn, rm, ArmShiftType.Lsl, 0); + } + + public readonly void Orrs(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount) + { + Orr(rd, rn, rm, shiftType, shiftAmount); + Tst(rd, rd); + } + + public readonly void PrfmI(Operand rn, int imm, uint type, uint target, uint policy) + { + Operand rt = new Operand((int)EncodeTypeTargetPolicy(type, target, policy), RegisterType.Integer, OperandType.I32); + WriteInstruction(0xf9800000u | (EncodeUImm12(imm, 3) << 10), rt, rn); + } + + public readonly void PrfmR(Operand rt, Operand rn) + { + WriteInstruction(0xf8a04800u, rt, rn); + } + + public readonly void Prfum(Operand rn, int imm, uint type, uint target, uint policy) + { + Operand rt = new Operand((int)EncodeTypeTargetPolicy(type, target, policy), RegisterType.Integer, OperandType.I32); + WriteInstruction(0xf8800000u | (EncodeSImm9(imm) << 12), rt, rn); + } + + public readonly void Rbit(Operand rd, Operand rn) + { + WriteInstructionAuto(0x5ac00000u, rd, rn); + } + + public readonly void Ret() + { + Ret(new Operand(30, RegisterType.Integer, OperandType.I64)); + } + + public readonly void Ret(Operand rn) + { + WriteUInt32(0xd65f0000u | (EncodeReg(rn) << 5)); + } + + public readonly void Rev(Operand rd, Operand rn) + { + uint opc0 = rd.Type == OperandType.I64 ? 1u << 10 : 0u; + WriteInstructionAuto(0x5ac00800u | opc0, rd, rn); + } + + public readonly void Rev16(Operand rd, Operand rn) + { + WriteInstructionAuto(0x5ac00400u, rd, rn); + } + + public readonly void Rev32(Operand rd, Operand rn) + { + WriteInstructionAuto(0xdac00800u, rd, rn); + } + + public readonly void Ror(Operand rd, Operand rn, Operand rm) + { + if (rm.Kind == OperandKind.Constant) + { + int shift = rm.AsInt32(); + int mask = rd.Type == OperandType.I64 ? 63 : 31; + shift &= mask; + Extr(rd, rn, rn, shift); + } + else + { + Rorv(rd, rn, rm); + } + } + + public readonly void Rorv(Operand rd, Operand rn, Operand rm) + { + WriteInstructionBitwiseAuto(0x1ac02c00u, rd, rn, rm); + } + + public readonly void Sbc(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x5a000000u, rd, rn, rm); + } + + public readonly void Sbcs(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x7a000000u, rd, rn, rm); + } + + public readonly void Sbfm(Operand rd, Operand rn, int immr, int imms) + { + uint n = rd.Type == OperandType.I64 ? 1u << 22 : 0u; + WriteInstructionAuto(0x13000000u | n | (EncodeUImm6(imms) << 10) | (EncodeUImm6(immr) << 16), rd, rn); + } + + public readonly void Sbfx(Operand rd, Operand rn, int lsb, int width) + { + Sbfm(rd, rn, lsb, lsb + width - 1); + } + + public readonly void Sdiv(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16Auto(0x1ac00c00u, rd, rn, rm); + } + + public readonly void Sev() + { + WriteUInt32(0xd503209fu); + } + + public readonly void Sevl() + { + WriteUInt32(0xd50320bfu); + } + + public readonly void Smaddl(Operand rd, Operand rn, Operand rm, Operand ra) + { + WriteInstruction(0x9b200000u, rd, rn, rm, ra); + } + + public readonly void Smsubl(Operand rd, Operand rn, Operand rm, Operand ra) + { + WriteInstruction(0x9b208000u, rd, rn, rm, ra); + } + + public readonly void Smulh(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x9b407c00u, rd, rn, rm); + } + + public readonly void Smull(Operand rd, Operand rn, Operand rm) + { + Smaddl(rd, rn, rm, new Operand(ZrRegister, RegisterType.Integer, rd.Type)); + } + + public readonly void Stlr(Operand rt, Operand rn) + { + WriteInstruction(0x889ffc00u | ((rt.Type == OperandType.I64 ? 3u : 2u) << 30), rt, rn); + } + + public readonly void Stlrb(Operand rt, Operand rn) + { + WriteInstruction(0x089ffc00u, rt, rn); + } + + public readonly void Stlrh(Operand rt, Operand rn) + { + WriteInstruction(0x489ffc00u, rt, rn); + } + + public readonly void Stlxp(Operand rs, Operand rt, Operand rt2, Operand rn) + { + WriteInstruction(0x88208000u | ((rt.Type == OperandType.I64 ? 3u : 2u) << 30), rt, rn, rs, rt2); + } + + public readonly void Stlxr(Operand rs, Operand rt, Operand rn) + { + WriteInstructionRm16(0x8800fc00u | ((rt.Type == OperandType.I64 ? 3u : 2u) << 30), rt, rn, rs); + } + + public readonly void Stlxrb(Operand rs, Operand rt, Operand rn) + { + WriteInstructionRm16(0x0800fc00u, rt, rn, rs); + } + + public readonly void Stlxrh(Operand rs, Operand rt, Operand rn) + { + WriteInstructionRm16(0x4800fc00u, rt, rn, rs); + } + + public readonly void StpRiPost(Operand rt, Operand rt2, Operand rn, int imm) + { + uint instruction = GetLdpStpInstruction(0x28800000u, 0x2c800000u, imm, rt.Type); + WriteInstruction(instruction, rt, rn, rt2); + } + + public readonly void StpRiPre(Operand rt, Operand rt2, Operand rn, int imm) + { + uint instruction = GetLdpStpInstruction(0x29800000u, 0x2d800000u, imm, rt.Type); + WriteInstruction(instruction, rt, rn, rt2); + } + + public readonly void StpRiUn(Operand rt, Operand rt2, Operand rn, int imm) + { + uint instruction = GetLdpStpInstruction(0x29000000u, 0x2d000000u, imm, rt.Type); + WriteInstruction(instruction, rt, rn, rt2); + } + + public readonly void StrRiPost(Operand rt, Operand rn, int imm) + { + uint instruction = GetLdrStrInstruction(0xb8000400u, 0x3c000400u, rt.Type) | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void StrRiPre(Operand rt, Operand rn, int imm) + { + uint instruction = GetLdrStrInstruction(0xb8000c00u, 0x3c000c00u, rt.Type) | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void StrRiUn(Operand rt, Operand rn, int imm) + { + uint instruction = GetLdrStrInstruction(0xb9000000u, 0x3d000000u, rt.Type) | (EncodeUImm12(imm, rt.Type) << 10); + WriteInstruction(instruction, rt, rn); + } + + public readonly void StrRiUn(Operand rt, Operand rn, int imm, uint size) + { + uint instruction = GetLdrStrInstruction(0xb9000000u, 0x3d000000u, rt.Type, size) | (EncodeUImm12(imm, (int)size) << 10); + WriteInstruction(instruction, rt, rn); + } + + public readonly void StrRr(Operand rt, Operand rn, Operand rm, ArmExtensionType extensionType, bool shift) + { + uint instruction = GetLdrStrInstruction(0xb8200800u, 0x3ca00800u, rt.Type); + WriteInstructionLdrStrAuto(instruction, rt, rn, rm, extensionType, shift); + } + + public readonly void StrbRiPost(Operand rt, Operand rn, int imm) + { + uint instruction = 0x38000400u | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void StrbRiPre(Operand rt, Operand rn, int imm) + { + uint instruction = 0x38000c00u | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void StrbRiUn(Operand rt, Operand rn, int imm) + { + uint instruction = 0x39000000u | (EncodeUImm12(imm, 0) << 10); + WriteInstruction(instruction, rt, rn); + } + + public readonly void StrhRiPost(Operand rt, Operand rn, int imm) + { + uint instruction = 0x78000400u | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void StrhRiPre(Operand rt, Operand rn, int imm) + { + uint instruction = 0x78000c00u | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void StrhRiUn(Operand rt, Operand rn, int imm) + { + uint instruction = 0x79000000u | (EncodeUImm12(imm, 1) << 10); + WriteInstruction(instruction, rt, rn); + } + + public readonly void Stur(Operand rt, Operand rn, int imm) + { + uint instruction = GetLdrStrInstruction(0xb8000000u, 0x3c000000u, rt.Type) | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void Stur(Operand rt, Operand rn, int imm, uint size) + { + uint instruction = GetLdrStrInstruction(0xb8000000u, 0x3c000000u, rt.Type, size) | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void Sturb(Operand rt, Operand rn, int imm) + { + uint instruction = 0x38000000u | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void Sturh(Operand rt, Operand rn, int imm) + { + uint instruction = 0x78000000u | (EncodeSImm9(imm) << 12); + WriteInstruction(instruction, rt, rn); + } + + public readonly void Sub(Operand rd, Operand rn, Operand rm, ArmExtensionType extensionType, int shiftAmount = 0) + { + WriteInstructionAuto(0x4b200000u, rd, rn, rm, extensionType, shiftAmount); + } + + public readonly void Sub(Operand rd, Operand rn, Operand rm) + { + Sub(rd, rn, rm, ArmShiftType.Lsl, 0); + } + + public readonly void Sub(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount) + { + WriteInstructionAuto(0x51000000u, 0x4b000000u, rd, rn, rm, shiftType, shiftAmount); + } + + public readonly void Subs(Operand rd, Operand rn, Operand rm) + { + Subs(rd, rn, rm, ArmShiftType.Lsl, 0); + } + + public readonly void Subs(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount) + { + WriteInstructionAuto(0x71000000u, 0x6b000000u, rd, rn, rm, shiftType, shiftAmount); + } + + public readonly void Sxtb(Operand rd, Operand rn) + { + Sbfm(rd, rn, 0, 7); + } + + public readonly void Sxth(Operand rd, Operand rn) + { + Sbfm(rd, rn, 0, 15); + } + + public readonly void Sxtw(Operand rd, Operand rn) + { + Sbfm(rd, rn, 0, 31); + } + + public readonly void Tsb() + { + WriteUInt32(0xd503225fu); + } + + public readonly void Tst(Operand rn, Operand rm) + { + Tst(rn, rm, ArmShiftType.Lsl, 0); + } + + public readonly void Tst(Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount) + { + Ands(new Operand(ZrRegister, RegisterType.Integer, rn.Type), rn, rm, shiftType, shiftAmount); + } + + public readonly void Ubfm(Operand rd, Operand rn, int immr, int imms) + { + uint n = rd.Type == OperandType.I64 ? 1u << 22 : 0u; + WriteInstructionAuto(0x53000000u | n | (EncodeUImm6(imms) << 10) | (EncodeUImm6(immr) << 16), rd, rn); + } + + public readonly void Ubfx(Operand rd, Operand rn, int lsb, int width) + { + Ubfm(rd, rn, lsb, lsb + width - 1); + } + + public readonly void Udiv(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16Auto(0x1ac00800u, rd, rn, rm); + } + + public readonly void Umaddl(Operand rd, Operand rn, Operand rm, Operand ra) + { + WriteInstructionAuto(0x9ba00000u, rd, rn, rm, ra); + } + + public readonly void Umulh(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x9bc07c00u, rd, rn, rm); + } + + public readonly void Umull(Operand rd, Operand rn, Operand rm) + { + Umaddl(rd, rn, rm, new Operand(ZrRegister, RegisterType.Integer, rd.Type)); + } + + public readonly void Uxtb(Operand rd, Operand rn) + { + Ubfm(rd, rn, 0, 7); + } + + public readonly void Uxth(Operand rd, Operand rn) + { + Ubfm(rd, rn, 0, 15); + } + + // FP & SIMD + + public readonly void AbsS(Operand rd, Operand rn, uint size) + { + WriteInstruction(0x5e20b800u | (size << 22), rd, rn); + } + + public readonly void AbsV(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x0e20b800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void Addhn(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e204000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void AddpPair(Operand rd, Operand rn, uint size) + { + WriteInstruction(0x5e31b800u | (size << 22), rd, rn); + } + + public readonly void AddpVec(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e20bc00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Addv(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x0e31b800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void AddS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x5e208400u | (size << 22), rd, rn, rm); + } + + public readonly void AddV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e208400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Aesd(Operand rd, Operand rn) + { + WriteInstruction(0x4e285800u, rd, rn); + } + + public readonly void Aese(Operand rd, Operand rn) + { + WriteInstruction(0x4e284800u, rd, rn); + } + + public readonly void Aesimc(Operand rd, Operand rn) + { + WriteInstruction(0x4e287800u, rd, rn); + } + + public readonly void Aesmc(Operand rd, Operand rn) + { + WriteInstruction(0x4e286800u, rd, rn); + } + + public readonly void And(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x0e201c00u | (q << 30), rd, rn, rm); + } + + public readonly void Bcax(Operand rd, Operand rn, Operand rm, Operand ra) + { + WriteInstruction(0xce200000u, rd, rn, rm, ra); + } + + public readonly void Bfcvtn(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x0ea16800u | (q << 30), rd, rn); + } + + public readonly void BfcvtFloat(Operand rd, Operand rn) + { + WriteInstruction(0x1e634000u, rd, rn); + } + + public readonly void BfdotElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q) + { + WriteInstructionRm16(0x0f40f000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm); + } + + public readonly void BfdotVec(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x2e40fc00u | (q << 30), rd, rn, rm); + } + + public readonly void BfmlalElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q) + { + WriteInstructionRm16(0x0fc0f000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm); + } + + public readonly void BfmlalVec(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x2ec0fc00u | (q << 30), rd, rn, rm); + } + + public readonly void Bfmmla(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x6e40ec00u, rd, rn, rm); + } + + public readonly void BicImm(Operand rd, uint h, uint g, uint f, uint e, uint d, uint c, uint b, uint a, uint q) + { + WriteInstruction(0x2f001400u | (h << 5) | (g << 6) | (f << 7) | (e << 8) | (d << 9) | (c << 16) | (b << 17) | (a << 18) | (q << 30), rd); + } + + public readonly void BicReg(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x0e601c00u | (q << 30), rd, rn, rm); + } + + public readonly void Bif(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x2ee01c00u | (q << 30), rd, rn, rm); + } + + public readonly void Bit(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x2ea01c00u | (q << 30), rd, rn, rm); + } + + public readonly void Bsl(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x2e601c00u | (q << 30), rd, rn, rm); + } + + public readonly void Cls(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x0e204800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void Clz(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x2e204800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void CmeqRegS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x7e208c00u | (size << 22), rd, rn, rm); + } + + public readonly void CmeqRegV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e208c00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void CmeqZeroS(Operand rd, Operand rn, uint size) + { + WriteInstruction(0x5e209800u | (size << 22), rd, rn); + } + + public readonly void CmeqZeroV(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x0e209800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void CmgeRegS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x5e203c00u | (size << 22), rd, rn, rm); + } + + public readonly void CmgeRegV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e203c00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void CmgeZeroS(Operand rd, Operand rn, uint size) + { + WriteInstruction(0x7e208800u | (size << 22), rd, rn); + } + + public readonly void CmgeZeroV(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x2e208800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void CmgtRegS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x5e203400u | (size << 22), rd, rn, rm); + } + + public readonly void CmgtRegV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e203400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void CmgtZeroS(Operand rd, Operand rn, uint size) + { + WriteInstruction(0x5e208800u | (size << 22), rd, rn); + } + + public readonly void CmgtZeroV(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x0e208800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void CmhiS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x7e203400u | (size << 22), rd, rn, rm); + } + + public readonly void CmhiV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e203400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void CmhsS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x7e203c00u | (size << 22), rd, rn, rm); + } + + public readonly void CmhsV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e203c00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void CmleS(Operand rd, Operand rn, uint size) + { + WriteInstruction(0x7e209800u | (size << 22), rd, rn); + } + + public readonly void CmleV(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x2e209800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void CmltS(Operand rd, Operand rn, uint size) + { + WriteInstruction(0x5e20a800u | (size << 22), rd, rn); + } + + public readonly void CmltV(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x0e20a800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void CmtstS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x5e208c00u | (size << 22), rd, rn, rm); + } + + public readonly void CmtstV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e208c00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Cnt(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x0e205800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void DupEltScalarFromElement(Operand rd, Operand rn, uint imm5) + { + WriteInstruction(0x5e000400u | (imm5 << 16), rd, rn); + } + + public readonly void DupEltVectorFromElement(Operand rd, Operand rn, uint imm5, uint q) + { + WriteInstruction(0x0e000400u | (imm5 << 16) | (q << 30), rd, rn); + } + + public readonly void DupGen(Operand rd, Operand rn, uint imm5, uint q) + { + WriteInstruction(0x0e000c00u | (imm5 << 16) | (q << 30), rd, rn); + } + + public readonly void Eor3(Operand rd, Operand rn, Operand rm, Operand ra) + { + WriteInstruction(0xce000000u, rd, rn, rm, ra); + } + + public readonly void Eor(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x2e201c00u | (q << 30), rd, rn, rm); + } + + public readonly void Ext(Operand rd, Operand rn, uint imm4, Operand rm, uint q) + { + WriteInstructionRm16(0x2e000000u | (imm4 << 11) | (q << 30), rd, rn, rm); + } + + public readonly void FabdSH(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x7ec01400u, rd, rn, rm); + } + + public readonly void FabdS(Operand rd, Operand rn, Operand rm, uint sz) + { + WriteInstructionRm16(0x7ea0d400u | (sz << 22), rd, rn, rm); + } + + public readonly void FabdVH(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x2ec01400u | (q << 30), rd, rn, rm); + } + + public readonly void FabdV(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x2ea0d400u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FabsHalf(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x0ef8f800u | (q << 30), rd, rn); + } + + public readonly void FabsSingleAndDouble(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x0ea0f800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FabsFloat(Operand rd, Operand rn, uint ftype) + { + WriteInstruction(0x1e20c000u | (ftype << 22), rd, rn); + } + + public readonly void FacgeSH(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x7e402c00u, rd, rn, rm); + } + + public readonly void FacgeS(Operand rd, Operand rn, Operand rm, uint sz) + { + WriteInstructionRm16(0x7e20ec00u | (sz << 22), rd, rn, rm); + } + + public readonly void FacgeVH(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x2e402c00u | (q << 30), rd, rn, rm); + } + + public readonly void FacgeV(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x2e20ec00u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FacgtSH(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x7ec02c00u, rd, rn, rm); + } + + public readonly void FacgtS(Operand rd, Operand rn, Operand rm, uint sz) + { + WriteInstructionRm16(0x7ea0ec00u | (sz << 22), rd, rn, rm); + } + + public readonly void FacgtVH(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x2ec02c00u | (q << 30), rd, rn, rm); + } + + public readonly void FacgtV(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x2ea0ec00u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FaddpPairHalf(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x5e30d800u | (sz << 22), rd, rn); + } + + public readonly void FaddpPairSingleAndDouble(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x7e30d800u | (sz << 22), rd, rn); + } + + public readonly void FaddpVecHalf(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x2e401400u | (q << 30), rd, rn, rm); + } + + public readonly void FaddpVecSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x2e20d400u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FaddHalf(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x0e401400u | (q << 30), rd, rn, rm); + } + + public readonly void FaddSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x0e20d400u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FaddFloat(Operand rd, Operand rn, Operand rm, uint ftype) + { + WriteInstructionRm16(0x1e202800u | (ftype << 22), rd, rn, rm); + } + + public readonly void FcaddVec(Operand rd, Operand rn, uint rot, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e00e400u | (rot << 12) | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FccmpeFloat(uint nzcv, Operand rn, uint cond, Operand rm, uint ftype) + { + WriteInstructionRm16(0x1e200410u | (nzcv << 0) | (cond << 12) | (ftype << 22), rn, rm); + } + + public readonly void FccmpFloat(uint nzcv, Operand rn, uint cond, Operand rm, uint ftype) + { + WriteInstructionRm16(0x1e200400u | (nzcv << 0) | (cond << 12) | (ftype << 22), rn, rm); + } + + public readonly void FcmeqRegSH(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x5e402400u, rd, rn, rm); + } + + public readonly void FcmeqRegS(Operand rd, Operand rn, Operand rm, uint sz) + { + WriteInstructionRm16(0x5e20e400u | (sz << 22), rd, rn, rm); + } + + public readonly void FcmeqRegVH(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x0e402400u | (q << 30), rd, rn, rm); + } + + public readonly void FcmeqRegV(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x0e20e400u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FcmeqZeroSH(Operand rd, Operand rn) + { + WriteInstruction(0x5ef8d800u, rd, rn); + } + + public readonly void FcmeqZeroS(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x5ea0d800u | (sz << 22), rd, rn); + } + + public readonly void FcmeqZeroVH(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x0ef8d800u | (q << 30), rd, rn); + } + + public readonly void FcmeqZeroV(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x0ea0d800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FcmgeRegSH(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x7e402400u, rd, rn, rm); + } + + public readonly void FcmgeRegS(Operand rd, Operand rn, Operand rm, uint sz) + { + WriteInstructionRm16(0x7e20e400u | (sz << 22), rd, rn, rm); + } + + public readonly void FcmgeRegVH(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x2e402400u | (q << 30), rd, rn, rm); + } + + public readonly void FcmgeRegV(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x2e20e400u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FcmgeZeroSH(Operand rd, Operand rn) + { + WriteInstruction(0x7ef8c800u, rd, rn); + } + + public readonly void FcmgeZeroS(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x7ea0c800u | (sz << 22), rd, rn); + } + + public readonly void FcmgeZeroVH(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x2ef8c800u | (q << 30), rd, rn); + } + + public readonly void FcmgeZeroV(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2ea0c800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FcmgtRegSH(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x7ec02400u, rd, rn, rm); + } + + public readonly void FcmgtRegS(Operand rd, Operand rn, Operand rm, uint sz) + { + WriteInstructionRm16(0x7ea0e400u | (sz << 22), rd, rn, rm); + } + + public readonly void FcmgtRegVH(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x2ec02400u | (q << 30), rd, rn, rm); + } + + public readonly void FcmgtRegV(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x2ea0e400u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FcmgtZeroSH(Operand rd, Operand rn) + { + WriteInstruction(0x5ef8c800u, rd, rn); + } + + public readonly void FcmgtZeroS(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x5ea0c800u | (sz << 22), rd, rn); + } + + public readonly void FcmgtZeroVH(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x0ef8c800u | (q << 30), rd, rn); + } + + public readonly void FcmgtZeroV(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x0ea0c800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FcmlaElt(Operand rd, Operand rn, uint h, uint rot, Operand rm, uint m, uint l, uint size, uint q) + { + WriteInstructionRm16(0x2f001000u | (h << 11) | (rot << 13) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FcmlaVec(Operand rd, Operand rn, uint rot, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e00c400u | (rot << 11) | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FcmleSH(Operand rd, Operand rn) + { + WriteInstruction(0x7ef8d800u, rd, rn); + } + + public readonly void FcmleS(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x7ea0d800u | (sz << 22), rd, rn); + } + + public readonly void FcmleVH(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x2ef8d800u | (q << 30), rd, rn); + } + + public readonly void FcmleV(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2ea0d800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FcmltSH(Operand rd, Operand rn) + { + WriteInstruction(0x5ef8e800u, rd, rn); + } + + public readonly void FcmltS(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x5ea0e800u | (sz << 22), rd, rn); + } + + public readonly void FcmltVH(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x0ef8e800u | (q << 30), rd, rn); + } + + public readonly void FcmltV(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x0ea0e800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FcmpeFloat(Operand rn, Operand rm, uint opc, uint ftype) + { + WriteInstructionRm16(0x1e202010u | (opc << 3) | (ftype << 22), rn, rm); + } + + public readonly void FcmpFloat(Operand rn, Operand rm, uint opc, uint ftype) + { + WriteInstructionRm16(0x1e202000u | (opc << 3) | (ftype << 22), rn, rm); + } + + public readonly void FcselFloat(Operand rd, Operand rn, uint cond, Operand rm, uint ftype) + { + WriteInstructionRm16(0x1e200c00u | (cond << 12) | (ftype << 22), rd, rn, rm); + } + + public readonly void FcvtasSH(Operand rd, Operand rn) + { + WriteInstruction(0x5e79c800u, rd, rn); + } + + public readonly void FcvtasS(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x5e21c800u | (sz << 22), rd, rn); + } + + public readonly void FcvtasVH(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x0e79c800u | (q << 30), rd, rn); + } + + public readonly void FcvtasV(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x0e21c800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FcvtasFloat(Operand rd, Operand rn, uint ftype, uint sf) + { + WriteInstruction(0x1e240000u | (ftype << 22) | (sf << 31), rd, rn); + } + + public readonly void FcvtauSH(Operand rd, Operand rn) + { + WriteInstruction(0x7e79c800u, rd, rn); + } + + public readonly void FcvtauS(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x7e21c800u | (sz << 22), rd, rn); + } + + public readonly void FcvtauVH(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x2e79c800u | (q << 30), rd, rn); + } + + public readonly void FcvtauV(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2e21c800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FcvtauFloat(Operand rd, Operand rn, uint ftype, uint sf) + { + WriteInstruction(0x1e250000u | (ftype << 22) | (sf << 31), rd, rn); + } + + public readonly void Fcvtl(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x0e217800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FcvtmsSH(Operand rd, Operand rn) + { + WriteInstruction(0x5e79b800u, rd, rn); + } + + public readonly void FcvtmsS(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x5e21b800u | (sz << 22), rd, rn); + } + + public readonly void FcvtmsVH(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x0e79b800u | (q << 30), rd, rn); + } + + public readonly void FcvtmsV(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x0e21b800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FcvtmsFloat(Operand rd, Operand rn, uint ftype, uint sf) + { + WriteInstruction(0x1e300000u | (ftype << 22) | (sf << 31), rd, rn); + } + + public readonly void FcvtmuSH(Operand rd, Operand rn) + { + WriteInstruction(0x7e79b800u, rd, rn); + } + + public readonly void FcvtmuS(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x7e21b800u | (sz << 22), rd, rn); + } + + public readonly void FcvtmuVH(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x2e79b800u | (q << 30), rd, rn); + } + + public readonly void FcvtmuV(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2e21b800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FcvtmuFloat(Operand rd, Operand rn, uint ftype, uint sf) + { + WriteInstruction(0x1e310000u | (ftype << 22) | (sf << 31), rd, rn); + } + + public readonly void FcvtnsSH(Operand rd, Operand rn) + { + WriteInstruction(0x5e79a800u, rd, rn); + } + + public readonly void FcvtnsS(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x5e21a800u | (sz << 22), rd, rn); + } + + public readonly void FcvtnsVH(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x0e79a800u | (q << 30), rd, rn); + } + + public readonly void FcvtnsV(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x0e21a800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FcvtnsFloat(Operand rd, Operand rn, uint ftype, uint sf) + { + WriteInstruction(0x1e200000u | (ftype << 22) | (sf << 31), rd, rn); + } + + public readonly void FcvtnuSH(Operand rd, Operand rn) + { + WriteInstruction(0x7e79a800u, rd, rn); + } + + public readonly void FcvtnuS(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x7e21a800u | (sz << 22), rd, rn); + } + + public readonly void FcvtnuVH(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x2e79a800u | (q << 30), rd, rn); + } + + public readonly void FcvtnuV(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2e21a800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FcvtnuFloat(Operand rd, Operand rn, uint ftype, uint sf) + { + WriteInstruction(0x1e210000u | (ftype << 22) | (sf << 31), rd, rn); + } + + public readonly void Fcvtn(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x0e216800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FcvtpsSH(Operand rd, Operand rn) + { + WriteInstruction(0x5ef9a800u, rd, rn); + } + + public readonly void FcvtpsS(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x5ea1a800u | (sz << 22), rd, rn); + } + + public readonly void FcvtpsVH(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x0ef9a800u | (q << 30), rd, rn); + } + + public readonly void FcvtpsV(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x0ea1a800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FcvtpsFloat(Operand rd, Operand rn, uint ftype, uint sf) + { + WriteInstruction(0x1e280000u | (ftype << 22) | (sf << 31), rd, rn); + } + + public readonly void FcvtpuSH(Operand rd, Operand rn) + { + WriteInstruction(0x7ef9a800u, rd, rn); + } + + public readonly void FcvtpuS(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x7ea1a800u | (sz << 22), rd, rn); + } + + public readonly void FcvtpuVH(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x2ef9a800u | (q << 30), rd, rn); + } + + public readonly void FcvtpuV(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2ea1a800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FcvtpuFloat(Operand rd, Operand rn, uint ftype, uint sf) + { + WriteInstruction(0x1e290000u | (ftype << 22) | (sf << 31), rd, rn); + } + + public readonly void FcvtxnS(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x7e216800u | (sz << 22), rd, rn); + } + + public readonly void FcvtxnV(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2e216800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FcvtzsFixS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x5f00fc00u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void FcvtzsFixV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x0f00fc00u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void FcvtzsIntSH(Operand rd, Operand rn) + { + WriteInstruction(0x5ef9b800u, rd, rn); + } + + public readonly void FcvtzsIntS(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x5ea1b800u | (sz << 22), rd, rn); + } + + public readonly void FcvtzsIntVH(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x0ef9b800u | (q << 30), rd, rn); + } + + public readonly void FcvtzsIntV(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x0ea1b800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FcvtzsFloatFix(Operand rd, Operand rn, uint scale, uint ftype, uint sf) + { + WriteInstruction(0x1e180000u | (scale << 10) | (ftype << 22) | (sf << 31), rd, rn); + } + + public readonly void FcvtzsFloatInt(Operand rd, Operand rn, uint ftype, uint sf) + { + WriteInstruction(0x1e380000u | (ftype << 22) | (sf << 31), rd, rn); + } + + public readonly void FcvtzuFixS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x7f00fc00u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void FcvtzuFixV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x2f00fc00u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void FcvtzuIntSH(Operand rd, Operand rn) + { + WriteInstruction(0x7ef9b800u, rd, rn); + } + + public readonly void FcvtzuIntS(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x7ea1b800u | (sz << 22), rd, rn); + } + + public readonly void FcvtzuIntVH(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x2ef9b800u | (q << 30), rd, rn); + } + + public readonly void FcvtzuIntV(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2ea1b800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FcvtzuFloatFix(Operand rd, Operand rn, uint scale, uint ftype, uint sf) + { + WriteInstruction(0x1e190000u | (scale << 10) | (ftype << 22) | (sf << 31), rd, rn); + } + + public readonly void FcvtzuFloatInt(Operand rd, Operand rn, uint ftype, uint sf) + { + WriteInstruction(0x1e390000u | (ftype << 22) | (sf << 31), rd, rn); + } + + public readonly void FcvtFloat(Operand rd, Operand rn, uint opc, uint ftype) + { + WriteInstruction(0x1e224000u | (opc << 15) | (ftype << 22), rd, rn); + } + + public readonly void FdivHalf(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x2e403c00u | (q << 30), rd, rn, rm); + } + + public readonly void FdivSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x2e20fc00u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FdivFloat(Operand rd, Operand rn, Operand rm, uint ftype) + { + WriteInstructionRm16(0x1e201800u | (ftype << 22), rd, rn, rm); + } + + public readonly void Fjcvtzs(Operand rd, Operand rn) + { + WriteInstruction(0x1e7e0000u, rd, rn); + } + + public readonly void FmaddFloat(Operand rd, Operand rn, Operand rm, Operand ra, uint ftype) + { + WriteInstruction(0x1f000000u | (ftype << 22), rd, rn, rm, ra); + } + + public readonly void FmaxnmpPairHalf(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x5e30c800u | (sz << 22), rd, rn); + } + + public readonly void FmaxnmpPairSingleAndDouble(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x7e30c800u | (sz << 22), rd, rn); + } + + public readonly void FmaxnmpVecHalf(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x2e400400u | (q << 30), rd, rn, rm); + } + + public readonly void FmaxnmpVecSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x2e20c400u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FmaxnmvHalf(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x0e30c800u | (q << 30), rd, rn); + } + + public readonly void FmaxnmvSingleAndDouble(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2e30c800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FmaxnmHalf(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x0e400400u | (q << 30), rd, rn, rm); + } + + public readonly void FmaxnmSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x0e20c400u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FmaxnmFloat(Operand rd, Operand rn, Operand rm, uint ftype) + { + WriteInstructionRm16(0x1e206800u | (ftype << 22), rd, rn, rm); + } + + public readonly void FmaxpPairHalf(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x5e30f800u | (sz << 22), rd, rn); + } + + public readonly void FmaxpPairSingleAndDouble(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x7e30f800u | (sz << 22), rd, rn); + } + + public readonly void FmaxpVecHalf(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x2e403400u | (q << 30), rd, rn, rm); + } + + public readonly void FmaxpVecSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x2e20f400u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FmaxvHalf(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x0e30f800u | (q << 30), rd, rn); + } + + public readonly void FmaxvSingleAndDouble(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2e30f800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FmaxHalf(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x0e403400u | (q << 30), rd, rn, rm); + } + + public readonly void FmaxSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x0e20f400u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FmaxFloat(Operand rd, Operand rn, Operand rm, uint ftype) + { + WriteInstructionRm16(0x1e204800u | (ftype << 22), rd, rn, rm); + } + + public readonly void FminnmpPairHalf(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x5eb0c800u | (sz << 22), rd, rn); + } + + public readonly void FminnmpPairSingleAndDouble(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x7eb0c800u | (sz << 22), rd, rn); + } + + public readonly void FminnmpVecHalf(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x2ec00400u | (q << 30), rd, rn, rm); + } + + public readonly void FminnmpVecSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x2ea0c400u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FminnmvHalf(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x0eb0c800u | (q << 30), rd, rn); + } + + public readonly void FminnmvSingleAndDouble(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2eb0c800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FminnmHalf(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x0ec00400u | (q << 30), rd, rn, rm); + } + + public readonly void FminnmSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x0ea0c400u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FminnmFloat(Operand rd, Operand rn, Operand rm, uint ftype) + { + WriteInstructionRm16(0x1e207800u | (ftype << 22), rd, rn, rm); + } + + public readonly void FminpPairHalf(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x5eb0f800u | (sz << 22), rd, rn); + } + + public readonly void FminpPairSingleAndDouble(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x7eb0f800u | (sz << 22), rd, rn); + } + + public readonly void FminpVecHalf(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x2ec03400u | (q << 30), rd, rn, rm); + } + + public readonly void FminpVecSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x2ea0f400u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FminvHalf(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x0eb0f800u | (q << 30), rd, rn); + } + + public readonly void FminvSingleAndDouble(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2eb0f800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FminHalf(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x0ec03400u | (q << 30), rd, rn, rm); + } + + public readonly void FminSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x0ea0f400u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FminFloat(Operand rd, Operand rn, Operand rm, uint ftype) + { + WriteInstructionRm16(0x1e205800u | (ftype << 22), rd, rn, rm); + } + + public readonly void FmlalEltFmlal(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q) + { + WriteInstructionRm16(0x0f800000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm); + } + + public readonly void FmlalEltFmlal2(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q) + { + WriteInstructionRm16(0x2f808000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm); + } + + public readonly void FmlalVecFmlal(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x0e20ec00u | (q << 30), rd, rn, rm); + } + + public readonly void FmlalVecFmlal2(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x2e20cc00u | (q << 30), rd, rn, rm); + } + + public readonly void FmlaElt2regScalarHalf(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l) + { + WriteInstructionRm16(0x5f001000u | (h << 11) | (m << 20) | (l << 21), rd, rn, rm); + } + + public readonly void FmlaElt2regScalarSingleAndDouble(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint sz) + { + WriteInstructionRm16(0x5f801000u | (h << 11) | (m << 20) | (l << 21) | (sz << 22), rd, rn, rm); + } + + public readonly void FmlaElt2regElementHalf(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q) + { + WriteInstructionRm16(0x0f001000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm); + } + + public readonly void FmlaElt2regElementSingleAndDouble(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint sz, uint q) + { + WriteInstructionRm16(0x0f801000u | (h << 11) | (m << 20) | (l << 21) | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FmlaVecHalf(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x0e400c00u | (q << 30), rd, rn, rm); + } + + public readonly void FmlaVecSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x0e20cc00u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FmlslEltFmlsl(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q) + { + WriteInstructionRm16(0x0f804000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm); + } + + public readonly void FmlslEltFmlsl2(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q) + { + WriteInstructionRm16(0x2f80c000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm); + } + + public readonly void FmlslVecFmlsl(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x0ea0ec00u | (q << 30), rd, rn, rm); + } + + public readonly void FmlslVecFmlsl2(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x2ea0cc00u | (q << 30), rd, rn, rm); + } + + public readonly void FmlsElt2regScalarHalf(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l) + { + WriteInstructionRm16(0x5f005000u | (h << 11) | (m << 20) | (l << 21), rd, rn, rm); + } + + public readonly void FmlsElt2regScalarSingleAndDouble(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint sz) + { + WriteInstructionRm16(0x5f805000u | (h << 11) | (m << 20) | (l << 21) | (sz << 22), rd, rn, rm); + } + + public readonly void FmlsElt2regElementHalf(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q) + { + WriteInstructionRm16(0x0f005000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm); + } + + public readonly void FmlsElt2regElementSingleAndDouble(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint sz, uint q) + { + WriteInstructionRm16(0x0f805000u | (h << 11) | (m << 20) | (l << 21) | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FmlsVecHalf(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x0ec00c00u | (q << 30), rd, rn, rm); + } + + public readonly void FmlsVecSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x0ea0cc00u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FmovPerHalf(Operand rd, uint h, uint g, uint f, uint e, uint d, uint c, uint b, uint a, uint q) + { + WriteInstruction(0x0f00fc00u | (h << 5) | (g << 6) | (f << 7) | (e << 8) | (d << 9) | (c << 16) | (b << 17) | (a << 18) | (q << 30), rd); + } + + public readonly void FmovSingleAndDouble(Operand rd, uint h, uint g, uint f, uint e, uint d, uint c, uint b, uint a, uint op, uint q) + { + WriteInstruction(0x0f00f400u | (h << 5) | (g << 6) | (f << 7) | (e << 8) | (d << 9) | (c << 16) | (b << 17) | (a << 18) | (op << 29) | (q << 30), rd); + } + + public readonly void FmovFloat(Operand rd, Operand rn, uint ftype) + { + WriteInstruction(0x1e204000u | (ftype << 22), rd, rn); + } + + public readonly void FmovFloatGen(Operand rd, Operand rn, uint ftype, uint sf, uint dir, uint top) + { + WriteInstruction(0x1e260000u | (dir << 16) | (top << 19) | (ftype << 22) | (sf << 31), rd, rn); + } + + public readonly void FmovFloatImm(Operand rd, uint imm8, uint ftype) + { + WriteInstruction(0x1e201000u | (imm8 << 13) | (ftype << 22), rd); + } + + public readonly void FmsubFloat(Operand rd, Operand rn, Operand rm, Operand ra, uint ftype) + { + WriteInstruction(0x1f008000u | (ftype << 22), rd, rn, rm, ra); + } + + public readonly void FmulxElt2regScalarHalf(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l) + { + WriteInstructionRm16(0x7f009000u | (h << 11) | (m << 20) | (l << 21), rd, rn, rm); + } + + public readonly void FmulxElt2regScalarSingleAndDouble(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint sz) + { + WriteInstructionRm16(0x7f809000u | (h << 11) | (m << 20) | (l << 21) | (sz << 22), rd, rn, rm); + } + + public readonly void FmulxElt2regElementHalf(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q) + { + WriteInstructionRm16(0x2f009000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm); + } + + public readonly void FmulxElt2regElementSingleAndDouble(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint sz, uint q) + { + WriteInstructionRm16(0x2f809000u | (h << 11) | (m << 20) | (l << 21) | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FmulxVecSH(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x5e401c00u, rd, rn, rm); + } + + public readonly void FmulxVecS(Operand rd, Operand rn, Operand rm, uint sz) + { + WriteInstructionRm16(0x5e20dc00u | (sz << 22), rd, rn, rm); + } + + public readonly void FmulxVecVH(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x0e401c00u | (q << 30), rd, rn, rm); + } + + public readonly void FmulxVecV(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x0e20dc00u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FmulElt2regScalarHalf(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l) + { + WriteInstructionRm16(0x5f009000u | (h << 11) | (m << 20) | (l << 21), rd, rn, rm); + } + + public readonly void FmulElt2regScalarSingleAndDouble(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint sz) + { + WriteInstructionRm16(0x5f809000u | (h << 11) | (m << 20) | (l << 21) | (sz << 22), rd, rn, rm); + } + + public readonly void FmulElt2regElementHalf(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q) + { + WriteInstructionRm16(0x0f009000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm); + } + + public readonly void FmulElt2regElementSingleAndDouble(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint sz, uint q) + { + WriteInstructionRm16(0x0f809000u | (h << 11) | (m << 20) | (l << 21) | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FmulVecHalf(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x2e401c00u | (q << 30), rd, rn, rm); + } + + public readonly void FmulVecSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x2e20dc00u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FmulFloat(Operand rd, Operand rn, Operand rm, uint ftype) + { + WriteInstructionRm16(0x1e200800u | (ftype << 22), rd, rn, rm); + } + + public readonly void FnegHalf(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x2ef8f800u | (q << 30), rd, rn); + } + + public readonly void FnegSingleAndDouble(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2ea0f800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FnegFloat(Operand rd, Operand rn, uint ftype) + { + WriteInstruction(0x1e214000u | (ftype << 22), rd, rn); + } + + public readonly void FnmaddFloat(Operand rd, Operand rn, Operand rm, Operand ra, uint ftype) + { + WriteInstruction(0x1f200000u | (ftype << 22), rd, rn, rm, ra); + } + + public readonly void FnmsubFloat(Operand rd, Operand rn, Operand rm, Operand ra, uint ftype) + { + WriteInstruction(0x1f208000u | (ftype << 22), rd, rn, rm, ra); + } + + public readonly void FnmulFloat(Operand rd, Operand rn, Operand rm, uint ftype) + { + WriteInstructionRm16(0x1e208800u | (ftype << 22), rd, rn, rm); + } + + public readonly void FrecpeSH(Operand rd, Operand rn) + { + WriteInstruction(0x5ef9d800u, rd, rn); + } + + public readonly void FrecpeS(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x5ea1d800u | (sz << 22), rd, rn); + } + + public readonly void FrecpeVH(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x0ef9d800u | (q << 30), rd, rn); + } + + public readonly void FrecpeV(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x0ea1d800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FrecpsSH(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x5e403c00u, rd, rn, rm); + } + + public readonly void FrecpsS(Operand rd, Operand rn, Operand rm, uint sz) + { + WriteInstructionRm16(0x5e20fc00u | (sz << 22), rd, rn, rm); + } + + public readonly void FrecpsVH(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x0e403c00u | (q << 30), rd, rn, rm); + } + + public readonly void FrecpsV(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x0e20fc00u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FrecpxHalf(Operand rd, Operand rn) + { + WriteInstruction(0x5ef9f800u, rd, rn); + } + + public readonly void FrecpxSingleAndDouble(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x5ea1f800u | (sz << 22), rd, rn); + } + + public readonly void Frint32x(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2e21e800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void Frint32xFloat(Operand rd, Operand rn) + { + WriteInstruction(0x1e28c000u, rd, rn); + } + + public readonly void Frint32z(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x0e21e800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void Frint32zFloat(Operand rd, Operand rn) + { + WriteInstruction(0x1e284000u, rd, rn); + } + + public readonly void Frint64x(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2e21f800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void Frint64xFloat(Operand rd, Operand rn) + { + WriteInstruction(0x1e29c000u, rd, rn); + } + + public readonly void Frint64z(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x0e21f800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void Frint64zFloat(Operand rd, Operand rn) + { + WriteInstruction(0x1e294000u, rd, rn); + } + + public readonly void FrintaHalf(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x2e798800u | (q << 30), rd, rn); + } + + public readonly void FrintaSingleAndDouble(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2e218800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FrintaFloat(Operand rd, Operand rn, uint ftype) + { + WriteInstruction(0x1e264000u | (ftype << 22), rd, rn); + } + + public readonly void FrintiHalf(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x2ef99800u | (q << 30), rd, rn); + } + + public readonly void FrintiSingleAndDouble(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2ea19800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FrintiFloat(Operand rd, Operand rn, uint ftype) + { + WriteInstruction(0x1e27c000u | (ftype << 22), rd, rn); + } + + public readonly void FrintmHalf(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x0e799800u | (q << 30), rd, rn); + } + + public readonly void FrintmSingleAndDouble(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x0e219800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FrintmFloat(Operand rd, Operand rn, uint ftype) + { + WriteInstruction(0x1e254000u | (ftype << 22), rd, rn); + } + + public readonly void FrintnHalf(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x0e798800u | (q << 30), rd, rn); + } + + public readonly void FrintnSingleAndDouble(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x0e218800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FrintnFloat(Operand rd, Operand rn, uint ftype) + { + WriteInstruction(0x1e244000u | (ftype << 22), rd, rn); + } + + public readonly void FrintpHalf(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x0ef98800u | (q << 30), rd, rn); + } + + public readonly void FrintpSingleAndDouble(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x0ea18800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FrintpFloat(Operand rd, Operand rn, uint ftype) + { + WriteInstruction(0x1e24c000u | (ftype << 22), rd, rn); + } + + public readonly void FrintxHalf(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x2e799800u | (q << 30), rd, rn); + } + + public readonly void FrintxSingleAndDouble(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2e219800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FrintxFloat(Operand rd, Operand rn, uint ftype) + { + WriteInstruction(0x1e274000u | (ftype << 22), rd, rn); + } + + public readonly void FrintzHalf(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x0ef99800u | (q << 30), rd, rn); + } + + public readonly void FrintzSingleAndDouble(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x0ea19800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FrintzFloat(Operand rd, Operand rn, uint ftype) + { + WriteInstruction(0x1e25c000u | (ftype << 22), rd, rn); + } + + public readonly void FrsqrteSH(Operand rd, Operand rn) + { + WriteInstruction(0x7ef9d800u, rd, rn); + } + + public readonly void FrsqrteS(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x7ea1d800u | (sz << 22), rd, rn); + } + + public readonly void FrsqrteVH(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x2ef9d800u | (q << 30), rd, rn); + } + + public readonly void FrsqrteV(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2ea1d800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FrsqrtsSH(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x5ec03c00u, rd, rn, rm); + } + + public readonly void FrsqrtsS(Operand rd, Operand rn, Operand rm, uint sz) + { + WriteInstructionRm16(0x5ea0fc00u | (sz << 22), rd, rn, rm); + } + + public readonly void FrsqrtsVH(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x0ec03c00u | (q << 30), rd, rn, rm); + } + + public readonly void FrsqrtsV(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x0ea0fc00u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FsqrtHalf(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x2ef9f800u | (q << 30), rd, rn); + } + + public readonly void FsqrtSingleAndDouble(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2ea1f800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void FsqrtFloat(Operand rd, Operand rn, uint ftype) + { + WriteInstruction(0x1e21c000u | (ftype << 22), rd, rn); + } + + public readonly void FsubHalf(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x0ec01400u | (q << 30), rd, rn, rm); + } + + public readonly void FsubSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q) + { + WriteInstructionRm16(0x0ea0d400u | (sz << 22) | (q << 30), rd, rn, rm); + } + + public readonly void FsubFloat(Operand rd, Operand rn, Operand rm, uint ftype) + { + WriteInstructionRm16(0x1e203800u | (ftype << 22), rd, rn, rm); + } + + public readonly void InsElt(Operand rd, Operand rn, uint imm4, uint imm5) + { + WriteInstruction(0x6e000400u | (imm4 << 11) | (imm5 << 16), rd, rn); + } + + public readonly void InsGen(Operand rd, Operand rn, uint imm5) + { + WriteInstruction(0x4e001c00u | (imm5 << 16), rd, rn); + } + + public readonly void Ld1rAsNoPostIndex(Operand rt, Operand rn, uint size, uint q) + { + WriteInstruction(0x0d40c000u | (size << 10) | (q << 30), rt, rn); + } + + public readonly void Ld1rAsPostIndex(Operand rt, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0dc0c000u | (size << 10) | (q << 30), rt, rn, rm); + } + + public readonly void Ld1MultAsNoPostIndex(Operand rt, Operand rn, uint registersCount, uint size, uint q) + { + WriteInstruction(0x0c402000u | (size << 10) | (EncodeLdSt1MultOpcode(registersCount) << 12) | (q << 30), rt, rn); + } + + public readonly void Ld1MultAsPostIndex(Operand rt, Operand rn, Operand rm, uint registersCount, uint size, uint q) + { + WriteInstructionRm16(0x0cc02000u | (size << 10) | (EncodeLdSt1MultOpcode(registersCount) << 12) | (q << 30), rt, rn, rm); + } + + public readonly void Ld1SnglAsNoPostIndex(Operand rt, Operand rn, uint index, uint size) + { + WriteInstruction(EncodeIndexSizeSngl(0x0d400000u, index, size), rt, rn); + } + + public readonly void Ld1SnglAsPostIndex(Operand rt, Operand rn, Operand rm, uint index, uint size) + { + WriteInstructionRm16(EncodeIndexSizeSngl(0x0dc00000u, index, size), rt, rn, rm); + } + + public readonly void Ld2rAsNoPostIndex(Operand rt, Operand rn, uint size, uint q) + { + WriteInstruction(0x0d60c000u | (size << 10) | (q << 30), rt, rn); + } + + public readonly void Ld2rAsPostIndex(Operand rt, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0de0c000u | (size << 10) | (q << 30), rt, rn, rm); + } + + public readonly void Ld2MultAsNoPostIndex(Operand rt, Operand rn, uint size, uint q) + { + WriteInstruction(0x0c408000u | (size << 10) | (q << 30), rt, rn); + } + + public readonly void Ld2MultAsPostIndex(Operand rt, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0cc08000u | (size << 10) | (q << 30), rt, rn, rm); + } + + public readonly void Ld2SnglAsNoPostIndex(Operand rt, Operand rn, uint index, uint size) + { + WriteInstruction(EncodeIndexSizeSngl(0x0d600000u, index, size), rt, rn); + } + + public readonly void Ld2SnglAsPostIndex(Operand rt, Operand rn, Operand rm, uint index, uint size) + { + WriteInstructionRm16(EncodeIndexSizeSngl(0x0de00000u, index, size), rt, rn, rm); + } + + public readonly void Ld3rAsNoPostIndex(Operand rt, Operand rn, uint size, uint q) + { + WriteInstruction(0x0d40e000u | (size << 10) | (q << 30), rt, rn); + } + + public readonly void Ld3rAsPostIndex(Operand rt, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0dc0e000u | (size << 10) | (q << 30), rt, rn, rm); + } + + public readonly void Ld3MultAsNoPostIndex(Operand rt, Operand rn, uint size, uint q) + { + WriteInstruction(0x0c404000u | (size << 10) | (q << 30), rt, rn); + } + + public readonly void Ld3MultAsPostIndex(Operand rt, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0cc04000u | (size << 10) | (q << 30), rt, rn, rm); + } + + public readonly void Ld3SnglAsNoPostIndex(Operand rt, Operand rn, uint index, uint size) + { + WriteInstruction(EncodeIndexSizeSngl(0x0d402000u, index, size), rt, rn); + } + + public readonly void Ld3SnglAsPostIndex(Operand rt, Operand rn, Operand rm, uint index, uint size) + { + WriteInstructionRm16(EncodeIndexSizeSngl(0x0dc02000u, index, size), rt, rn, rm); + } + + public readonly void Ld4rAsNoPostIndex(Operand rt, Operand rn, uint size, uint q) + { + WriteInstruction(0x0d60e000u | (size << 10) | (q << 30), rt, rn); + } + + public readonly void Ld4rAsPostIndex(Operand rt, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0de0e000u | (size << 10) | (q << 30), rt, rn, rm); + } + + public readonly void Ld4MultAsNoPostIndex(Operand rt, Operand rn, uint size, uint q) + { + WriteInstruction(0x0c400000u | (size << 10) | (q << 30), rt, rn); + } + + public readonly void Ld4MultAsPostIndex(Operand rt, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0cc00000u | (size << 10) | (q << 30), rt, rn, rm); + } + + public readonly void Ld4SnglAsNoPostIndex(Operand rt, Operand rn, uint index, uint size) + { + WriteInstruction(EncodeIndexSizeSngl(0x0d602000u, index, size), rt, rn); + } + + public readonly void Ld4SnglAsPostIndex(Operand rt, Operand rn, Operand rm, uint index, uint size) + { + WriteInstructionRm16(EncodeIndexSizeSngl(0x0de02000u, index, size), rt, rn, rm); + } + + public readonly void Ldap1Sngl(Operand rt, Operand rn, uint q) + { + WriteInstruction(0x0d418400u | (q << 30), rt, rn); + } + + public readonly void Ldra(Operand rt, Operand rn, uint w, uint imm9, uint s, uint m) + { + WriteInstruction(0xf8200400u | (w << 11) | (imm9 << 12) | (s << 22) | (m << 23), rt, rn); + } + + public readonly void MlaElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q) + { + WriteInstructionRm16(0x2f000000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void MlaVec(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e209400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void MlsElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q) + { + WriteInstructionRm16(0x2f004000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void MlsVec(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e209400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Movi(Operand rd, uint h, uint g, uint f, uint e, uint d, uint cmode, uint c, uint b, uint a, uint op, uint q) + { + WriteInstruction(0x0f000400u | (h << 5) | (g << 6) | (f << 7) | (e << 8) | (d << 9) | (cmode << 12) | (c << 16) | (b << 17) | (a << 18) | (op << 29) | (q << 30), rd); + } + + public readonly void MulElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q) + { + WriteInstructionRm16(0x0f008000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void MulVec(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e209c00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Mvni(Operand rd, uint h, uint g, uint f, uint e, uint d, uint cmode, uint c, uint b, uint a, uint q) + { + WriteInstruction(0x2f000400u | (h << 5) | (g << 6) | (f << 7) | (e << 8) | (d << 9) | (cmode << 12) | (c << 16) | (b << 17) | (a << 18) | (q << 30), rd); + } + + public readonly void NegS(Operand rd, Operand rn, uint size) + { + WriteInstruction(0x7e20b800u | (size << 22), rd, rn); + } + + public readonly void NegV(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x2e20b800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void Not(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x2e205800u | (q << 30), rd, rn); + } + + public readonly void Orn(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x0ee01c00u | (q << 30), rd, rn, rm); + } + + public readonly void OrrImm(Operand rd, uint h, uint g, uint f, uint e, uint d, uint c, uint b, uint a, uint q) + { + WriteInstruction(0x0f001400u | (h << 5) | (g << 6) | (f << 7) | (e << 8) | (d << 9) | (c << 16) | (b << 17) | (a << 18) | (q << 30), rd); + } + + public readonly void OrrReg(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x0ea01c00u | (q << 30), rd, rn, rm); + } + + public readonly void Pmull(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e20e000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Pmul(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e209c00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Raddhn(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e204000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Rax1(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0xce608c00u, rd, rn, rm); + } + + public readonly void Rbit(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x2e605800u | (q << 30), rd, rn); + } + + public readonly void Rev16(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x0e201800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void Rev32(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x2e200800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void Rev64(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x0e200800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void Rshrn(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x0f008c00u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void Rsubhn(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e206000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Sabal(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e205000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Saba(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e207c00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Sabdl(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e207000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Sabd(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e207400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Sadalp(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x0e206800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void Saddlp(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x0e202800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void Saddlv(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x0e303800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void Saddl(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e200000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Saddw(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e201000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void ScvtfFixS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x5f00e400u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void ScvtfFixV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x0f00e400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void ScvtfIntSH(Operand rd, Operand rn) + { + WriteInstruction(0x5e79d800u, rd, rn); + } + + public readonly void ScvtfIntS(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x5e21d800u | (sz << 22), rd, rn); + } + + public readonly void ScvtfIntVH(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x0e79d800u | (q << 30), rd, rn); + } + + public readonly void ScvtfIntV(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x0e21d800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void ScvtfFloatFix(Operand rd, Operand rn, uint scale, uint ftype, uint sf) + { + WriteInstruction(0x1e020000u | (scale << 10) | (ftype << 22) | (sf << 31), rd, rn); + } + + public readonly void ScvtfFloatInt(Operand rd, Operand rn, uint ftype, uint sf) + { + WriteInstruction(0x1e220000u | (ftype << 22) | (sf << 31), rd, rn); + } + + public readonly void SdotElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q) + { + WriteInstructionRm16(0x0f00e000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SdotVec(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e009400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Sha1c(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x5e000000u, rd, rn, rm); + } + + public readonly void Sha1h(Operand rd, Operand rn) + { + WriteInstruction(0x5e280800u, rd, rn); + } + + public readonly void Sha1m(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x5e002000u, rd, rn, rm); + } + + public readonly void Sha1p(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x5e001000u, rd, rn, rm); + } + + public readonly void Sha1su0(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x5e003000u, rd, rn, rm); + } + + public readonly void Sha1su1(Operand rd, Operand rn) + { + WriteInstruction(0x5e281800u, rd, rn); + } + + public readonly void Sha256h2(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x5e005000u, rd, rn, rm); + } + + public readonly void Sha256h(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x5e004000u, rd, rn, rm); + } + + public readonly void Sha256su0(Operand rd, Operand rn) + { + WriteInstruction(0x5e282800u, rd, rn); + } + + public readonly void Sha256su1(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x5e006000u, rd, rn, rm); + } + + public readonly void Sha512h2(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0xce608400u, rd, rn, rm); + } + + public readonly void Sha512h(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0xce608000u, rd, rn, rm); + } + + public readonly void Sha512su0(Operand rd, Operand rn) + { + WriteInstruction(0xcec08000u, rd, rn); + } + + public readonly void Sha512su1(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0xce608800u, rd, rn, rm); + } + + public readonly void Shadd(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e200400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Shll(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x2e213800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void ShlS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x5f005400u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void ShlV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x0f005400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void Shrn(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x0f008400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void Shsub(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e202400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SliS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x7f005400u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void SliV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x2f005400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void Sm3partw1(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0xce60c000u, rd, rn, rm); + } + + public readonly void Sm3partw2(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0xce60c400u, rd, rn, rm); + } + + public readonly void Sm3ss1(Operand rd, Operand rn, Operand rm, Operand ra) + { + WriteInstruction(0xce400000u, rd, rn, rm, ra); + } + + public readonly void Sm3tt1a(Operand rd, Operand rn, uint imm2, Operand rm) + { + WriteInstructionRm16(0xce408000u | (imm2 << 12), rd, rn, rm); + } + + public readonly void Sm3tt1b(Operand rd, Operand rn, uint imm2, Operand rm) + { + WriteInstructionRm16(0xce408400u | (imm2 << 12), rd, rn, rm); + } + + public readonly void Sm3tt2a(Operand rd, Operand rn, uint imm2, Operand rm) + { + WriteInstructionRm16(0xce408800u | (imm2 << 12), rd, rn, rm); + } + + public readonly void Sm3tt2b(Operand rd, Operand rn, uint imm2, Operand rm) + { + WriteInstructionRm16(0xce408c00u | (imm2 << 12), rd, rn, rm); + } + + public readonly void Sm4ekey(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0xce60c800u, rd, rn, rm); + } + + public readonly void Sm4e(Operand rd, Operand rn) + { + WriteInstruction(0xcec08400u, rd, rn); + } + + public readonly void Smaxp(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e20a400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Smaxv(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x0e30a800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void Smax(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e206400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Sminp(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e20ac00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Sminv(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x0e31a800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void Smin(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e206c00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SmlalElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q) + { + WriteInstructionRm16(0x0f002000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SmlalVec(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e208000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SmlslElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q) + { + WriteInstructionRm16(0x0f006000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SmlslVec(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e20a000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SmmlaVec(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x4e80a400u, rd, rn, rm); + } + + public readonly void Smov(Operand rd, Operand rn, int index, int size) + { + uint q = size == 2 ? 1u << 30 : 0u; + WriteInstruction(0x0e002c00u | (EncodeIndexSizeImm5(index, size) << 16) | q, rd, rn); + } + + public readonly void SmullElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q) + { + WriteInstructionRm16(0x0f00a000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SmullVec(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e20c000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SqabsS(Operand rd, Operand rn, uint size) + { + WriteInstruction(0x5e207800u | (size << 22), rd, rn); + } + + public readonly void SqabsV(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x0e207800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void SqaddS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x5e200c00u | (size << 22), rd, rn, rm); + } + + public readonly void SqaddV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e200c00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SqdmlalElt2regScalar(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size) + { + WriteInstructionRm16(0x5f003000u | (h << 11) | (m << 20) | (l << 21) | (size << 22), rd, rn, rm); + } + + public readonly void SqdmlalElt2regElement(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q) + { + WriteInstructionRm16(0x0f003000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SqdmlalVecS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x5e209000u | (size << 22), rd, rn, rm); + } + + public readonly void SqdmlalVecV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e209000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SqdmlslElt2regScalar(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size) + { + WriteInstructionRm16(0x5f007000u | (h << 11) | (m << 20) | (l << 21) | (size << 22), rd, rn, rm); + } + + public readonly void SqdmlslElt2regElement(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q) + { + WriteInstructionRm16(0x0f007000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SqdmlslVecS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x5e20b000u | (size << 22), rd, rn, rm); + } + + public readonly void SqdmlslVecV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e20b000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SqdmulhElt2regScalar(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size) + { + WriteInstructionRm16(0x5f00c000u | (h << 11) | (m << 20) | (l << 21) | (size << 22), rd, rn, rm); + } + + public readonly void SqdmulhElt2regElement(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q) + { + WriteInstructionRm16(0x0f00c000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SqdmulhVecS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x5e20b400u | (size << 22), rd, rn, rm); + } + + public readonly void SqdmulhVecV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e20b400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SqdmullElt2regScalar(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size) + { + WriteInstructionRm16(0x5f00b000u | (h << 11) | (m << 20) | (l << 21) | (size << 22), rd, rn, rm); + } + + public readonly void SqdmullElt2regElement(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q) + { + WriteInstructionRm16(0x0f00b000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SqdmullVecS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x5e20d000u | (size << 22), rd, rn, rm); + } + + public readonly void SqdmullVecV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e20d000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SqnegS(Operand rd, Operand rn, uint size) + { + WriteInstruction(0x7e207800u | (size << 22), rd, rn); + } + + public readonly void SqnegV(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x2e207800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void SqrdmlahElt2regScalar(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size) + { + WriteInstructionRm16(0x7f00d000u | (h << 11) | (m << 20) | (l << 21) | (size << 22), rd, rn, rm); + } + + public readonly void SqrdmlahElt2regElement(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q) + { + WriteInstructionRm16(0x2f00d000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SqrdmlahVecS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x7e008400u | (size << 22), rd, rn, rm); + } + + public readonly void SqrdmlahVecV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e008400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SqrdmlshElt2regScalar(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size) + { + WriteInstructionRm16(0x7f00f000u | (h << 11) | (m << 20) | (l << 21) | (size << 22), rd, rn, rm); + } + + public readonly void SqrdmlshElt2regElement(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q) + { + WriteInstructionRm16(0x2f00f000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SqrdmlshVecS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x7e008c00u | (size << 22), rd, rn, rm); + } + + public readonly void SqrdmlshVecV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e008c00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SqrdmulhElt2regScalar(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size) + { + WriteInstructionRm16(0x5f00d000u | (h << 11) | (m << 20) | (l << 21) | (size << 22), rd, rn, rm); + } + + public readonly void SqrdmulhElt2regElement(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q) + { + WriteInstructionRm16(0x0f00d000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SqrdmulhVecS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x7e20b400u | (size << 22), rd, rn, rm); + } + + public readonly void SqrdmulhVecV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e20b400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SqrshlS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x5e205c00u | (size << 22), rd, rn, rm); + } + + public readonly void SqrshlV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e205c00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SqrshrnS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x5f009c00u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void SqrshrnV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x0f009c00u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void SqrshrunS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x7f008c00u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void SqrshrunV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x2f008c00u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void SqshluS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x7f006400u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void SqshluV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x2f006400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void SqshlImmS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x5f007400u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void SqshlImmV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x0f007400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void SqshlRegS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x5e204c00u | (size << 22), rd, rn, rm); + } + + public readonly void SqshlRegV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e204c00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SqshrnS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x5f009400u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void SqshrnV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x0f009400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void SqshrunS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x7f008400u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void SqshrunV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x2f008400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void SqsubS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x5e202c00u | (size << 22), rd, rn, rm); + } + + public readonly void SqsubV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e202c00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SqxtnS(Operand rd, Operand rn, uint size) + { + WriteInstruction(0x5e214800u | (size << 22), rd, rn); + } + + public readonly void SqxtnV(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x0e214800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void SqxtunS(Operand rd, Operand rn, uint size) + { + WriteInstruction(0x7e212800u | (size << 22), rd, rn); + } + + public readonly void SqxtunV(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x2e212800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void Srhadd(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e201400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SriS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x7f004400u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void SriV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x2f004400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void SrshlS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x5e205400u | (size << 22), rd, rn, rm); + } + + public readonly void SrshlV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e205400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SrshrS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x5f002400u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void SrshrV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x0f002400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void SrsraS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x5f003400u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void SrsraV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x0f003400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void Sshll(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x0f00a400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void SshlS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x5e204400u | (size << 22), rd, rn, rm); + } + + public readonly void SshlV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e204400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SshrS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x5f000400u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void SshrV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x0f000400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void SsraS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x5f001400u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void SsraV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x0f001400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void Ssubl(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e202000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Ssubw(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e203000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void St1MultAsNoPostIndex(Operand rt, Operand rn, uint registersCount, uint size, uint q) + { + WriteInstruction(0x0c002000u | (size << 10) | (EncodeLdSt1MultOpcode(registersCount) << 12) | (q << 30), rt, rn); + } + + public readonly void St1MultAsPostIndex(Operand rt, Operand rn, Operand rm, uint registersCount, uint size, uint q) + { + WriteInstructionRm16(0x0c802000u | (size << 10) | (EncodeLdSt1MultOpcode(registersCount) << 12) | (q << 30), rt, rn, rm); + } + + public readonly void St1SnglAsNoPostIndex(Operand rt, Operand rn, uint index, uint size) + { + WriteInstruction(EncodeIndexSizeSngl(0x0d000000u, index, size), rt, rn); + } + + public readonly void St1SnglAsPostIndex(Operand rt, Operand rn, Operand rm, uint index, uint size) + { + WriteInstructionRm16(EncodeIndexSizeSngl(0x0d800000u, index, size), rt, rn, rm); + } + + public readonly void St2MultAsNoPostIndex(Operand rt, Operand rn, uint size, uint q) + { + WriteInstruction(0x0c008000u | (size << 10) | (q << 30), rt, rn); + } + + public readonly void St2MultAsPostIndex(Operand rt, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0c808000u | (size << 10) | (q << 30), rt, rn, rm); + } + + public readonly void St2SnglAsNoPostIndex(Operand rt, Operand rn, uint index, uint size) + { + WriteInstruction(EncodeIndexSizeSngl(0x0d200000u, index, size), rt, rn); + } + + public readonly void St2SnglAsPostIndex(Operand rt, Operand rn, Operand rm, uint index, uint size) + { + WriteInstructionRm16(EncodeIndexSizeSngl(0x0da00000u, index, size), rt, rn, rm); + } + + public readonly void St3MultAsNoPostIndex(Operand rt, Operand rn, uint size, uint q) + { + WriteInstruction(0x0c004000u | (size << 10) | (q << 30), rt, rn); + } + + public readonly void St3MultAsPostIndex(Operand rt, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0c804000u | (size << 10) | (q << 30), rt, rn, rm); + } + + public readonly void St3SnglAsNoPostIndex(Operand rt, Operand rn, uint index, uint size) + { + WriteInstruction(EncodeIndexSizeSngl(0x0d002000u, index, size), rt, rn); + } + + public readonly void St3SnglAsPostIndex(Operand rt, Operand rn, Operand rm, uint index, uint size) + { + WriteInstructionRm16(EncodeIndexSizeSngl(0x0d802000u, index, size), rt, rn, rm); + } + + public readonly void St4MultAsNoPostIndex(Operand rt, Operand rn, uint size, uint q) + { + WriteInstruction(0x0c000000u | (size << 10) | (q << 30), rt, rn); + } + + public readonly void St4MultAsPostIndex(Operand rt, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0c800000u | (size << 10) | (q << 30), rt, rn, rm); + } + + public readonly void St4SnglAsNoPostIndex(Operand rt, Operand rn, uint index, uint size) + { + WriteInstruction(EncodeIndexSizeSngl(0x0d202000u, index, size), rt, rn); + } + + public readonly void St4SnglAsPostIndex(Operand rt, Operand rn, Operand rm, uint index, uint size) + { + WriteInstructionRm16(EncodeIndexSizeSngl(0x0da02000u, index, size), rt, rn, rm); + } + + public readonly void Stl1Sngl(Operand rt, Operand rn, uint q) + { + WriteInstruction(0x0d018400u | (q << 30), rt, rn); + } + + public readonly void Subhn(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e206000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SubS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x7e208400u | (size << 22), rd, rn, rm); + } + + public readonly void SubV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e208400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void SudotElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q) + { + WriteInstructionRm16(0x0f00f000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm); + } + + public readonly void SuqaddS(Operand rd, Operand rn, uint size) + { + WriteInstruction(0x5e203800u | (size << 22), rd, rn); + } + + public readonly void SuqaddV(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x0e203800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void Tbl(Operand rd, Operand rn, uint len, Operand rm, uint q) + { + WriteInstructionRm16(0x0e000000u | (len << 13) | (q << 30), rd, rn, rm); + } + + public readonly void Tbx(Operand rd, Operand rn, uint len, Operand rm, uint q) + { + WriteInstructionRm16(0x0e001000u | (len << 13) | (q << 30), rd, rn, rm); + } + + public readonly void Trn1(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e002800u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Trn2(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e006800u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Uabal(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e205000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Uaba(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e207c00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Uabdl(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e207000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Uabd(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e207400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Uadalp(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x2e206800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void Uaddlp(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x2e202800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void Uaddlv(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x2e303800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void Uaddl(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e200000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Uaddw(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e201000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void UcvtfFixS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x7f00e400u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void UcvtfFixV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x2f00e400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void UcvtfIntSH(Operand rd, Operand rn) + { + WriteInstruction(0x7e79d800u, rd, rn); + } + + public readonly void UcvtfIntS(Operand rd, Operand rn, uint sz) + { + WriteInstruction(0x7e21d800u | (sz << 22), rd, rn); + } + + public readonly void UcvtfIntVH(Operand rd, Operand rn, uint q) + { + WriteInstruction(0x2e79d800u | (q << 30), rd, rn); + } + + public readonly void UcvtfIntV(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2e21d800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void UcvtfFloatFix(Operand rd, Operand rn, uint scale, uint ftype, uint sf) + { + WriteInstruction(0x1e030000u | (scale << 10) | (ftype << 22) | (sf << 31), rd, rn); + } + + public readonly void UcvtfFloatInt(Operand rd, Operand rn, uint ftype, uint sf) + { + WriteInstruction(0x1e230000u | (ftype << 22) | (sf << 31), rd, rn); + } + + public readonly void UdotElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q) + { + WriteInstructionRm16(0x2f00e000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void UdotVec(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e009400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Uhadd(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e200400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Uhsub(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e202400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Umaxp(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e20a400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Umaxv(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x2e30a800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void Umax(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e206400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Uminp(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e20ac00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Uminv(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x2e31a800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void Umin(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e206c00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void UmlalElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q) + { + WriteInstructionRm16(0x2f002000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void UmlalVec(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e208000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void UmlslElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q) + { + WriteInstructionRm16(0x2f006000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void UmlslVec(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e20a000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void UmmlaVec(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x6e80a400u, rd, rn, rm); + } + + public readonly void Umov(Operand rd, Operand rn, int index, int size) + { + uint q = size == 3 ? 1u << 30 : 0u; + WriteInstruction(0x0e003c00u | (EncodeIndexSizeImm5(index, size) << 16) | q, rd, rn); + } + + public readonly void UmullElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q) + { + WriteInstructionRm16(0x2f00a000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void UmullVec(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e20c000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void UqaddS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x7e200c00u | (size << 22), rd, rn, rm); + } + + public readonly void UqaddV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e200c00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void UqrshlS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x7e205c00u | (size << 22), rd, rn, rm); + } + + public readonly void UqrshlV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e205c00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void UqrshrnS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x7f009c00u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void UqrshrnV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x2f009c00u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void UqshlImmS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x7f007400u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void UqshlImmV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x2f007400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void UqshlRegS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x7e204c00u | (size << 22), rd, rn, rm); + } + + public readonly void UqshlRegV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e204c00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void UqshrnS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x7f009400u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void UqshrnV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x2f009400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void UqsubS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x7e202c00u | (size << 22), rd, rn, rm); + } + + public readonly void UqsubV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e202c00u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void UqxtnS(Operand rd, Operand rn, uint size) + { + WriteInstruction(0x7e214800u | (size << 22), rd, rn); + } + + public readonly void UqxtnV(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x2e214800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void Urecpe(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x0ea1c800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void Urhadd(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e201400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void UrshlS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x7e205400u | (size << 22), rd, rn, rm); + } + + public readonly void UrshlV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e205400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void UrshrS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x7f002400u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void UrshrV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x2f002400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void Ursqrte(Operand rd, Operand rn, uint sz, uint q) + { + WriteInstruction(0x2ea1c800u | (sz << 22) | (q << 30), rd, rn); + } + + public readonly void UrsraS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x7f003400u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void UrsraV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x2f003400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void UsdotElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q) + { + WriteInstructionRm16(0x0f80f000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm); + } + + public readonly void UsdotVec(Operand rd, Operand rn, Operand rm, uint q) + { + WriteInstructionRm16(0x0e809c00u | (q << 30), rd, rn, rm); + } + + public readonly void Ushll(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x2f00a400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void UshlS(Operand rd, Operand rn, Operand rm, uint size) + { + WriteInstructionRm16(0x7e204400u | (size << 22), rd, rn, rm); + } + + public readonly void UshlV(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e204400u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void UshrS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x7f000400u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void UshrV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x2f000400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void UsmmlaVec(Operand rd, Operand rn, Operand rm) + { + WriteInstructionRm16(0x4e80ac00u, rd, rn, rm); + } + + public readonly void UsqaddS(Operand rd, Operand rn, uint size) + { + WriteInstruction(0x7e203800u | (size << 22), rd, rn); + } + + public readonly void UsqaddV(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x2e203800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void UsraS(Operand rd, Operand rn, uint immb, uint immh) + { + WriteInstruction(0x7f001400u | (immb << 16) | (immh << 19), rd, rn); + } + + public readonly void UsraV(Operand rd, Operand rn, uint immb, uint immh, uint q) + { + WriteInstruction(0x2f001400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn); + } + + public readonly void Usubl(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e202000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Usubw(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x2e203000u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Uzp1(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e001800u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Uzp2(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e005800u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Wfe() + { + WriteUInt32(0xd503205fu); + } + + public readonly void Wfi() + { + WriteUInt32(0xd503207fu); + } + + public readonly void Xar(Operand rd, Operand rn, uint imm6, Operand rm) + { + WriteInstructionRm16(0xce800000u | (imm6 << 10), rd, rn, rm); + } + + public readonly void Xtn(Operand rd, Operand rn, uint size, uint q) + { + WriteInstruction(0x0e212800u | (size << 22) | (q << 30), rd, rn); + } + + public readonly void Yield() + { + WriteUInt32(0xd503203fu); + } + + public readonly void Zip1(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e003800u | (size << 22) | (q << 30), rd, rn, rm); + } + + public readonly void Zip2(Operand rd, Operand rn, Operand rm, uint size, uint q) + { + WriteInstructionRm16(0x0e007800u | (size << 22) | (q << 30), rd, rn, rm); + } + + // Utility + + public readonly void WriteSysRegInstruction(uint inst, Operand rt, uint o0, uint op1, uint crn, uint crm, uint op2) + { + inst |= (op2 & 7) << 5; + inst |= (crm & 15) << 8; + inst |= (crn & 15) << 12; + inst |= (op1 & 7) << 16; + inst |= (o0 & 1) << 19; + + WriteInstruction(inst, rt); + } + + private readonly void WriteInstructionAuto( + uint instI, + uint instR, + Operand rd, + Operand rn, + Operand rm, + ArmShiftType shiftType = ArmShiftType.Lsl, + int shiftAmount = 0, + bool immForm = false) + { + if (rm.Kind == OperandKind.Constant && (rm.Value != 0 || immForm)) + { + Debug.Assert(shiftAmount == 0); + int imm = rm.AsInt32(); + Debug.Assert((uint)imm == rm.Value); + if (imm != 0 && (imm & 0xfff) == 0) + { + instI |= 1 << 22; // sh flag + imm >>= 12; + } + WriteInstructionAuto(instI | (EncodeUImm12(imm, 0) << 10), rd, rn); + } + else + { + Debug.Assert((uint)shiftType < 3); // ROR shift is a reserved encoding for ADD and SUB. + instR |= EncodeUImm6(shiftAmount) << 10; + instR |= (uint)shiftType << 22; + + WriteInstructionRm16Auto(instR, rd, rn, rm); + } + } + + private readonly void WriteInstructionAuto( + uint instR, + Operand rd, + Operand rn, + Operand rm, + ArmShiftType shiftType = ArmShiftType.Lsl, + int shiftAmount = 0) + { + instR |= EncodeUImm6(shiftAmount) << 10; + instR |= (uint)shiftType << 22; + + WriteInstructionRm16Auto(instR, rd, rn, rm); + } + + private readonly void WriteInstructionAuto( + uint instruction, + Operand rd, + Operand rn, + Operand rm, + ArmExtensionType extensionType, + int shiftAmount = 0) + { + Debug.Assert((uint)shiftAmount <= 4); + + instruction |= (uint)shiftAmount << 10; + instruction |= (uint)extensionType << 13; + + WriteInstructionRm16Auto(instruction, rd, rn, rm); + } + + private readonly void WriteInstructionBitwiseAuto( + uint instI, + uint instR, + Operand rd, + Operand rn, + Operand rm, + ArmShiftType shiftType = ArmShiftType.Lsl, + int shiftAmount = 0) + { + if (rm.Kind == OperandKind.Constant && rm.Value != 0) + { + Debug.Assert(shiftAmount == 0); + bool canEncode = CodeGenCommon.TryEncodeBitMask(rm, out int immN, out int immS, out int immR); + Debug.Assert(canEncode); + uint instruction = instI | ((uint)immS << 10) | ((uint)immR << 16) | ((uint)immN << 22); + + WriteInstructionAuto(instruction, rd, rn); + } + else + { + WriteInstructionBitwiseAuto(instR, rd, rn, rm, shiftType, shiftAmount); + } + } + + private readonly void WriteInstructionBitwiseAuto( + uint instruction, + Operand rd, + Operand rn, + Operand rm, + ArmShiftType shiftType = ArmShiftType.Lsl, + int shiftAmount = 0) + { + if (rd.Type == OperandType.I64) + { + instruction |= SfFlag; + } + + instruction |= EncodeUImm6(shiftAmount) << 10; + instruction |= (uint)shiftType << 22; + + WriteInstructionRm16(instruction, rd, rn, rm); + } + + private readonly void WriteInstructionLdrStrAuto( + uint instruction, + Operand rd, + Operand rn, + Operand rm, + ArmExtensionType extensionType, + bool shift) + { + if (shift) + { + instruction |= 1u << 12; + } + + instruction |= (uint)extensionType << 13; + + if (rd.Type == OperandType.I64) + { + instruction |= 1u << 30; + } + + WriteInstructionRm16(instruction, rd, rn, rm); + } + + private readonly void WriteInstructionAuto(uint instruction, Operand rd) + { + if (rd.Type == OperandType.I64) + { + instruction |= SfFlag; + } + + WriteInstruction(instruction, rd); + } + + public readonly void WriteInstructionAuto(uint instruction, Operand rd, Operand rn) + { + if (rd.Type == OperandType.I64) + { + instruction |= SfFlag; + } + + WriteInstruction(instruction, rd, rn); + } + + private readonly void WriteInstructionAuto(uint instruction, Operand rd, Operand rn, Operand rm, Operand ra) + { + if (rd.Type == OperandType.I64) + { + instruction |= SfFlag; + } + + WriteInstruction(instruction, rd, rn, rm, ra); + } + + public readonly void WriteInstruction(uint instruction, Operand rd) + { + WriteUInt32(instruction | EncodeReg(rd)); + } + + public readonly void WriteInstruction(uint instruction, Operand rd, Operand rn) + { + WriteUInt32(instruction | EncodeReg(rd) | (EncodeReg(rn) << 5)); + } + + public readonly void WriteInstruction(uint instruction, Operand rd, Operand rn, Operand rm) + { + WriteUInt32(instruction | EncodeReg(rd) | (EncodeReg(rn) << 5) | (EncodeReg(rm) << 10)); + } + + public readonly void WriteInstruction(uint instruction, Operand rd, Operand rn, Operand rm, Operand ra) + { + WriteUInt32(instruction | EncodeReg(rd) | (EncodeReg(rn) << 5) | (EncodeReg(ra) << 10) | (EncodeReg(rm) << 16)); + } + + private readonly void WriteInstructionRm16Auto(uint instruction, Operand rd, Operand rn, Operand rm) + { + if (rd.Type == OperandType.I64) + { + instruction |= SfFlag; + } + + WriteInstructionRm16(instruction, rd, rn, rm); + } + + public readonly void WriteInstructionRm16(uint instruction, Operand rn, Operand rm) + { + WriteUInt32(instruction | (EncodeReg(rn) << 5) | (EncodeReg(rm) << 16)); + } + + public readonly void WriteInstructionRm16(uint instruction, Operand rd, Operand rn, Operand rm) + { + WriteUInt32(instruction | EncodeReg(rd) | (EncodeReg(rn) << 5) | (EncodeReg(rm) << 16)); + } + + private static uint GetLdpStpInstruction(uint intInst, uint vecInst, int imm, OperandType type) + { + uint instruction; + int scale; + + if (type.IsInteger()) + { + instruction = intInst; + + if (type == OperandType.I64) + { + instruction |= SfFlag; + scale = 3; + } + else + { + scale = 2; + } + } + else + { + int opc = type switch + { + OperandType.FP32 => 0, + OperandType.FP64 => 1, + _ => 2, + }; + + instruction = vecInst | ((uint)opc << 30); + scale = 2 + opc; + } + + instruction |= (EncodeSImm7(imm, scale) << 15); + + return instruction; + } + + private static uint GetLdrStrInstruction(uint intInst, uint vecInst, OperandType type) + { + uint instruction; + + if (type.IsInteger()) + { + instruction = intInst; + + if (type == OperandType.I64) + { + instruction |= 1 << 30; + } + } + else + { + instruction = vecInst; + + if (type == OperandType.V128) + { + instruction |= 1u << 23; + } + else + { + instruction |= type == OperandType.FP32 ? 2u << 30 : 3u << 30; + } + } + + return instruction; + } + + private static uint GetLdrStrInstruction(uint intInst, uint vecInst, OperandType type, uint size) + { + uint instruction; + + if (type.IsInteger()) + { + instruction = intInst; + + if (type == OperandType.I64) + { + instruction |= 1 << 30; + } + } + else + { + instruction = vecInst; + + if (type == OperandType.V128) + { + instruction |= 1u << 23; + } + else + { + instruction |= size << 30; + } + } + + return instruction; + } + + private static uint EncodeIndexSizeImm5(int index, int size) + { + Debug.Assert((uint)size < 4); + Debug.Assert((uint)index < (16u >> size), $"Invalid index {index} and size {size} combination."); + return ((uint)index << (size + 1)) | (1u << size); + } + + private static uint EncodeSImm7(int value, int scale) + { + uint imm = (uint)(value >> scale) & 0x7f; + Debug.Assert(((int)imm << 25) >> (25 - scale) == value, $"Failed to encode constant 0x{value:X} with scale {scale}."); + return imm; + } + + private static uint EncodeSImm9(int value) + { + uint imm = (uint)value & 0x1ff; + Debug.Assert(((int)imm << 23) >> 23 == value, $"Failed to encode constant 0x{value:X}."); + return imm; + } + + private static uint EncodeSImm19_2(int value) + { + uint imm = (uint)(value >> 2) & 0x7ffff; + Debug.Assert(((int)imm << 13) >> 11 == value, $"Failed to encode constant 0x{value:X}."); + return imm; + } + + private static uint EncodeSImm26_2(int value) + { + uint imm = (uint)(value >> 2) & 0x3ffffff; + Debug.Assert(((int)imm << 6) >> 4 == value, $"Failed to encode constant 0x{value:X}."); + return imm; + } + + private static uint EncodeUImm4(int value) + { + uint imm = (uint)value & 0xf; + Debug.Assert((int)imm == value, $"Failed to encode constant 0x{value:X}."); + return imm; + } + + private static uint EncodeUImm6(int value) + { + uint imm = (uint)value & 0x3f; + Debug.Assert((int)imm == value, $"Failed to encode constant 0x{value:X}."); + return imm; + } + + private static uint EncodeUImm12(int value, OperandType type) + { + return EncodeUImm12(value, GetScaleForType(type)); + } + + private static uint EncodeUImm12(int value, int scale) + { + uint imm = (uint)(value >> scale) & 0xfff; + Debug.Assert((int)imm << scale == value, $"Failed to encode constant 0x{value:X} with scale {scale}."); + return imm; + } + + private static uint EncodeUImm16(int value) + { + uint imm = (uint)value & 0xffff; + Debug.Assert((int)imm == value, $"Failed to encode constant 0x{value:X}."); + return imm; + } + + private static uint EncodeReg(Operand reg) + { + if (reg.Kind == OperandKind.Constant && reg.Value == 0) + { + return ZrRegister; + } + + uint regIndex = (uint)reg.GetRegister().Index; + Debug.Assert(reg.Kind == OperandKind.Register); + Debug.Assert(regIndex < 32); + return regIndex; + } + + private static uint EncodeTypeTargetPolicy(uint type, uint target, uint policy) + { + Debug.Assert(type <= 2); + Debug.Assert(target <= 2); + Debug.Assert(policy <= 1); + + return (type << 3) | (target << 1) | policy; + } + + private static uint EncodeIndexSizeSngl(uint inst, uint index, uint size) + { + uint opcode = Math.Min(2u, size) << 1; + + index <<= (int)size; + + if (size == 3) + { + index |= 1u; + } + + size = index & 3; + uint s = (index >> 2) & 1; + uint q = index >> 3; + + Debug.Assert(q <= 1); + + return inst | (size << 10) | (s << 12) | (opcode << 13) | (q << 30); + } + + private static uint EncodeLdSt1MultOpcode(uint registersCount) + { + return registersCount switch + { + 2 => 0b1010, + 3 => 0b0110, + 4 => 0b0010, + _ => 0b0111, + }; + } + + private static int GetScaleForType(OperandType type) + { + return type switch + { + OperandType.I32 => 2, + OperandType.I64 => 3, + OperandType.FP32 => 2, + OperandType.FP64 => 3, + OperandType.V128 => 4, + _ => throw new ArgumentException($"Invalid type {type}."), + }; + } + + private readonly void WriteUInt32(uint value) + { + _code.Add(value); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/CodeGenCommon.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/CodeGenCommon.cs new file mode 100644 index 000000000..db6a71593 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/CodeGenCommon.cs @@ -0,0 +1,67 @@ +using System.Numerics; + +namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64 +{ + static class CodeGenCommon + { + public static bool TryEncodeBitMask(Operand operand, out int immN, out int immS, out int immR) + { + return TryEncodeBitMask(operand.Type, operand.Value, out immN, out immS, out immR); + } + + public static bool TryEncodeBitMask(OperandType type, ulong value, out int immN, out int immS, out int immR) + { + if (type == OperandType.I32) + { + value &= uint.MaxValue; + value |= value << 32; + } + + return TryEncodeBitMask(value, out immN, out immS, out immR); + } + + public static bool TryEncodeBitMask(ulong value, out int immN, out int immS, out int immR) + { + // Some special values also can't be encoded: + // 0 can't be encoded because we need to subtract 1 from onesCount (which would became negative if 0). + // A value with all bits set can't be encoded because it is reserved according to the spec, because: + // Any value AND all ones will be equal itself, so it's effectively a no-op. + // Any value OR all ones will be equal all ones, so one can just use MOV. + // Any value XOR all ones will be equal its inverse, so one can just use MVN. + if (value == 0 || value == ulong.MaxValue) + { + immN = 0; + immS = 0; + immR = 0; + + return false; + } + + // Normalize value, rotating it such that the LSB is 1: Ensures we get a complete element that has not + // been cut-in-half across the word boundary. + int rotation = BitOperations.TrailingZeroCount(value & (value + 1)); + ulong rotatedValue = ulong.RotateRight(value, rotation); + + // Now that we have a complete element in the LSB with the LSB = 1, determine size and number of ones + // in element. + int elementSize = BitOperations.TrailingZeroCount(rotatedValue & (rotatedValue + 1)); + int onesInElement = BitOperations.TrailingZeroCount(~rotatedValue); + + // Check the value is repeating; also ensures element size is a power of two. + if (ulong.RotateRight(value, elementSize) != value) + { + immN = 0; + immS = 0; + immR = 0; + + return false; + } + + immN = (elementSize >> 6) & 1; + immS = (((~elementSize + 1) << 1) | (onesInElement - 1)) & 0x3f; + immR = (elementSize - rotation) & (elementSize - 1); + + return true; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/RegisterSaveRestore.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/RegisterSaveRestore.cs new file mode 100644 index 000000000..b4b8bb524 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/RegisterSaveRestore.cs @@ -0,0 +1,252 @@ +using System.Numerics; + +namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64 +{ + readonly struct RegisterSaveRestore + { + private const int FpRegister = 29; + private const int LrRegister = 30; + + public const int Encodable9BitsOffsetLimit = 0x100; + + private readonly uint _gprMask; + private readonly uint _fpSimdMask; + private readonly OperandType _fpSimdType; + private readonly int _reservedStackSize; + private readonly bool _hasCall; + + public RegisterSaveRestore( + uint gprMask, + uint fpSimdMask = 0, + OperandType fpSimdType = OperandType.FP64, + bool hasCall = false, + int reservedStackSize = 0) + { + _gprMask = gprMask; + _fpSimdMask = fpSimdMask; + _fpSimdType = fpSimdType; + _reservedStackSize = reservedStackSize; + _hasCall = hasCall; + } + + public int GetReservedStackOffset() + { + int gprCalleeSavedRegsCount = BitOperations.PopCount(_gprMask); + int fpSimdCalleeSavedRegsCount = BitOperations.PopCount(_fpSimdMask); + + return (_hasCall ? 16 : 0) + Align16(gprCalleeSavedRegsCount * 8 + fpSimdCalleeSavedRegsCount * _fpSimdType.GetSizeInBytes()); + } + + public void WritePrologue(ref Assembler asm) + { + uint gprMask = _gprMask; + uint fpSimdMask = _fpSimdMask; + + int gprCalleeSavedRegsCount = BitOperations.PopCount(gprMask); + int fpSimdCalleeSavedRegsCount = BitOperations.PopCount(fpSimdMask); + + int reservedStackSize = Align16(_reservedStackSize); + int calleeSaveRegionSize = Align16(gprCalleeSavedRegsCount * 8 + fpSimdCalleeSavedRegsCount * _fpSimdType.GetSizeInBytes()) + reservedStackSize; + int offset = 0; + + WritePrologueCalleeSavesPreIndexed(ref asm, ref gprMask, ref offset, calleeSaveRegionSize, OperandType.I64); + + if (_fpSimdType == OperandType.V128 && (gprCalleeSavedRegsCount & 1) != 0) + { + offset += 8; + } + + WritePrologueCalleeSavesPreIndexed(ref asm, ref fpSimdMask, ref offset, calleeSaveRegionSize, _fpSimdType); + + if (_hasCall) + { + Operand rsp = Register(Assembler.SpRegister); + + if (offset != 0 || calleeSaveRegionSize + 16 < Encodable9BitsOffsetLimit) + { + asm.StpRiPre(Register(FpRegister), Register(LrRegister), rsp, offset == 0 ? -(calleeSaveRegionSize + 16) : -16); + } + else + { + asm.Sub(rsp, rsp, new Operand(OperandKind.Constant, OperandType.I64, (ulong)calleeSaveRegionSize)); + asm.StpRiPre(Register(FpRegister), Register(LrRegister), rsp, -16); + } + + asm.MovSp(Register(FpRegister), rsp); + } + } + + private static void WritePrologueCalleeSavesPreIndexed( + ref Assembler asm, + ref uint mask, + ref int offset, + int calleeSaveRegionSize, + OperandType type) + { + if ((BitOperations.PopCount(mask) & 1) != 0) + { + int reg = BitOperations.TrailingZeroCount(mask); + + mask &= ~(1u << reg); + + if (offset != 0) + { + asm.StrRiUn(Register(reg, type), Register(Assembler.SpRegister), offset); + } + else if (calleeSaveRegionSize < Encodable9BitsOffsetLimit) + { + asm.StrRiPre(Register(reg, type), Register(Assembler.SpRegister), -calleeSaveRegionSize); + } + else + { + asm.Sub(Register(Assembler.SpRegister), Register(Assembler.SpRegister), new Operand(OperandType.I64, (ulong)calleeSaveRegionSize)); + asm.StrRiUn(Register(reg, type), Register(Assembler.SpRegister), 0); + } + + offset += type.GetSizeInBytes(); + } + + while (mask != 0) + { + int reg = BitOperations.TrailingZeroCount(mask); + + mask &= ~(1u << reg); + + int reg2 = BitOperations.TrailingZeroCount(mask); + + mask &= ~(1u << reg2); + + if (offset != 0) + { + asm.StpRiUn(Register(reg, type), Register(reg2, type), Register(Assembler.SpRegister), offset); + } + else if (calleeSaveRegionSize < Encodable9BitsOffsetLimit) + { + asm.StpRiPre(Register(reg, type), Register(reg2, type), Register(Assembler.SpRegister), -calleeSaveRegionSize); + } + else + { + asm.Sub(Register(Assembler.SpRegister), Register(Assembler.SpRegister), new Operand(OperandType.I64, (ulong)calleeSaveRegionSize)); + asm.StpRiUn(Register(reg, type), Register(reg2, type), Register(Assembler.SpRegister), 0); + } + + offset += type.GetSizeInBytes() * 2; + } + } + + public void WriteEpilogue(ref Assembler asm) + { + uint gprMask = _gprMask; + uint fpSimdMask = _fpSimdMask; + + int gprCalleeSavedRegsCount = BitOperations.PopCount(gprMask); + int fpSimdCalleeSavedRegsCount = BitOperations.PopCount(fpSimdMask); + + bool misalignedVector = _fpSimdType == OperandType.V128 && (gprCalleeSavedRegsCount & 1) != 0; + + int offset = gprCalleeSavedRegsCount * 8 + fpSimdCalleeSavedRegsCount * _fpSimdType.GetSizeInBytes(); + + if (misalignedVector) + { + offset += 8; + } + + int calleeSaveRegionSize = Align16(offset) + Align16(_reservedStackSize); + + if (_hasCall) + { + Operand rsp = Register(Assembler.SpRegister); + + if (offset != 0 || calleeSaveRegionSize + 16 < Encodable9BitsOffsetLimit) + { + asm.LdpRiPost(Register(FpRegister), Register(LrRegister), rsp, offset == 0 ? calleeSaveRegionSize + 16 : 16); + } + else + { + asm.LdpRiPost(Register(FpRegister), Register(LrRegister), rsp, 16); + asm.Add(rsp, rsp, new Operand(OperandKind.Constant, OperandType.I64, (ulong)calleeSaveRegionSize)); + } + } + + WriteEpilogueCalleeSavesPostIndexed(ref asm, ref fpSimdMask, ref offset, calleeSaveRegionSize, _fpSimdType); + + if (misalignedVector) + { + offset -= 8; + } + + WriteEpilogueCalleeSavesPostIndexed(ref asm, ref gprMask, ref offset, calleeSaveRegionSize, OperandType.I64); + } + + private static void WriteEpilogueCalleeSavesPostIndexed( + ref Assembler asm, + ref uint mask, + ref int offset, + int calleeSaveRegionSize, + OperandType type) + { + while (mask != 0) + { + int reg = HighestBitSet(mask); + + mask &= ~(1u << reg); + + if (mask != 0) + { + int reg2 = HighestBitSet(mask); + + mask &= ~(1u << reg2); + + offset -= type.GetSizeInBytes() * 2; + + if (offset != 0) + { + asm.LdpRiUn(Register(reg2, type), Register(reg, type), Register(Assembler.SpRegister), offset); + } + else if (calleeSaveRegionSize < Encodable9BitsOffsetLimit) + { + asm.LdpRiPost(Register(reg2, type), Register(reg, type), Register(Assembler.SpRegister), calleeSaveRegionSize); + } + else + { + asm.LdpRiUn(Register(reg2, type), Register(reg, type), Register(Assembler.SpRegister), 0); + asm.Add(Register(Assembler.SpRegister), Register(Assembler.SpRegister), new Operand(OperandType.I64, (ulong)calleeSaveRegionSize)); + } + } + else + { + offset -= type.GetSizeInBytes(); + + if (offset != 0) + { + asm.LdrRiUn(Register(reg, type), Register(Assembler.SpRegister), offset); + } + else if (calleeSaveRegionSize < Encodable9BitsOffsetLimit) + { + asm.LdrRiPost(Register(reg, type), Register(Assembler.SpRegister), calleeSaveRegionSize); + } + else + { + asm.LdrRiUn(Register(reg, type), Register(Assembler.SpRegister), 0); + asm.Add(Register(Assembler.SpRegister), Register(Assembler.SpRegister), new Operand(OperandType.I64, (ulong)calleeSaveRegionSize)); + } + } + } + } + + private static int HighestBitSet(uint value) + { + return 31 - BitOperations.LeadingZeroCount(value); + } + + private static Operand Register(int register, OperandType type = OperandType.I64) + { + return new Operand(register, RegisterType.Integer, type); + } + + private static int Align16(int value) + { + return (value + 0xf) & ~0xf; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/StackWalker.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/StackWalker.cs new file mode 100644 index 000000000..3b01e674b --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/StackWalker.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64 +{ + class StackWalker : IStackWalker + { + public IEnumerable GetCallStack(IntPtr framePointer, IntPtr codeRegionStart, int codeRegionSize, IntPtr codeRegion2Start, int codeRegion2Size) + { + List functionPointers = new(); + + while (true) + { + IntPtr functionPointer = Marshal.ReadIntPtr(framePointer, IntPtr.Size); + + if ((functionPointer < codeRegionStart || functionPointer >= codeRegionStart + codeRegionSize) && + (functionPointer < codeRegion2Start || functionPointer >= codeRegion2Start + codeRegion2Size)) + { + break; + } + + functionPointers.Add((ulong)functionPointer - 4); + framePointer = Marshal.ReadIntPtr(framePointer); + } + + return functionPointers; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/TailMerger.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/TailMerger.cs new file mode 100644 index 000000000..e042af126 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/TailMerger.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; + +namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64 +{ + class TailMerger + { + private enum BranchType + { + Conditional, + Unconditional, + } + + private readonly List<(BranchType, int)> _branchPointers; + + public TailMerger() + { + _branchPointers = new(); + } + + public void AddConditionalReturn(CodeWriter writer, in Assembler asm, ArmCondition returnCondition) + { + _branchPointers.Add((BranchType.Conditional, writer.InstructionPointer)); + asm.B(returnCondition, 0); + } + + public void AddConditionalZeroReturn(CodeWriter writer, in Assembler asm, Operand value) + { + _branchPointers.Add((BranchType.Conditional, writer.InstructionPointer)); + asm.Cbz(value, 0); + } + + public void AddUnconditionalReturn(CodeWriter writer, in Assembler asm) + { + _branchPointers.Add((BranchType.Unconditional, writer.InstructionPointer)); + asm.B(0); + } + + public void WriteReturn(CodeWriter writer, Action writeEpilogue) + { + if (_branchPointers.Count == 0) + { + return; + } + + int targetIndex = writer.InstructionPointer; + int startIndex = _branchPointers.Count - 1; + + if (startIndex >= 0 && + _branchPointers[startIndex].Item1 == BranchType.Unconditional && + _branchPointers[startIndex].Item2 == targetIndex - 1) + { + // Remove the last branch if it is redundant. + writer.RemoveLastInstruction(); + startIndex--; + targetIndex--; + } + + Assembler asm = new(writer); + + writeEpilogue(); + asm.Ret(); + + for (int i = startIndex; i >= 0; i--) + { + (BranchType type, int branchIndex) = _branchPointers[i]; + + uint encoding = writer.ReadInstructionAt(branchIndex); + int delta = targetIndex - branchIndex; + + if (type == BranchType.Conditional) + { + uint branchMask = 0x7ffff; + int branchMax = (int)(branchMask + 1) / 2; + + if (delta >= -branchMax && delta < branchMax) + { + writer.WriteInstructionAt(branchIndex, (encoding & ~(branchMask << 5)) | (uint)((delta & branchMask) << 5)); + } + else + { + // If the branch target is too far away, we use a regular unconditional branch + // instruction instead which has a much higher range. + // We branch directly to the end of the function, where we put the conditional branch, + // and then branch back to the next instruction or return the branch target depending + // on the branch being taken or not. + + delta = writer.InstructionPointer - branchIndex; + + uint branchInst = 0x14000000u | ((uint)delta & 0x3ffffff); + Debug.Assert(ExtractSImm26Times4(branchInst) == delta * 4); + + writer.WriteInstructionAt(branchIndex, branchInst); + + int movedBranchIndex = writer.InstructionPointer; + + writer.WriteInstruction(0u); // Placeholder + asm.B((branchIndex + 1 - writer.InstructionPointer) * 4); + + delta = targetIndex - movedBranchIndex; + + writer.WriteInstructionAt(movedBranchIndex, (encoding & ~(branchMask << 5)) | (uint)((delta & branchMask) << 5)); + } + } + else + { + Debug.Assert(type == BranchType.Unconditional); + + writer.WriteInstructionAt(branchIndex, (encoding & ~0x3ffffffu) | (uint)(delta & 0x3ffffff)); + } + } + } + + private static int ExtractSImm26Times4(uint encoding) + { + return (int)(encoding << 6) >> 4; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Operand.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Operand.cs new file mode 100644 index 000000000..8bf340304 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Operand.cs @@ -0,0 +1,38 @@ +using System.Diagnostics; + +namespace Ryujinx.Cpu.LightningJit.CodeGen +{ + readonly struct Operand + { + public readonly OperandKind Kind { get; } + public readonly OperandType Type { get; } + public readonly ulong Value { get; } + + public Operand(OperandKind kind, OperandType type, ulong value) + { + Kind = kind; + Type = type; + Value = value; + } + + public Operand(int index, RegisterType regType, OperandType type) : this(OperandKind.Register, type, (ulong)((int)regType << 24 | index)) + { + } + + public Operand(OperandType type, ulong value) : this(OperandKind.Constant, type, value) + { + } + + public readonly Register GetRegister() + { + Debug.Assert(Kind == OperandKind.Register); + + return new Register((int)Value & 0xffffff, (RegisterType)(Value >> 24)); + } + + public readonly int AsInt32() + { + return (int)Value; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/OperandKind.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/OperandKind.cs new file mode 100644 index 000000000..4f31763ba --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/OperandKind.cs @@ -0,0 +1,10 @@ +namespace Ryujinx.Cpu.LightningJit.CodeGen +{ + enum OperandKind + { + None, + Constant, + Label, + Register, + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/OperandType.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/OperandType.cs new file mode 100644 index 000000000..6191f791b --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/OperandType.cs @@ -0,0 +1,35 @@ +using System; + +namespace Ryujinx.Cpu.LightningJit.CodeGen +{ + enum OperandType + { + None, + I32, + I64, + FP32, + FP64, + V128, + } + + static class OperandTypeExtensions + { + public static bool IsInteger(this OperandType type) + { + return type == OperandType.I32 || type == OperandType.I64; + } + + public static int GetSizeInBytes(this OperandType type) + { + return type switch + { + OperandType.FP32 => 4, + OperandType.FP64 => 8, + OperandType.I32 => 4, + OperandType.I64 => 8, + OperandType.V128 => 16, + _ => throw new InvalidOperationException($"Invalid operand type \"{type}\"."), + }; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Register.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Register.cs new file mode 100644 index 000000000..8b96c9164 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Register.cs @@ -0,0 +1,42 @@ +using System; + +namespace Ryujinx.Cpu.LightningJit.CodeGen +{ + readonly struct Register : IEquatable + { + public int Index { get; } + + public RegisterType Type { get; } + + public Register(int index, RegisterType type) + { + Index = index; + Type = type; + } + + public override int GetHashCode() + { + return (ushort)Index | ((int)Type << 16); + } + + public static bool operator ==(Register x, Register y) + { + return x.Equals(y); + } + + public static bool operator !=(Register x, Register y) + { + return !x.Equals(y); + } + + public override bool Equals(object obj) + { + return obj is Register reg && Equals(reg); + } + + public bool Equals(Register other) + { + return other.Index == Index && other.Type == Type; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/RegisterType.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/RegisterType.cs new file mode 100644 index 000000000..c4a726bc9 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/RegisterType.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.Cpu.LightningJit.CodeGen +{ + enum RegisterType + { + Integer, + Vector, + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/CodeWriter.cs b/src/Ryujinx.Cpu/LightningJit/CodeWriter.cs new file mode 100644 index 000000000..ac4b22ff1 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/CodeWriter.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace Ryujinx.Cpu.LightningJit +{ + class CodeWriter + { + private readonly List _instructions; + + public int InstructionPointer => _instructions.Count; + + public CodeWriter() + { + _instructions = new(); + } + + public void WriteInstruction(uint instruction) + { + _instructions.Add(instruction); + } + + public void WriteInstructionAt(int index, uint instruction) + { + _instructions[index] = instruction; + } + + public void WriteInstructionsAt(int index, CodeWriter writer) + { + _instructions.InsertRange(index, writer._instructions); + } + + public uint ReadInstructionAt(int index) + { + return _instructions[index]; + } + + public List GetList() + { + return _instructions; + } + + public void RemoveLastInstruction() + { + if (_instructions.Count > 0) + { + _instructions.RemoveAt(_instructions.Count - 1); + } + } + + public ReadOnlySpan AsSpan() + { + return CollectionsMarshal.AsSpan(_instructions); + } + + public ReadOnlySpan AsByteSpan() + { + return MemoryMarshal.Cast(AsSpan()); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/CompiledFunction.cs b/src/Ryujinx.Cpu/LightningJit/CompiledFunction.cs new file mode 100644 index 000000000..ed375f220 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/CompiledFunction.cs @@ -0,0 +1,16 @@ +using System; + +namespace Ryujinx.Cpu.LightningJit +{ + readonly ref struct CompiledFunction + { + public readonly ReadOnlySpan Code; + public readonly int GuestCodeLength; + + public CompiledFunction(ReadOnlySpan code, int guestCodeLength) + { + Code = code; + GuestCodeLength = guestCodeLength; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/CpuPreset.cs b/src/Ryujinx.Cpu/LightningJit/CpuPreset.cs new file mode 100644 index 000000000..e5af69b3f --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/CpuPreset.cs @@ -0,0 +1,14 @@ +namespace Ryujinx.Cpu.LightningJit +{ + public readonly struct CpuPreset + { + public readonly IsaVersion Version; + public readonly IsaFeature Features; + + public CpuPreset(IsaVersion version, IsaFeature features) + { + Version = version; + Features = features; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/CpuPresets.cs b/src/Ryujinx.Cpu/LightningJit/CpuPresets.cs new file mode 100644 index 000000000..7798fbfc7 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/CpuPresets.cs @@ -0,0 +1,13 @@ +namespace Ryujinx.Cpu.LightningJit +{ + public static class CpuPresets + { + public static CpuPreset CortexA57 => new( + IsaVersion.v80, + IsaFeature.FeatAes | + IsaFeature.FeatCrc32 | + IsaFeature.FeatSha1 | + IsaFeature.FeatSha256 | + IsaFeature.FeatPmull); + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Graph/DataFlow.cs b/src/Ryujinx.Cpu/LightningJit/Graph/DataFlow.cs new file mode 100644 index 000000000..e5b369d66 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Graph/DataFlow.cs @@ -0,0 +1,171 @@ +namespace Ryujinx.Cpu.LightningJit.Graph +{ + static class DataFlow + { + public static (RegisterMask[], RegisterMask[]) GetGlobalUses(IBlockList blocks) + { + // Compute local register inputs and outputs used inside blocks. + RegisterMask[] localInputs = new RegisterMask[blocks.Count]; + RegisterMask[] localOutputs = new RegisterMask[blocks.Count]; + + for (int index = 0; index < blocks.Count; index++) + { + IBlock block = blocks[index]; + + RegisterUse use = block.ComputeUseMasks(); + + localInputs[block.Index] = use.Read; + localOutputs[block.Index] = use.Write; + } + + // Compute global register inputs and outputs used across blocks. + RegisterMask[] globalInputs = new RegisterMask[blocks.Count]; + RegisterMask[] globalOutputs = new RegisterMask[blocks.Count]; + + bool modified; + + // Compute register outputs. + do + { + modified = false; + + for (int index = 0; index < blocks.Count; index++) + { + IBlock block = blocks[index]; + + int firstPIndex = GetFirstPredecessorIndex(block); + if (firstPIndex >= 0) + { + IBlock predecessor = block.GetPredecessor(firstPIndex); + + RegisterMask outputs = globalOutputs[predecessor.Index]; + + for (int pIndex = firstPIndex + 1; pIndex < block.PredecessorsCount; pIndex++) + { + predecessor = block.GetPredecessor(pIndex); + + if (predecessor.EndsWithContextStore()) + { + // If a block ended with a context store, then we don't need to care + // about any of it's outputs, as they have already been saved to the context. + // Common outputs must be reset as doing a context stores indicates we will + // do a function call and wipe all register values. + + continue; + } + + outputs |= globalOutputs[predecessor.Index]; + } + + outputs |= localOutputs[block.Index]; + modified |= Exchange(globalOutputs, block.Index, globalOutputs[block.Index] | outputs); + } + else + { + modified |= Exchange(globalOutputs, block.Index, localOutputs[block.Index]); + } + } + } + while (modified); + + // Compute register inputs. + do + { + modified = false; + + for (int index = blocks.Count - 1; index >= 0; index--) + { + IBlock block = blocks[index]; + + RegisterMask cmnOutputs = RegisterMask.Zero; + RegisterMask allOutputs = RegisterMask.Zero; + + int firstPIndex = GetFirstPredecessorIndex(block); + if (firstPIndex == 0) + { + IBlock predecessor = block.GetPredecessor(0); + + // Assumes that block index 0 is the entry block. + cmnOutputs = block.Index != 0 ? globalOutputs[predecessor.Index] : RegisterMask.Zero; + allOutputs = globalOutputs[predecessor.Index]; + + for (int pIndex = 1; pIndex < block.PredecessorsCount; pIndex++) + { + predecessor = block.GetPredecessor(pIndex); + + if (!predecessor.EndsWithContextStore()) + { + RegisterMask outputs = globalOutputs[predecessor.Index]; + + cmnOutputs &= outputs; + allOutputs |= outputs; + } + else + { + cmnOutputs = RegisterMask.Zero; + } + } + } + else if (firstPIndex > 0) + { + IBlock predecessor = block.GetPredecessor(firstPIndex); + + allOutputs = globalOutputs[predecessor.Index]; + + for (int pIndex = firstPIndex + 1; pIndex < block.PredecessorsCount; pIndex++) + { + predecessor = block.GetPredecessor(pIndex); + + if (!predecessor.EndsWithContextStore()) + { + allOutputs |= globalOutputs[predecessor.Index]; + } + } + } + + RegisterMask inputs = localInputs[block.Index]; + + // If this block will load from context at the end, + // we don't need to care about what comes next. + if (!block.EndsWithContextLoad()) + { + for (int sIndex = 0; sIndex < block.SuccessorsCount; sIndex++) + { + inputs |= globalInputs[block.GetSuccessor(sIndex).Index] & ~localOutputs[block.Index]; + } + } + + inputs |= allOutputs & ~localOutputs[block.Index]; + inputs &= ~cmnOutputs; + + modified |= Exchange(globalInputs, block.Index, globalInputs[block.Index] | inputs); + } + } + while (modified); + + return (globalInputs, globalOutputs); + } + + private static bool Exchange(RegisterMask[] masks, int blkIndex, RegisterMask value) + { + ref RegisterMask curValue = ref masks[blkIndex]; + bool changed = curValue != value; + curValue = value; + + return changed; + } + + private static int GetFirstPredecessorIndex(IBlock block) + { + for (int pIndex = 0; pIndex < block.PredecessorsCount; pIndex++) + { + if (!block.GetPredecessor(pIndex).EndsWithContextStore()) + { + return pIndex; + } + } + + return -1; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Graph/IBlock.cs b/src/Ryujinx.Cpu/LightningJit/Graph/IBlock.cs new file mode 100644 index 000000000..2e5d71322 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Graph/IBlock.cs @@ -0,0 +1,17 @@ +namespace Ryujinx.Cpu.LightningJit.Graph +{ + interface IBlock + { + int Index { get; } + + int PredecessorsCount { get; } + int SuccessorsCount { get; } + + IBlock GetSuccessor(int index); + IBlock GetPredecessor(int index); + + RegisterUse ComputeUseMasks(); + bool EndsWithContextLoad(); + bool EndsWithContextStore(); + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Graph/IBlockList.cs b/src/Ryujinx.Cpu/LightningJit/Graph/IBlockList.cs new file mode 100644 index 000000000..aeec799cb --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Graph/IBlockList.cs @@ -0,0 +1,9 @@ +namespace Ryujinx.Cpu.LightningJit.Graph +{ + interface IBlockList + { + int Count { get; } + + IBlock this[int index] { get; } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Graph/RegisterMask.cs b/src/Ryujinx.Cpu/LightningJit/Graph/RegisterMask.cs new file mode 100644 index 000000000..cde324d5c --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Graph/RegisterMask.cs @@ -0,0 +1,60 @@ +using System; + +namespace Ryujinx.Cpu.LightningJit.Graph +{ + readonly struct RegisterMask : IEquatable + { + public readonly uint GprMask; + public readonly uint FpSimdMask; + public readonly uint PStateMask; + + public static RegisterMask Zero => new(0u, 0u, 0u); + + public RegisterMask(uint gprMask, uint fpSimdMask, uint pStateMask) + { + GprMask = gprMask; + FpSimdMask = fpSimdMask; + PStateMask = pStateMask; + } + + public static RegisterMask operator &(RegisterMask x, RegisterMask y) + { + return new(x.GprMask & y.GprMask, x.FpSimdMask & y.FpSimdMask, x.PStateMask & y.PStateMask); + } + + public static RegisterMask operator |(RegisterMask x, RegisterMask y) + { + return new(x.GprMask | y.GprMask, x.FpSimdMask | y.FpSimdMask, x.PStateMask | y.PStateMask); + } + + public static RegisterMask operator ~(RegisterMask x) + { + return new(~x.GprMask, ~x.FpSimdMask, ~x.PStateMask); + } + + public static bool operator ==(RegisterMask x, RegisterMask y) + { + return x.Equals(y); + } + + public static bool operator !=(RegisterMask x, RegisterMask y) + { + return !x.Equals(y); + } + + public override bool Equals(object obj) + { + return obj is RegisterMask regMask && Equals(regMask); + } + + public bool Equals(RegisterMask other) + { + return GprMask == other.GprMask && FpSimdMask == other.FpSimdMask && PStateMask == other.PStateMask; + } + + public override int GetHashCode() + { + return HashCode.Combine(GprMask, FpSimdMask, PStateMask); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Graph/RegisterUse.cs b/src/Ryujinx.Cpu/LightningJit/Graph/RegisterUse.cs new file mode 100644 index 000000000..83ef4192c --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Graph/RegisterUse.cs @@ -0,0 +1,24 @@ +namespace Ryujinx.Cpu.LightningJit.Graph +{ + readonly struct RegisterUse + { + public readonly RegisterMask Read; + public readonly RegisterMask Write; + + public RegisterUse(RegisterMask read, RegisterMask write) + { + Read = read; + Write = write; + } + + public RegisterUse( + uint gprReadMask, + uint gprWriteMask, + uint fpSimdReadMask, + uint fpSimdWriteMask, + uint pStateReadMask, + uint pStateWriteMask) : this(new(gprReadMask, fpSimdReadMask, pStateReadMask), new(gprWriteMask, fpSimdWriteMask, pStateWriteMask)) + { + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/IStackWalker.cs b/src/Ryujinx.Cpu/LightningJit/IStackWalker.cs new file mode 100644 index 000000000..2fddef659 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/IStackWalker.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; + +namespace Ryujinx.Cpu.LightningJit +{ + interface IStackWalker + { + IEnumerable GetCallStack(IntPtr framePointer, IntPtr codeRegionStart, int codeRegionSize, IntPtr codeRegion2Start, int codeRegion2Size); + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/IsaFeature.cs b/src/Ryujinx.Cpu/LightningJit/IsaFeature.cs new file mode 100644 index 000000000..c1f799d28 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/IsaFeature.cs @@ -0,0 +1,65 @@ +using System; + +namespace Ryujinx.Cpu.LightningJit +{ + [Flags] + public enum IsaFeature : ulong + { + None = 0, + FeatAa32bf16 = 1UL << 0, + FeatAa32i8mm = 1UL << 1, + FeatAes = 1UL << 2, + FeatBf16 = 1UL << 3, + FeatBti = 1UL << 4, + FeatChk = 1UL << 5, + FeatClrbhb = 1UL << 6, + FeatCrc32 = 1UL << 7, + FeatCssc = 1UL << 8, + FeatD128 = 1UL << 9, + FeatDgh = 1UL << 10, + FeatDotprod = 1UL << 11, + FeatFcma = 1UL << 12, + FeatFhm = 1UL << 13, + FeatFlagm = 1UL << 14, + FeatFlagm2 = 1UL << 15, + FeatFp16 = 1UL << 16, + FeatFrintts = 1UL << 17, + FeatGcs = 1UL << 18, + FeatHbc = 1UL << 19, + FeatI8mm = 1UL << 20, + FeatJscvt = 1UL << 21, + FeatLor = 1UL << 22, + FeatLrcpc = 1UL << 23, + FeatLrcpc2 = 1UL << 24, + FeatLrcpc3 = 1UL << 25, + FeatLs64 = 1UL << 26, + FeatLs64Accdata = 1UL << 27, + FeatLs64V = 1UL << 28, + FeatLse = 1UL << 29, + FeatLse128 = 1UL << 30, + FeatMops = 1UL << 31, + FeatMte = 1UL << 32, + FeatMte2 = 1UL << 33, + FeatPan = 1UL << 34, + FeatPauth = 1UL << 35, + FeatPmull = 1UL << 36, + FeatRas = 1UL << 37, + FeatRdm = 1UL << 38, + FeatRprfm = 1UL << 39, + FeatSb = 1UL << 40, + FeatSha1 = 1UL << 41, + FeatSha256 = 1UL << 42, + FeatSha3 = 1UL << 43, + FeatSha512 = 1UL << 44, + FeatSm3 = 1UL << 45, + FeatSm4 = 1UL << 46, + FeatSpe = 1UL << 47, + FeatSysinstr128 = 1UL << 48, + FeatSysreg128 = 1UL << 49, + FeatThe = 1UL << 50, + FeatTme = 1UL << 51, + FeatTrf = 1UL << 52, + FeatWfxt = 1UL << 53, + FeatXs = 1UL << 54, + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/IsaVersion.cs b/src/Ryujinx.Cpu/LightningJit/IsaVersion.cs new file mode 100644 index 000000000..5923eede4 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/IsaVersion.cs @@ -0,0 +1,17 @@ +namespace Ryujinx.Cpu.LightningJit +{ + public enum IsaVersion + { + None, + v80, + v81, + v82, + v83, + v84, + v85, + v86, + v87, + v88, + v89, + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/LightningJitCpuContext.cs b/src/Ryujinx.Cpu/LightningJit/LightningJitCpuContext.cs new file mode 100644 index 000000000..b63636e39 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/LightningJitCpuContext.cs @@ -0,0 +1,58 @@ +using ARMeilleure.Memory; +using Ryujinx.Cpu.Jit; +using Ryujinx.Cpu.LightningJit.State; + +namespace Ryujinx.Cpu.LightningJit +{ + class LightningJitCpuContext : ICpuContext + { + private readonly ITickSource _tickSource; + private readonly Translator _translator; + + public LightningJitCpuContext(ITickSource tickSource, IMemoryManager memory, bool for64Bit) + { + _tickSource = tickSource; + _translator = new Translator(memory, for64Bit); + memory.UnmapEvent += UnmapHandler; + } + + private void UnmapHandler(ulong address, ulong size) + { + _translator.InvalidateJitCacheRegion(address, size); + } + + /// + public IExecutionContext CreateExecutionContext(ExceptionCallbacks exceptionCallbacks) + { + return new ExecutionContext(new JitMemoryAllocator(), _tickSource, exceptionCallbacks); + } + + /// + public void Execute(IExecutionContext context, ulong address) + { + _translator.Execute((ExecutionContext)context, address); + } + + /// + public void InvalidateCacheRegion(ulong address, ulong size) + { + _translator.InvalidateJitCacheRegion(address, size); + } + + /// + public IDiskCacheLoadState LoadDiskCache(string titleIdText, string displayVersion, bool enabled) + { + return new DummyDiskCacheLoadState(); + } + + /// + public void PrepareCodeRange(ulong address, ulong size) + { + } + + public void Dispose() + { + _translator.Dispose(); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/LightningJitEngine.cs b/src/Ryujinx.Cpu/LightningJit/LightningJitEngine.cs new file mode 100644 index 000000000..c97ddc7c7 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/LightningJitEngine.cs @@ -0,0 +1,20 @@ +using ARMeilleure.Memory; + +namespace Ryujinx.Cpu.LightningJit +{ + public class LightningJitEngine : ICpuEngine + { + private readonly ITickSource _tickSource; + + public LightningJitEngine(ITickSource tickSource) + { + _tickSource = tickSource; + } + + /// + public ICpuContext CreateCpuContext(IMemoryManager memoryManager, bool for64Bit) + { + return new LightningJitCpuContext(_tickSource, memoryManager, for64Bit); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/NativeContextOffsets.cs b/src/Ryujinx.Cpu/LightningJit/NativeContextOffsets.cs new file mode 100644 index 000000000..8a3a968d0 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/NativeContextOffsets.cs @@ -0,0 +1,17 @@ +using Ryujinx.Cpu.LightningJit.State; + +namespace Ryujinx.Cpu.LightningJit +{ + class NativeContextOffsets + { + public static int GprBaseOffset => NativeContext.GetXOffset(); + public static int FpSimdBaseOffset => NativeContext.GetVOffset(); + public static int FlagsBaseOffset => NativeContext.GetFlagsOffset(); + public static int FpFlagsBaseOffset => NativeContext.GetFpFlagsOffset(); + public static int TpidrEl0Offset => NativeContext.GetTpidrEl0Offset(); + public static int TpidrroEl0Offset => NativeContext.GetTpidrroEl0Offset(); + public static int RunningOffset => NativeContext.GetRunningOffset(); + public static int CounterOffset => NativeContext.GetCounterOffset(); + public static int DispatchAddressOffset => NativeContext.GetDispatchAddressOffset(); + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/NativeInterface.cs b/src/Ryujinx.Cpu/LightningJit/NativeInterface.cs new file mode 100644 index 000000000..da3ad9832 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/NativeInterface.cs @@ -0,0 +1,93 @@ +using ARMeilleure.Memory; +using Ryujinx.Cpu.LightningJit.State; +using System; + +namespace Ryujinx.Cpu.LightningJit +{ + static class NativeInterface + { + private const int DczSizeLog2 = 4; // Log2 size in words + private const int DczSizeInBytes = 4 << DczSizeLog2; + + private class ThreadContext + { + public ExecutionContext Context { get; } + public IMemoryManager Memory { get; } + public Translator Translator { get; } + + public ThreadContext(ExecutionContext context, IMemoryManager memory, Translator translator) + { + Context = context; + Memory = memory; + Translator = translator; + } + } + + [ThreadStatic] + private static ThreadContext Context; + + public static void RegisterThread(ExecutionContext context, IMemoryManager memory, Translator translator) + { + Context = new ThreadContext(context, memory, translator); + } + + public static void UnregisterThread() + { + Context = null; + } + + public static void Break(ulong address, int imm) + { + GetContext().OnBreak(address, imm); + } + + public static void SupervisorCall(ulong address, int imm) + { + GetContext().OnSupervisorCall(address, imm); + } + + public static void Undefined(ulong address, int opCode) + { + GetContext().OnUndefined(address, opCode); + } + + public static ulong GetCntfrqEl0() + { + return GetContext().CntfrqEl0; + } + + public static ulong GetCntpctEl0() + { + return GetContext().CntpctEl0; + } + + public static ulong GetFunctionAddress(IntPtr framePointer, ulong address) + { + return (ulong)Context.Translator.GetOrTranslatePointer(framePointer, address, GetContext().ExecutionMode); + } + + public static void InvalidateCacheLine(ulong address) + { + Context.Translator.InvalidateJitCacheRegion(address, DczSizeInBytes); + } + + public static bool CheckSynchronization() + { + ExecutionContext context = GetContext(); + + context.CheckInterrupt(); + + return context.Running; + } + + public static ExecutionContext GetContext() + { + return Context.Context; + } + + public static IMemoryManager GetMemoryManager() + { + return Context.Memory; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/State/ExecutionContext.cs b/src/Ryujinx.Cpu/LightningJit/State/ExecutionContext.cs new file mode 100644 index 000000000..facb9142f --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/State/ExecutionContext.cs @@ -0,0 +1,153 @@ +using ARMeilleure.Memory; +using ARMeilleure.State; +using System; + +namespace Ryujinx.Cpu.LightningJit.State +{ + public class ExecutionContext : IExecutionContext + { + private const int MinCountForCheck = 4000; + + private readonly NativeContext _nativeContext; + + internal IntPtr NativeContextPtr => _nativeContext.BasePtr; + + private bool _interrupted; + private readonly ICounter _counter; + + public ulong Pc => _nativeContext.GetPc(); + + public ulong CntfrqEl0 => _counter.Frequency; + public ulong CntpctEl0 => _counter.Counter; + + public long TpidrEl0 + { + get => _nativeContext.GetTpidrEl0(); + set => _nativeContext.SetTpidrEl0(value); + } + + public long TpidrroEl0 + { + get => _nativeContext.GetTpidrroEl0(); + set => _nativeContext.SetTpidrroEl0(value); + } + + public uint Pstate + { + get => _nativeContext.GetPstate(); + set => _nativeContext.SetPstate(value); + } + + public uint Fpsr + { + get => _nativeContext.GetFPState((uint)FPSR.Mask); + set => _nativeContext.SetFPState(value, (uint)FPSR.Mask); + } + + public uint Fpcr + { + get => _nativeContext.GetFPState((uint)FPCR.Mask); + set => _nativeContext.SetFPState(value, (uint)FPCR.Mask); + } + + public bool IsAarch32 { get; set; } + + internal ExecutionMode ExecutionMode + { + get + { + if (IsAarch32) + { + return (Pstate & (1u << 5)) != 0 + ? ExecutionMode.Aarch32Thumb + : ExecutionMode.Aarch32Arm; + } + else + { + return ExecutionMode.Aarch64; + } + } + } + + public bool Running + { + get => _nativeContext.GetRunning(); + private set => _nativeContext.SetRunning(value); + } + + private readonly ExceptionCallbackNoArgs _interruptCallback; + private readonly ExceptionCallback _breakCallback; + private readonly ExceptionCallback _supervisorCallback; + private readonly ExceptionCallback _undefinedCallback; + + public ExecutionContext(IJitMemoryAllocator allocator, ICounter counter, ExceptionCallbacks exceptionCallbacks) + { + _nativeContext = new NativeContext(allocator); + _counter = counter; + _interruptCallback = exceptionCallbacks.InterruptCallback; + _breakCallback = exceptionCallbacks.BreakCallback; + _supervisorCallback = exceptionCallbacks.SupervisorCallback; + _undefinedCallback = exceptionCallbacks.UndefinedCallback; + + Running = true; + + _nativeContext.SetCounter(MinCountForCheck); + } + + public ulong GetX(int index) => _nativeContext.GetX(index); + public void SetX(int index, ulong value) => _nativeContext.SetX(index, value); + + public V128 GetV(int index) => _nativeContext.GetV(index); + public void SetV(int index, V128 value) => _nativeContext.SetV(index, value); + + internal void CheckInterrupt() + { + if (_interrupted) + { + _interrupted = false; + + _interruptCallback?.Invoke(this); + } + + _nativeContext.SetCounter(MinCountForCheck); + } + + public void RequestInterrupt() + { + _interrupted = true; + } + + internal void OnBreak(ulong address, int imm) + { + _breakCallback?.Invoke(this, address, imm); + } + + internal void OnSupervisorCall(ulong address, int imm) + { + _supervisorCallback?.Invoke(this, address, imm); + } + + internal void OnUndefined(ulong address, int opCode) + { + _undefinedCallback?.Invoke(this, address, opCode); + } + + public void StopRunning() + { + Running = false; + + _nativeContext.SetCounter(0); + } + + protected virtual void Dispose(bool disposing) + { + _nativeContext.Dispose(); + } + + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/State/ExecutionMode.cs b/src/Ryujinx.Cpu/LightningJit/State/ExecutionMode.cs new file mode 100644 index 000000000..0602bc9af --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/State/ExecutionMode.cs @@ -0,0 +1,9 @@ +namespace Ryujinx.Cpu.LightningJit.State +{ + enum ExecutionMode + { + Aarch32Arm = 0, + Aarch32Thumb = 1, + Aarch64 = 2, + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/State/NativeContext.cs b/src/Ryujinx.Cpu/LightningJit/State/NativeContext.cs new file mode 100644 index 000000000..fdb8793de --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/State/NativeContext.cs @@ -0,0 +1,173 @@ +using ARMeilleure.Memory; +using ARMeilleure.State; +using System; +using System.Runtime.CompilerServices; + +namespace Ryujinx.Cpu.LightningJit.State +{ + class NativeContext : IDisposable + { + private unsafe struct NativeCtxStorage + { + public fixed ulong X[32]; + public fixed ulong V[64]; + public uint Flags; + public uint FpFlags; + public long TpidrEl0; + public long TpidrroEl0; + public int Counter; + public uint HostFpFlags; + public ulong DispatchAddress; + public int Running; + } + + private static NativeCtxStorage _dummyStorage = new(); + + private readonly IJitMemoryBlock _block; + + public IntPtr BasePtr => _block.Pointer; + + public NativeContext(IJitMemoryAllocator allocator) + { + _block = allocator.Allocate((ulong)Unsafe.SizeOf()); + } + + public ulong GetPc() + { + // TODO: More precise tracking of PC value. + return GetStorage().DispatchAddress; + } + + public unsafe ulong GetX(int index) + { + if ((uint)index >= 32) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + return GetStorage().X[index]; + } + + public unsafe void SetX(int index, ulong value) + { + if ((uint)index >= 32) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + GetStorage().X[index] = value; + } + + public unsafe V128 GetV(int index) + { + if ((uint)index >= 32) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + return new V128(GetStorage().V[index * 2 + 0], GetStorage().V[index * 2 + 1]); + } + + public unsafe void SetV(int index, V128 value) + { + if ((uint)index >= 32) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + GetStorage().V[index * 2 + 0] = value.Extract(0); + GetStorage().V[index * 2 + 1] = value.Extract(1); + } + + public unsafe uint GetPstate() + { + return GetStorage().Flags; + } + + public unsafe void SetPstate(uint value) + { + GetStorage().Flags = value; + } + + public unsafe uint GetFPState(uint mask = uint.MaxValue) + { + return GetStorage().FpFlags & mask; + } + + public unsafe void SetFPState(uint value, uint mask = uint.MaxValue) + { + GetStorage().FpFlags = (value & mask) | (GetStorage().FpFlags & ~mask); + } + + public long GetTpidrEl0() => GetStorage().TpidrEl0; + public void SetTpidrEl0(long value) => GetStorage().TpidrEl0 = value; + + public long GetTpidrroEl0() => GetStorage().TpidrroEl0; + public void SetTpidrroEl0(long value) => GetStorage().TpidrroEl0 = value; + + public int GetCounter() => GetStorage().Counter; + public void SetCounter(int value) => GetStorage().Counter = value; + + public bool GetRunning() => GetStorage().Running != 0; + public void SetRunning(bool value) => GetStorage().Running = value ? 1 : 0; + + public unsafe static int GetXOffset() + { + return StorageOffset(ref _dummyStorage, ref _dummyStorage.X[0]); + } + + public unsafe static int GetVOffset() + { + return StorageOffset(ref _dummyStorage, ref _dummyStorage.V[0]); + } + + public static int GetFlagsOffset() + { + return StorageOffset(ref _dummyStorage, ref _dummyStorage.Flags); + } + + public static int GetFpFlagsOffset() + { + return StorageOffset(ref _dummyStorage, ref _dummyStorage.FpFlags); + } + + public static int GetTpidrEl0Offset() + { + return StorageOffset(ref _dummyStorage, ref _dummyStorage.TpidrEl0); + } + + public static int GetTpidrroEl0Offset() + { + return StorageOffset(ref _dummyStorage, ref _dummyStorage.TpidrroEl0); + } + + public static int GetCounterOffset() + { + return StorageOffset(ref _dummyStorage, ref _dummyStorage.Counter); + } + + public static int GetHostFpFlagsOffset() + { + return StorageOffset(ref _dummyStorage, ref _dummyStorage.HostFpFlags); + } + + public static int GetDispatchAddressOffset() + { + return StorageOffset(ref _dummyStorage, ref _dummyStorage.DispatchAddress); + } + + public static int GetRunningOffset() + { + return StorageOffset(ref _dummyStorage, ref _dummyStorage.Running); + } + + private static int StorageOffset(ref NativeCtxStorage storage, ref T target) + { + return (int)Unsafe.ByteOffset(ref Unsafe.As(ref storage), ref target); + } + + private unsafe ref NativeCtxStorage GetStorage() => ref Unsafe.AsRef((void*)_block.Pointer); + + public void Dispose() => _block.Dispose(); + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Table/IInstInfo.cs b/src/Ryujinx.Cpu/LightningJit/Table/IInstInfo.cs new file mode 100644 index 000000000..a51fe37b2 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Table/IInstInfo.cs @@ -0,0 +1,12 @@ +namespace Ryujinx.Cpu.LightningJit.Table +{ + interface IInstInfo + { + public uint Encoding { get; } + public uint EncodingMask { get; } + public IsaVersion Version { get; } + public IsaFeature Feature { get; } + + bool IsConstrained(uint encoding); + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Table/InstEncoding.cs b/src/Ryujinx.Cpu/LightningJit/Table/InstEncoding.cs new file mode 100644 index 000000000..32250b03f --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Table/InstEncoding.cs @@ -0,0 +1,14 @@ +namespace Ryujinx.Cpu.LightningJit.Table +{ + readonly struct InstEncoding + { + public readonly uint Encoding; + public readonly uint EncodingMask; + + public InstEncoding(uint encoding, uint encodingMask) + { + Encoding = encoding; + EncodingMask = encodingMask; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Table/InstTableLevel.cs b/src/Ryujinx.Cpu/LightningJit/Table/InstTableLevel.cs new file mode 100644 index 000000000..6567efeef --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Table/InstTableLevel.cs @@ -0,0 +1,96 @@ +using System.Collections.Generic; +using System.Numerics; + +namespace Ryujinx.Cpu.LightningJit.Table +{ + class InstTableLevel where T : IInstInfo + { + private readonly int _shift; + private readonly uint _mask; + private readonly InstTableLevel[] _childs; + private readonly List _insts; + + private InstTableLevel(List insts, uint baseMask) + { + uint commonEncodingMask = baseMask; + + foreach (T info in insts) + { + commonEncodingMask &= info.EncodingMask; + } + + if (commonEncodingMask != 0) + { + _shift = BitOperations.TrailingZeroCount(commonEncodingMask); + int bits = BitOperations.TrailingZeroCount(~(commonEncodingMask >> _shift)); + int count = 1 << bits; + _mask = uint.MaxValue >> (32 - bits); + + _childs = new InstTableLevel[count]; + + List[] splitList = new List[count]; + + for (int index = 0; index < insts.Count; index++) + { + int splitIndex = (int)((insts[index].Encoding >> _shift) & _mask); + + (splitList[splitIndex] ??= new()).Add(insts[index]); + } + + for (int index = 0; index < count; index++) + { + if (splitList[index] == null) + { + continue; + } + + _childs[index] = new InstTableLevel(splitList[index], baseMask & ~commonEncodingMask); + } + } + else + { + _insts = insts; + } + } + + public InstTableLevel(List insts) : this(insts, uint.MaxValue) + { + } + + public bool TryFind(uint encoding, IsaVersion version, IsaFeature features, out T value) + { + if (_childs != null) + { + int index = (int)((encoding >> _shift) & _mask); + + if (_childs[index] == null) + { + value = default; + + return false; + } + + return _childs[index].TryFind(encoding, version, features, out value); + } + else + { + foreach (T info in _insts) + { + if ((encoding & info.EncodingMask) == info.Encoding && + !info.IsConstrained(encoding) && + info.Version <= version && + (info.Feature & features) == info.Feature) + { + value = info; + + return true; + } + } + + value = default; + + return false; + } + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/TranslatedFunction.cs b/src/Ryujinx.Cpu/LightningJit/TranslatedFunction.cs new file mode 100644 index 000000000..a4e2c7b93 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/TranslatedFunction.cs @@ -0,0 +1,16 @@ +using System; + +namespace Ryujinx.Cpu.LightningJit +{ + class TranslatedFunction + { + public IntPtr FuncPointer { get; } + public ulong GuestSize { get; } + + public TranslatedFunction(IntPtr funcPointer, ulong guestSize) + { + FuncPointer = funcPointer; + GuestSize = guestSize; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/Translator.cs b/src/Ryujinx.Cpu/LightningJit/Translator.cs new file mode 100644 index 000000000..c883c1d60 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Translator.cs @@ -0,0 +1,227 @@ +using ARMeilleure.Common; +using ARMeilleure.Memory; +using Ryujinx.Cpu.Jit; +using Ryujinx.Cpu.LightningJit.Cache; +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; +using Ryujinx.Cpu.LightningJit.State; +using Ryujinx.Cpu.Signal; +using Ryujinx.Memory; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading; + +namespace Ryujinx.Cpu.LightningJit +{ + class Translator : IDisposable + { + // Should be enabled on platforms that enforce W^X. + private static bool IsNoWxPlatform => false; + + private static readonly AddressTable.Level[] _levels64Bit = + new AddressTable.Level[] + { + new(31, 17), + new(23, 8), + new(15, 8), + new( 7, 8), + new( 2, 5), + }; + + private static readonly AddressTable.Level[] _levels32Bit = + new AddressTable.Level[] + { + new(23, 9), + new(15, 8), + new( 7, 8), + new( 1, 6), + }; + + private readonly ConcurrentQueue> _oldFuncs; + private readonly NoWxCache _noWxCache; + private bool _disposed; + + internal TranslatorCache Functions { get; } + internal AddressTable FunctionTable { get; } + internal TranslatorStubs Stubs { get; } + internal IMemoryManager Memory { get; } + + public Translator(IMemoryManager memory, bool for64Bits) + { + Memory = memory; + + _oldFuncs = new ConcurrentQueue>(); + + if (IsNoWxPlatform) + { + _noWxCache = new(new JitMemoryAllocator(), CreateStackWalker(), this); + } + else + { + JitCache.Initialize(new JitMemoryAllocator(forJit: true)); + } + + Functions = new TranslatorCache(); + FunctionTable = new AddressTable(for64Bits ? _levels64Bit : _levels32Bit); + Stubs = new TranslatorStubs(FunctionTable, _noWxCache); + + FunctionTable.Fill = (ulong)Stubs.SlowDispatchStub; + + if (memory.Type.IsHostMapped()) + { + NativeSignalHandler.InitializeSignalHandler(MemoryBlock.GetPageSize()); + } + } + + private static IStackWalker CreateStackWalker() + { + if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64) + { + return new StackWalker(); + } + else + { + throw new PlatformNotSupportedException(); + } + } + + public void Execute(State.ExecutionContext context, ulong address) + { + ObjectDisposedException.ThrowIf(_disposed, this); + + NativeInterface.RegisterThread(context, Memory, this); + + Stubs.DispatchLoop(context.NativeContextPtr, address); + + NativeInterface.UnregisterThread(); + _noWxCache?.ClearEntireThreadLocalCache(); + } + + internal IntPtr GetOrTranslatePointer(IntPtr framePointer, ulong address, ExecutionMode mode) + { + if (_noWxCache != null) + { + CompiledFunction func = Compile(address, mode); + + return _noWxCache.Map(framePointer, func.Code, address, (ulong)func.GuestCodeLength); + } + + return GetOrTranslate(address, mode).FuncPointer; + } + + private TranslatedFunction GetOrTranslate(ulong address, ExecutionMode mode) + { + if (!Functions.TryGetValue(address, out TranslatedFunction func)) + { + func = Translate(address, mode); + + TranslatedFunction oldFunc = Functions.GetOrAdd(address, func.GuestSize, func); + + if (oldFunc != func) + { + JitCache.Unmap(func.FuncPointer); + func = oldFunc; + } + + RegisterFunction(address, func); + } + + return func; + } + + internal void RegisterFunction(ulong guestAddress, TranslatedFunction func) + { + if (FunctionTable.IsValid(guestAddress)) + { + Volatile.Write(ref FunctionTable.GetValue(guestAddress), (ulong)func.FuncPointer); + } + } + + private TranslatedFunction Translate(ulong address, ExecutionMode mode) + { + CompiledFunction func = Compile(address, mode); + IntPtr funcPointer = JitCache.Map(func.Code); + + return new TranslatedFunction(funcPointer, (ulong)func.GuestCodeLength); + } + + private CompiledFunction Compile(ulong address, ExecutionMode mode) + { + return AarchCompiler.Compile(CpuPresets.CortexA57, Memory, address, FunctionTable, Stubs.DispatchStub, mode, RuntimeInformation.ProcessArchitecture); + } + + public void InvalidateJitCacheRegion(ulong address, ulong size) + { + ulong[] overlapAddresses = Array.Empty(); + + int overlapsCount = Functions.GetOverlaps(address, size, ref overlapAddresses); + + for (int index = 0; index < overlapsCount; index++) + { + ulong overlapAddress = overlapAddresses[index]; + + if (Functions.TryGetValue(overlapAddress, out TranslatedFunction overlap)) + { + Functions.Remove(overlapAddress); + Volatile.Write(ref FunctionTable.GetValue(overlapAddress), FunctionTable.Fill); + EnqueueForDeletion(overlapAddress, overlap); + } + } + + // TODO: Remove overlapping functions from the JitCache aswell. + // This should be done safely, with a mechanism to ensure the function is not being executed. + } + + private void EnqueueForDeletion(ulong guestAddress, TranslatedFunction func) + { + _oldFuncs.Enqueue(new(guestAddress, func)); + } + + private void ClearJitCache() + { + List functions = Functions.AsList(); + + foreach (var func in functions) + { + JitCache.Unmap(func.FuncPointer); + } + + Functions.Clear(); + + while (_oldFuncs.TryDequeue(out var kv)) + { + JitCache.Unmap(kv.Value.FuncPointer); + } + } + + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + if (_noWxCache != null) + { + _noWxCache.Dispose(); + } + else + { + ClearJitCache(); + } + + Stubs.Dispose(); + FunctionTable.Dispose(); + } + + _disposed = true; + } + } + + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/TranslatorCache.cs b/src/Ryujinx.Cpu/LightningJit/TranslatorCache.cs new file mode 100644 index 000000000..60e13de9f --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/TranslatorCache.cs @@ -0,0 +1,96 @@ +using ARMeilleure.Translation; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Ryujinx.Cpu.LightningJit +{ + internal class TranslatorCache + { + private readonly IntervalTree _tree; + private readonly ReaderWriterLockSlim _treeLock; + + public int Count => _tree.Count; + + public TranslatorCache() + { + _tree = new IntervalTree(); + _treeLock = new ReaderWriterLockSlim(); + } + + public bool TryAdd(ulong address, ulong size, T value) + { + return AddOrUpdate(address, size, value, null); + } + + public bool AddOrUpdate(ulong address, ulong size, T value, Func updateFactoryCallback) + { + _treeLock.EnterWriteLock(); + bool result = _tree.AddOrUpdate(address, address + size, value, updateFactoryCallback); + _treeLock.ExitWriteLock(); + + return result; + } + + public T GetOrAdd(ulong address, ulong size, T value) + { + _treeLock.EnterWriteLock(); + value = _tree.GetOrAdd(address, address + size, value); + _treeLock.ExitWriteLock(); + + return value; + } + + public bool Remove(ulong address) + { + _treeLock.EnterWriteLock(); + bool removed = _tree.Remove(address) != 0; + _treeLock.ExitWriteLock(); + + return removed; + } + + public void Clear() + { + _treeLock.EnterWriteLock(); + _tree.Clear(); + _treeLock.ExitWriteLock(); + } + + public bool ContainsKey(ulong address) + { + _treeLock.EnterReadLock(); + bool result = _tree.ContainsKey(address); + _treeLock.ExitReadLock(); + + return result; + } + + public bool TryGetValue(ulong address, out T value) + { + _treeLock.EnterReadLock(); + bool result = _tree.TryGet(address, out value); + _treeLock.ExitReadLock(); + + return result; + } + + public int GetOverlaps(ulong address, ulong size, ref ulong[] overlaps) + { + _treeLock.EnterReadLock(); + int count = _tree.Get(address, address + size, ref overlaps); + _treeLock.ExitReadLock(); + + return count; + } + + public List AsList() + { + _treeLock.EnterReadLock(); + List list = _tree.AsList(); + _treeLock.ExitReadLock(); + + return list; + } + } +} diff --git a/src/Ryujinx.Cpu/LightningJit/TranslatorStubs.cs b/src/Ryujinx.Cpu/LightningJit/TranslatorStubs.cs new file mode 100644 index 000000000..914712bb1 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/TranslatorStubs.cs @@ -0,0 +1,380 @@ +using ARMeilleure.Common; +using Ryujinx.Cpu.LightningJit.Cache; +using Ryujinx.Cpu.LightningJit.CodeGen; +using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; +using Ryujinx.Cpu.LightningJit.State; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace Ryujinx.Cpu.LightningJit +{ + delegate void DispatcherFunction(IntPtr nativeContext, ulong startAddress); + + /// + /// Represents a stub manager. + /// + class TranslatorStubs : IDisposable + { + private delegate ulong GetFunctionAddressDelegate(IntPtr framePointer, ulong address); + + private readonly Lazy _slowDispatchStub; + + private bool _disposed; + + private readonly AddressTable _functionTable; + private readonly NoWxCache _noWxCache; + private readonly GetFunctionAddressDelegate _getFunctionAddressRef; + private readonly IntPtr _getFunctionAddress; + private readonly Lazy _dispatchStub; + private readonly Lazy _dispatchLoop; + + /// + /// Gets the dispatch stub. + /// + /// instance was disposed + public IntPtr DispatchStub + { + get + { + ObjectDisposedException.ThrowIf(_disposed, this); + + return _dispatchStub.Value; + } + } + + /// + /// Gets the slow dispatch stub. + /// + /// instance was disposed + public IntPtr SlowDispatchStub + { + get + { + ObjectDisposedException.ThrowIf(_disposed, this); + + return _slowDispatchStub.Value; + } + } + + /// + /// Gets the dispatch loop function. + /// + /// instance was disposed + public DispatcherFunction DispatchLoop + { + get + { + ObjectDisposedException.ThrowIf(_disposed, this); + + return _dispatchLoop.Value; + } + } + + /// + /// Initializes a new instance of the class with the specified + /// instance. + /// + /// Function table used to store pointers to the functions that the guest code will call + /// Cache used on platforms that enforce W^X, otherwise should be null + /// is null + public TranslatorStubs(AddressTable functionTable, NoWxCache noWxCache) + { + ArgumentNullException.ThrowIfNull(functionTable); + + _functionTable = functionTable; + _noWxCache = noWxCache; + _getFunctionAddressRef = NativeInterface.GetFunctionAddress; + _getFunctionAddress = Marshal.GetFunctionPointerForDelegate(_getFunctionAddressRef); + _slowDispatchStub = new(GenerateSlowDispatchStub, isThreadSafe: true); + _dispatchStub = new(GenerateDispatchStub, isThreadSafe: true); + _dispatchLoop = new(GenerateDispatchLoop, isThreadSafe: true); + } + + /// + /// Releases all resources used by the instance. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Releases all unmanaged and optionally managed resources used by the instance. + /// + /// to dispose managed resources also; otherwise just unmanaged resouces + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (_noWxCache == null) + { + if (_dispatchStub.IsValueCreated) + { + JitCache.Unmap(_dispatchStub.Value); + } + + if (_dispatchLoop.IsValueCreated) + { + JitCache.Unmap(Marshal.GetFunctionPointerForDelegate(_dispatchLoop.Value)); + } + } + + _disposed = true; + } + } + + /// + /// Frees resources used by the instance. + /// + ~TranslatorStubs() + { + Dispose(false); + } + + /// + /// Generates a . + /// + /// Generated + private IntPtr GenerateDispatchStub() + { + List branchToFallbackOffsets = new(); + + CodeWriter writer = new(); + + if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64) + { + Assembler asm = new(writer); + RegisterSaveRestore rsr = new((1u << 19) | (1u << 21) | (1u << 22), hasCall: true); + + rsr.WritePrologue(ref asm); + + Operand context = Register(19); + asm.Mov(context, Register(0)); + + // Load the target guest address from the native context. + Operand guestAddress = Register(16); + + asm.LdrRiUn(guestAddress, context, NativeContext.GetDispatchAddressOffset()); + + // Check if guest address is within range of the AddressTable. + asm.And(Register(17), guestAddress, Const(~_functionTable.Mask)); + + branchToFallbackOffsets.Add(writer.InstructionPointer); + + asm.Cbnz(Register(17), 0); + + Operand page = Register(17); + Operand index = Register(21); + Operand mask = Register(22); + + asm.Mov(page, (ulong)_functionTable.Base); + + for (int i = 0; i < _functionTable.Levels.Length; i++) + { + ref var level = ref _functionTable.Levels[i]; + + asm.Mov(mask, level.Mask >> level.Index); + asm.And(index, mask, guestAddress, ArmShiftType.Lsr, level.Index); + + if (i < _functionTable.Levels.Length - 1) + { + asm.LdrRr(page, page, index, ArmExtensionType.Uxtx, true); + + branchToFallbackOffsets.Add(writer.InstructionPointer); + + asm.Cbz(page, 0); + } + } + + asm.LdrRr(page, page, index, ArmExtensionType.Uxtx, true); + + rsr.WriteEpilogue(ref asm); + + asm.Br(page); + + foreach (int branchOffset in branchToFallbackOffsets) + { + uint branchInst = writer.ReadInstructionAt(branchOffset); + Debug.Assert(writer.InstructionPointer > branchOffset); + writer.WriteInstructionAt(branchOffset, branchInst | ((uint)(writer.InstructionPointer - branchOffset) << 5)); + } + + // Fallback. + asm.Mov(Register(0), Register(29)); + asm.Mov(Register(1), guestAddress); + asm.Mov(Register(16), (ulong)_getFunctionAddress); + asm.Blr(Register(16)); + asm.Mov(Register(16), Register(0)); + asm.Mov(Register(0), Register(19)); + + rsr.WriteEpilogue(ref asm); + + asm.Br(Register(16)); + } + else + { + throw new PlatformNotSupportedException(); + } + + return Map(writer.AsByteSpan()); + } + + /// + /// Generates a . + /// + /// Generated + private IntPtr GenerateSlowDispatchStub() + { + CodeWriter writer = new(); + + if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64) + { + Assembler asm = new(writer); + RegisterSaveRestore rsr = new(1u << 19, hasCall: true); + + rsr.WritePrologue(ref asm); + + Operand context = Register(19); + asm.Mov(context, Register(0)); + + // Load the target guest address from the native context. + asm.Mov(Register(0), Register(29)); + asm.LdrRiUn(Register(1), context, NativeContext.GetDispatchAddressOffset()); + asm.Mov(Register(16), (ulong)_getFunctionAddress); + asm.Blr(Register(16)); + asm.Mov(Register(16), Register(0)); + asm.Mov(Register(0), Register(19)); + + rsr.WriteEpilogue(ref asm); + + asm.Br(Register(16)); + } + else + { + throw new PlatformNotSupportedException(); + } + + return Map(writer.AsByteSpan()); + } + + /// + /// Emits code that syncs FP state before executing guest code, or returns it to normal. + /// + /// Assembler + /// Pointer to the native context + /// First temporary register + /// Second temporary register + /// True if entering guest code, false otherwise + private static void EmitSyncFpContext(ref Assembler asm, Operand context, Operand tempRegister, Operand tempRegister2, bool enter) + { + if (enter) + { + EmitSwapFpFlags(ref asm, context, tempRegister, tempRegister2, NativeContext.GetFpFlagsOffset(), NativeContext.GetHostFpFlagsOffset()); + } + else + { + EmitSwapFpFlags(ref asm, context, tempRegister, tempRegister2, NativeContext.GetHostFpFlagsOffset(), NativeContext.GetFpFlagsOffset()); + } + } + + /// + /// Swaps the FPCR and FPSR values with values stored in the native context. + /// + /// Assembler + /// Pointer to the native context + /// First temporary register + /// Second temporary register + /// Offset of the new flags that will be loaded + /// Offset where the current flags should be saved + private static void EmitSwapFpFlags(ref Assembler asm, Operand context, Operand tempRegister, Operand tempRegister2, int loadOffset, int storeOffset) + { + asm.MrsFpcr(tempRegister); + asm.MrsFpsr(tempRegister2); + asm.Orr(tempRegister, tempRegister, tempRegister2); + + asm.StrRiUn(tempRegister, context, storeOffset); + + asm.LdrRiUn(tempRegister, context, loadOffset); + asm.MsrFpcr(tempRegister); + asm.MsrFpsr(tempRegister2); + } + + /// + /// Generates a function. + /// + /// function + private DispatcherFunction GenerateDispatchLoop() + { + CodeWriter writer = new(); + + if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64) + { + Assembler asm = new(writer); + RegisterSaveRestore rsr = new(1u << 19, hasCall: true); + + rsr.WritePrologue(ref asm); + + Operand context = Register(19); + asm.Mov(context, Register(0)); + + EmitSyncFpContext(ref asm, context, Register(16, OperandType.I32), Register(17, OperandType.I32), true); + + // Load the target guest address from the native context. + Operand guestAddress = Register(16); + + asm.Mov(guestAddress, Register(1)); + + int loopStartIndex = writer.InstructionPointer; + + asm.StrRiUn(guestAddress, context, NativeContext.GetDispatchAddressOffset()); + asm.Mov(Register(0), context); + asm.Mov(Register(17), (ulong)DispatchStub); + asm.Blr(Register(17)); + asm.Mov(guestAddress, Register(0)); + asm.Cbz(guestAddress, 16); + asm.LdrRiUn(Register(17), context, NativeContext.GetRunningOffset()); + asm.Cbz(Register(17), 8); + asm.B((loopStartIndex - writer.InstructionPointer) * 4); + + EmitSyncFpContext(ref asm, context, Register(16, OperandType.I32), Register(17, OperandType.I32), false); + + rsr.WriteEpilogue(ref asm); + + asm.Ret(); + } + else + { + throw new PlatformNotSupportedException(); + } + + IntPtr pointer = Map(writer.AsByteSpan()); + + return Marshal.GetDelegateForFunctionPointer(pointer); + } + + private IntPtr Map(ReadOnlySpan code) + { + if (_noWxCache != null) + { + return _noWxCache.MapPageAligned(code); + } + else + { + return JitCache.Map(code); + } + } + + private static Operand Register(int register, OperandType type = OperandType.I64) + { + return new Operand(register, RegisterType.Integer, type); + } + + private static Operand Const(ulong value) + { + return new(OperandKind.Constant, OperandType.I64, value); + } + } +} diff --git a/src/Ryujinx.Cpu/MemoryEhMeilleure.cs b/src/Ryujinx.Cpu/MemoryEhMeilleure.cs index 9aa101aa9..f3a5b056b 100644 --- a/src/Ryujinx.Cpu/MemoryEhMeilleure.cs +++ b/src/Ryujinx.Cpu/MemoryEhMeilleure.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Signal; +using Ryujinx.Cpu.Signal; using Ryujinx.Memory; using Ryujinx.Memory.Tracking; using System; diff --git a/src/Ryujinx.Cpu/MemoryHelper.cs b/src/Ryujinx.Cpu/MemoryHelper.cs index ee14ee958..e3d08ad5a 100644 --- a/src/Ryujinx.Cpu/MemoryHelper.cs +++ b/src/Ryujinx.Cpu/MemoryHelper.cs @@ -1,4 +1,4 @@ -using Microsoft.IO; +using Microsoft.IO; using Ryujinx.Common.Memory; using Ryujinx.Memory; using System; diff --git a/src/Ryujinx.Cpu/MemoryManagerBase.cs b/src/Ryujinx.Cpu/MemoryManagerBase.cs index d2fc7a196..3288e3a49 100644 --- a/src/Ryujinx.Cpu/MemoryManagerBase.cs +++ b/src/Ryujinx.Cpu/MemoryManagerBase.cs @@ -1,4 +1,4 @@ -using Ryujinx.Memory; +using Ryujinx.Memory; using System.Diagnostics; using System.Threading; diff --git a/src/Ryujinx.Cpu/Signal/NativeSignalHandler.cs b/src/Ryujinx.Cpu/Signal/NativeSignalHandler.cs new file mode 100644 index 000000000..5a9d92cc4 --- /dev/null +++ b/src/Ryujinx.Cpu/Signal/NativeSignalHandler.cs @@ -0,0 +1,179 @@ +using ARMeilleure.Signal; +using Ryujinx.Common; +using Ryujinx.Memory; +using System; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Ryujinx.Cpu.Signal +{ + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct SignalHandlerRange + { + public int IsActive; + public nuint RangeAddress; + public nuint RangeEndAddress; + public IntPtr ActionPointer; + } + + [InlineArray(NativeSignalHandlerGenerator.MaxTrackedRanges)] + struct SignalHandlerRangeArray + { + public SignalHandlerRange Range0; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct SignalHandlerConfig + { + /// + /// The byte offset of the faulting address in the SigInfo or ExceptionRecord struct. + /// + public int StructAddressOffset; + + /// + /// The byte offset of the write flag in the SigInfo or ExceptionRecord struct. + /// + public int StructWriteOffset; + + /// + /// The sigaction handler that was registered before this one. (unix only) + /// + public nuint UnixOldSigaction; + + /// + /// The type of the previous sigaction. True for the 3 argument variant. (unix only) + /// + public int UnixOldSigaction3Arg; + + /// + /// Fixed size array of tracked ranges. + /// + public SignalHandlerRangeArray Ranges; + } + + static class NativeSignalHandler + { + private static readonly IntPtr _handlerConfig; + private static IntPtr _signalHandlerPtr; + + private static MemoryBlock _codeBlock; + + private static readonly object _lock = new(); + private static bool _initialized; + + static NativeSignalHandler() + { + _handlerConfig = Marshal.AllocHGlobal(Unsafe.SizeOf()); + ref SignalHandlerConfig config = ref GetConfigRef(); + + config = new SignalHandlerConfig(); + } + + public static void InitializeSignalHandler(ulong pageSize, Func customSignalHandlerFactory = null) + { + if (_initialized) + { + return; + } + + lock (_lock) + { + if (_initialized) + { + return; + } + + int rangeStructSize = Unsafe.SizeOf(); + + ref SignalHandlerConfig config = ref GetConfigRef(); + + if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) + { + _signalHandlerPtr = MapCode(NativeSignalHandlerGenerator.GenerateUnixSignalHandler(_handlerConfig, rangeStructSize, pageSize)); + + if (customSignalHandlerFactory != null) + { + _signalHandlerPtr = customSignalHandlerFactory(UnixSignalHandlerRegistration.GetSegfaultExceptionHandler().sa_handler, _signalHandlerPtr); + } + + var old = UnixSignalHandlerRegistration.RegisterExceptionHandler(_signalHandlerPtr); + + config.UnixOldSigaction = (nuint)(ulong)old.sa_handler; + config.UnixOldSigaction3Arg = old.sa_flags & 4; + } + else + { + config.StructAddressOffset = 40; // ExceptionInformation1 + config.StructWriteOffset = 32; // ExceptionInformation0 + + _signalHandlerPtr = MapCode(NativeSignalHandlerGenerator.GenerateWindowsSignalHandler(_handlerConfig, rangeStructSize, pageSize)); + + if (customSignalHandlerFactory != null) + { + _signalHandlerPtr = customSignalHandlerFactory(IntPtr.Zero, _signalHandlerPtr); + } + + WindowsSignalHandlerRegistration.RegisterExceptionHandler(_signalHandlerPtr); + } + + _initialized = true; + } + } + + private static IntPtr MapCode(ReadOnlySpan code) + { + Debug.Assert(_codeBlock == null); + + ulong codeSizeAligned = BitUtils.AlignUp((ulong)code.Length, MemoryBlock.GetPageSize()); + + _codeBlock = new MemoryBlock(codeSizeAligned); + _codeBlock.Write(0, code); + _codeBlock.Reprotect(0, codeSizeAligned, MemoryPermission.ReadAndExecute); + + return _codeBlock.Pointer; + } + + private static unsafe ref SignalHandlerConfig GetConfigRef() + { + return ref Unsafe.AsRef((void*)_handlerConfig); + } + + public static bool AddTrackedRegion(nuint address, nuint endAddress, IntPtr action) + { + Span ranges = GetConfigRef().Ranges; + + for (int i = 0; i < NativeSignalHandlerGenerator.MaxTrackedRanges; i++) + { + if (ranges[i].IsActive == 0) + { + ranges[i].RangeAddress = address; + ranges[i].RangeEndAddress = endAddress; + ranges[i].ActionPointer = action; + ranges[i].IsActive = 1; + + return true; + } + } + + return false; + } + + public static bool RemoveTrackedRegion(nuint address) + { + Span ranges = GetConfigRef().Ranges; + + for (int i = 0; i < NativeSignalHandlerGenerator.MaxTrackedRanges; i++) + { + if (ranges[i].IsActive == 1 && ranges[i].RangeAddress == address) + { + ranges[i].IsActive = 0; + + return true; + } + } + + return false; + } + } +} diff --git a/src/ARMeilleure/Signal/UnixSignalHandlerRegistration.cs b/src/Ryujinx.Cpu/Signal/UnixSignalHandlerRegistration.cs similarity index 98% rename from src/ARMeilleure/Signal/UnixSignalHandlerRegistration.cs rename to src/Ryujinx.Cpu/Signal/UnixSignalHandlerRegistration.cs index 79a8f803d..e88a6c0f6 100644 --- a/src/ARMeilleure/Signal/UnixSignalHandlerRegistration.cs +++ b/src/Ryujinx.Cpu/Signal/UnixSignalHandlerRegistration.cs @@ -1,7 +1,7 @@ -using System; +using System; using System.Runtime.InteropServices; -namespace ARMeilleure.Signal +namespace Ryujinx.Cpu.Signal { static partial class UnixSignalHandlerRegistration { diff --git a/src/Ryujinx.Cpu/Signal/WindowsSignalHandlerRegistration.cs b/src/Ryujinx.Cpu/Signal/WindowsSignalHandlerRegistration.cs new file mode 100644 index 000000000..1fbce0f72 --- /dev/null +++ b/src/Ryujinx.Cpu/Signal/WindowsSignalHandlerRegistration.cs @@ -0,0 +1,24 @@ +using System; +using System.Runtime.InteropServices; + +namespace Ryujinx.Cpu.Signal +{ + static partial class WindowsSignalHandlerRegistration + { + [LibraryImport("kernel32.dll")] + private static partial IntPtr AddVectoredExceptionHandler(uint first, IntPtr handler); + + [LibraryImport("kernel32.dll")] + private static partial ulong RemoveVectoredExceptionHandler(IntPtr handle); + + public static IntPtr RegisterExceptionHandler(IntPtr action) + { + return AddVectoredExceptionHandler(1, action); + } + + public static bool RemoveExceptionHandler(IntPtr handle) + { + return RemoveVectoredExceptionHandler(handle) != 0; + } + } +} diff --git a/src/Ryujinx.Graphics.Device/DeviceMemoryManager.cs b/src/Ryujinx.Graphics.Device/DeviceMemoryManager.cs new file mode 100644 index 000000000..d64ed3095 --- /dev/null +++ b/src/Ryujinx.Graphics.Device/DeviceMemoryManager.cs @@ -0,0 +1,395 @@ +using Ryujinx.Memory; +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Ryujinx.Graphics.Device +{ + /// + /// Device memory manager. + /// + public class DeviceMemoryManager : IWritableBlock + { + private const int PtLvl0Bits = 10; + private const int PtLvl1Bits = 10; + public const int PtPageBits = 12; + + private const ulong PtLvl0Size = 1UL << PtLvl0Bits; + private const ulong PtLvl1Size = 1UL << PtLvl1Bits; + public const ulong PageSize = 1UL << PtPageBits; + + private const ulong PtLvl0Mask = PtLvl0Size - 1; + private const ulong PtLvl1Mask = PtLvl1Size - 1; + public const ulong PageMask = PageSize - 1; + + private const int PtLvl0Bit = PtPageBits + PtLvl1Bits; + private const int PtLvl1Bit = PtPageBits; + private const int AddressSpaceBits = PtPageBits + PtLvl1Bits + PtLvl0Bits; + + public const ulong PteUnmapped = ulong.MaxValue; + + private readonly ulong[][] _pageTable; + + private readonly IVirtualMemoryManager _physical; + + /// + /// Creates a new instance of the GPU memory manager. + /// + /// Physical memory that this memory manager will map into + public DeviceMemoryManager(IVirtualMemoryManager physicalMemory) + { + _physical = physicalMemory; + _pageTable = new ulong[PtLvl0Size][]; + } + + /// + /// Reads data from GPU mapped memory. + /// + /// Type of the data + /// GPU virtual address where the data is located + /// The data at the specified memory location + public T Read(ulong va) where T : unmanaged + { + int size = Unsafe.SizeOf(); + + if (IsContiguous(va, size)) + { + return _physical.Read(Translate(va)); + } + else + { + Span data = new byte[size]; + + ReadImpl(va, data); + + return MemoryMarshal.Cast(data)[0]; + } + } + + /// + /// Gets a read-only span of data from GPU mapped memory. + /// + /// GPU virtual address where the data is located + /// Size of the data + /// The span of the data at the specified memory location + public ReadOnlySpan GetSpan(ulong va, int size) + { + if (IsContiguous(va, size)) + { + return _physical.GetSpan(Translate(va), size); + } + else + { + Span data = new byte[size]; + + ReadImpl(va, data); + + return data; + } + } + + /// + /// Reads data from a possibly non-contiguous region of GPU mapped memory. + /// + /// GPU virtual address of the data + /// Span to write the read data into + private void ReadImpl(ulong va, Span data) + { + if (data.Length == 0) + { + return; + } + + int offset = 0, size; + + if ((va & PageMask) != 0) + { + ulong pa = Translate(va); + + size = Math.Min(data.Length, (int)PageSize - (int)(va & PageMask)); + + if (pa != PteUnmapped && _physical.IsMapped(pa)) + { + _physical.GetSpan(pa, size).CopyTo(data[..size]); + } + + offset += size; + } + + for (; offset < data.Length; offset += size) + { + ulong pa = Translate(va + (ulong)offset); + + size = Math.Min(data.Length - offset, (int)PageSize); + + if (pa != PteUnmapped && _physical.IsMapped(pa)) + { + _physical.GetSpan(pa, size).CopyTo(data.Slice(offset, size)); + } + } + } + + /// + /// Gets a writable region from GPU mapped memory. + /// + /// Start address of the range + /// Size in bytes to be range + /// A writable region with the data at the specified memory location + public WritableRegion GetWritableRegion(ulong va, int size) + { + if (IsContiguous(va, size)) + { + return _physical.GetWritableRegion(Translate(va), size, tracked: true); + } + else + { + Memory memory = new byte[size]; + + GetSpan(va, size).CopyTo(memory.Span); + + return new WritableRegion(this, va, memory, tracked: true); + } + } + + /// + /// Writes data to GPU mapped memory. + /// + /// Type of the data + /// GPU virtual address to write the value into + /// The value to be written + public void Write(ulong va, T value) where T : unmanaged + { + Write(va, MemoryMarshal.Cast(MemoryMarshal.CreateSpan(ref value, 1))); + } + + /// + /// Writes data to GPU mapped memory. + /// + /// GPU virtual address to write the data into + /// The data to be written + public void Write(ulong va, ReadOnlySpan data) + { + if (IsContiguous(va, data.Length)) + { + _physical.Write(Translate(va), data); + } + else + { + int offset = 0, size; + + if ((va & PageMask) != 0) + { + ulong pa = Translate(va); + + size = Math.Min(data.Length, (int)PageSize - (int)(va & PageMask)); + + if (pa != PteUnmapped && _physical.IsMapped(pa)) + { + _physical.Write(pa, data[..size]); + } + + offset += size; + } + + for (; offset < data.Length; offset += size) + { + ulong pa = Translate(va + (ulong)offset); + + size = Math.Min(data.Length - offset, (int)PageSize); + + if (pa != PteUnmapped && _physical.IsMapped(pa)) + { + _physical.Write(pa, data.Slice(offset, size)); + } + } + } + } + + /// + /// Writes data to GPU mapped memory without write tracking. + /// + /// GPU virtual address to write the data into + /// The data to be written + public void WriteUntracked(ulong va, ReadOnlySpan data) + { + throw new NotSupportedException(); + } + + /// + /// Maps a given range of pages to the specified CPU virtual address. + /// + /// + /// All addresses and sizes must be page aligned. + /// + /// CPU virtual address to map into + /// GPU virtual address to be mapped + /// Kind of the resource located at the mapping + public void Map(ulong pa, ulong va, ulong size) + { + lock (_pageTable) + { + for (ulong offset = 0; offset < size; offset += PageSize) + { + SetPte(va + offset, PackPte(pa + offset)); + } + } + } + + /// + /// Unmaps a given range of pages at the specified GPU virtual memory region. + /// + /// GPU virtual address to unmap + /// Size in bytes of the region being unmapped + public void Unmap(ulong va, ulong size) + { + lock (_pageTable) + { + for (ulong offset = 0; offset < size; offset += PageSize) + { + SetPte(va + offset, PteUnmapped); + } + } + } + + /// + /// Checks if a region of GPU mapped memory is contiguous. + /// + /// GPU virtual address of the region + /// Size of the region + /// True if the region is contiguous, false otherwise + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private bool IsContiguous(ulong va, int size) + { + if (!ValidateAddress(va) || GetPte(va) == PteUnmapped) + { + return false; + } + + ulong endVa = (va + (ulong)size + PageMask) & ~PageMask; + + va &= ~PageMask; + + int pages = (int)((endVa - va) / PageSize); + + for (int page = 0; page < pages - 1; page++) + { + if (!ValidateAddress(va + PageSize) || GetPte(va + PageSize) == PteUnmapped) + { + return false; + } + + if (Translate(va) + PageSize != Translate(va + PageSize)) + { + return false; + } + + va += PageSize; + } + + return true; + } + + /// + /// Validates a GPU virtual address. + /// + /// Address to validate + /// True if the address is valid, false otherwise + private static bool ValidateAddress(ulong va) + { + return va < (1UL << AddressSpaceBits); + } + + /// + /// Checks if a given page is mapped. + /// + /// GPU virtual address of the page to check + /// True if the page is mapped, false otherwise + public bool IsMapped(ulong va) + { + return Translate(va) != PteUnmapped; + } + + /// + /// Translates a GPU virtual address to a CPU virtual address. + /// + /// GPU virtual address to be translated + /// CPU virtual address, or if unmapped + public ulong Translate(ulong va) + { + if (!ValidateAddress(va)) + { + return PteUnmapped; + } + + ulong pte = GetPte(va); + + if (pte == PteUnmapped) + { + return PteUnmapped; + } + + return UnpackPaFromPte(pte) + (va & PageMask); + } + + /// + /// Gets the Page Table entry for a given GPU virtual address. + /// + /// GPU virtual address + /// Page table entry (CPU virtual address) + private ulong GetPte(ulong va) + { + ulong l0 = (va >> PtLvl0Bit) & PtLvl0Mask; + ulong l1 = (va >> PtLvl1Bit) & PtLvl1Mask; + + if (_pageTable[l0] == null) + { + return PteUnmapped; + } + + return _pageTable[l0][l1]; + } + + /// + /// Sets a Page Table entry at a given GPU virtual address. + /// + /// GPU virtual address + /// Page table entry (CPU virtual address) + private void SetPte(ulong va, ulong pte) + { + ulong l0 = (va >> PtLvl0Bit) & PtLvl0Mask; + ulong l1 = (va >> PtLvl1Bit) & PtLvl1Mask; + + if (_pageTable[l0] == null) + { + _pageTable[l0] = new ulong[PtLvl1Size]; + + for (ulong index = 0; index < PtLvl1Size; index++) + { + _pageTable[l0][index] = PteUnmapped; + } + } + + _pageTable[l0][l1] = pte; + } + + /// + /// Creates a page table entry from a physical address and kind. + /// + /// Physical address + /// Page table entry + private static ulong PackPte(ulong pa) + { + return pa; + } + + /// + /// Unpacks physical address from a page table entry. + /// + /// Page table entry + /// Physical address + private static ulong UnpackPaFromPte(ulong pte) + { + return pte; + } + } +} diff --git a/src/Ryujinx.Graphics.Device/DeviceState.cs b/src/Ryujinx.Graphics.Device/DeviceState.cs index b07582a8a..de8582a3b 100644 --- a/src/Ryujinx.Graphics.Device/DeviceState.cs +++ b/src/Ryujinx.Graphics.Device/DeviceState.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Ryujinx.Graphics.Device/IDeviceState.cs b/src/Ryujinx.Graphics.Device/IDeviceState.cs index 077d69f20..dcd32cf07 100644 --- a/src/Ryujinx.Graphics.Device/IDeviceState.cs +++ b/src/Ryujinx.Graphics.Device/IDeviceState.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Device +namespace Ryujinx.Graphics.Device { public interface IDeviceState { diff --git a/src/Ryujinx.Graphics.Device/ISynchronizationManager.cs b/src/Ryujinx.Graphics.Device/ISynchronizationManager.cs new file mode 100644 index 000000000..2a8d1d9b7 --- /dev/null +++ b/src/Ryujinx.Graphics.Device/ISynchronizationManager.cs @@ -0,0 +1,39 @@ +using Ryujinx.Common.Logging; +using System; +using System.Threading; + +namespace Ryujinx.Graphics.Device +{ + /// + /// Synchronization manager interface. + /// + public interface ISynchronizationManager + { + /// + /// Increment the value of a syncpoint with a given id. + /// + /// The id of the syncpoint + /// Thrown when id >= MaxHardwareSyncpoints + /// The incremented value of the syncpoint + uint IncrementSyncpoint(uint id); + + /// + /// Get the value of a syncpoint with a given id. + /// + /// The id of the syncpoint + /// Thrown when id >= MaxHardwareSyncpoints + /// The value of the syncpoint + uint GetSyncpointValue(uint id); + + /// + /// Wait on a syncpoint with a given id at a target threshold. + /// The callback will be called once the threshold is reached and will automatically be unregistered. + /// + /// The id of the syncpoint + /// The target threshold + /// The timeout + /// Thrown when id >= MaxHardwareSyncpoints + /// True if timed out + bool WaitOnSyncpoint(uint id, uint threshold, TimeSpan timeout); + } +} diff --git a/src/Ryujinx.Graphics.Device/RwCallback.cs b/src/Ryujinx.Graphics.Device/RwCallback.cs index dc8499e9d..46428cdd1 100644 --- a/src/Ryujinx.Graphics.Device/RwCallback.cs +++ b/src/Ryujinx.Graphics.Device/RwCallback.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.Device { diff --git a/src/Ryujinx.Graphics.Device/Ryujinx.Graphics.Device.csproj b/src/Ryujinx.Graphics.Device/Ryujinx.Graphics.Device.csproj index ae2821edb..973a9e260 100644 --- a/src/Ryujinx.Graphics.Device/Ryujinx.Graphics.Device.csproj +++ b/src/Ryujinx.Graphics.Device/Ryujinx.Graphics.Device.csproj @@ -4,4 +4,8 @@ net8.0 + + + + diff --git a/src/Ryujinx.Graphics.Device/SizeCalculator.cs b/src/Ryujinx.Graphics.Device/SizeCalculator.cs index d5697fe5e..54820ec36 100644 --- a/src/Ryujinx.Graphics.Device/SizeCalculator.cs +++ b/src/Ryujinx.Graphics.Device/SizeCalculator.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Reflection; namespace Ryujinx.Graphics.Device diff --git a/src/Ryujinx.Graphics.GAL/AntiAliasing.cs b/src/Ryujinx.Graphics.GAL/AntiAliasing.cs index 9f526909b..04b529764 100644 --- a/src/Ryujinx.Graphics.GAL/AntiAliasing.cs +++ b/src/Ryujinx.Graphics.GAL/AntiAliasing.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL +namespace Ryujinx.Graphics.GAL { public enum AntiAliasing { diff --git a/src/Ryujinx.Graphics.GAL/BufferAccess.cs b/src/Ryujinx.Graphics.GAL/BufferAccess.cs index e7d7ceb0a..faefa5188 100644 --- a/src/Ryujinx.Graphics.GAL/BufferAccess.cs +++ b/src/Ryujinx.Graphics.GAL/BufferAccess.cs @@ -1,9 +1,13 @@ +using System; + namespace Ryujinx.Graphics.GAL { + [Flags] public enum BufferAccess { - Default, - FlushPersistent, - Stream + Default = 0, + FlushPersistent = 1 << 0, + Stream = 1 << 1, + SparseCompatible = 1 << 2, } } diff --git a/src/Ryujinx.Graphics.GAL/BufferAssignment.cs b/src/Ryujinx.Graphics.GAL/BufferAssignment.cs index d129135e2..e302936e9 100644 --- a/src/Ryujinx.Graphics.GAL/BufferAssignment.cs +++ b/src/Ryujinx.Graphics.GAL/BufferAssignment.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL +namespace Ryujinx.Graphics.GAL { public readonly struct BufferAssignment { diff --git a/src/Ryujinx.Graphics.GAL/BufferHandle.cs b/src/Ryujinx.Graphics.GAL/BufferHandle.cs index a2adea56a..7994e4eea 100644 --- a/src/Ryujinx.Graphics.GAL/BufferHandle.cs +++ b/src/Ryujinx.Graphics.GAL/BufferHandle.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.Graphics.GAL { diff --git a/src/Ryujinx.Graphics.GAL/Capabilities.cs b/src/Ryujinx.Graphics.GAL/Capabilities.cs index 961848d72..4d0186078 100644 --- a/src/Ryujinx.Graphics.GAL/Capabilities.cs +++ b/src/Ryujinx.Graphics.GAL/Capabilities.cs @@ -23,6 +23,7 @@ namespace Ryujinx.Graphics.GAL public readonly bool SupportsR4G4B4A4Format; public readonly bool SupportsScaledVertexFormats; public readonly bool SupportsSnormBufferTextureFormat; + public readonly bool SupportsSparseBuffer; public readonly bool Supports5BitComponentFormat; public readonly bool SupportsBlendEquationAdvanced; public readonly bool SupportsFragmentShaderInterlock; @@ -80,6 +81,7 @@ namespace Ryujinx.Graphics.GAL bool supportsScaledVertexFormats, bool supportsSnormBufferTextureFormat, bool supports5BitComponentFormat, + bool supportsSparseBuffer, bool supportsBlendEquationAdvanced, bool supportsFragmentShaderInterlock, bool supportsFragmentShaderOrderingIntel, @@ -132,6 +134,7 @@ namespace Ryujinx.Graphics.GAL SupportsScaledVertexFormats = supportsScaledVertexFormats; SupportsSnormBufferTextureFormat = supportsSnormBufferTextureFormat; Supports5BitComponentFormat = supports5BitComponentFormat; + SupportsSparseBuffer = supportsSparseBuffer; SupportsBlendEquationAdvanced = supportsBlendEquationAdvanced; SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock; SupportsFragmentShaderOrderingIntel = supportsFragmentShaderOrderingIntel; diff --git a/src/Ryujinx.Graphics.GAL/HardwareInfo.cs b/src/Ryujinx.Graphics.GAL/HardwareInfo.cs index 4dd6849bd..c2546fa46 100644 --- a/src/Ryujinx.Graphics.GAL/HardwareInfo.cs +++ b/src/Ryujinx.Graphics.GAL/HardwareInfo.cs @@ -1,14 +1,16 @@ -namespace Ryujinx.Graphics.GAL +namespace Ryujinx.Graphics.GAL { public readonly struct HardwareInfo { public string GpuVendor { get; } public string GpuModel { get; } + public string GpuDriver { get; } - public HardwareInfo(string gpuVendor, string gpuModel) + public HardwareInfo(string gpuVendor, string gpuModel, string gpuDriver) { GpuVendor = gpuVendor; GpuModel = gpuModel; + GpuDriver = gpuDriver; } } } diff --git a/src/Ryujinx.Graphics.GAL/ICounterEvent.cs b/src/Ryujinx.Graphics.GAL/ICounterEvent.cs index 13b15ae4b..a410506be 100644 --- a/src/Ryujinx.Graphics.GAL/ICounterEvent.cs +++ b/src/Ryujinx.Graphics.GAL/ICounterEvent.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.GAL { diff --git a/src/Ryujinx.Graphics.GAL/IRenderer.cs b/src/Ryujinx.Graphics.GAL/IRenderer.cs index 1dabbdaef..3bf56465e 100644 --- a/src/Ryujinx.Graphics.GAL/IRenderer.cs +++ b/src/Ryujinx.Graphics.GAL/IRenderer.cs @@ -16,13 +16,10 @@ namespace Ryujinx.Graphics.GAL void BackgroundContextAction(Action action, bool alwaysBackground = false); - BufferHandle CreateBuffer(int size, BufferHandle storageHint); - BufferHandle CreateBuffer(int size) - { - return CreateBuffer(size, BufferHandle.Null); - } + BufferHandle CreateBuffer(int size, BufferAccess access = BufferAccess.Default); + BufferHandle CreateBuffer(int size, BufferAccess access, BufferHandle storageHint); BufferHandle CreateBuffer(nint pointer, int size); - BufferHandle CreateBuffer(int size, BufferAccess access); + BufferHandle CreateBufferSparse(ReadOnlySpan storageBuffers); IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info); diff --git a/src/Ryujinx.Graphics.GAL/LogicalOp.cs b/src/Ryujinx.Graphics.GAL/LogicalOp.cs index 8fe6c782d..6c6a6189b 100644 --- a/src/Ryujinx.Graphics.GAL/LogicalOp.cs +++ b/src/Ryujinx.Graphics.GAL/LogicalOp.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL +namespace Ryujinx.Graphics.GAL { public enum LogicalOp { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/BufferMap.cs b/src/Ryujinx.Graphics.GAL/Multithreading/BufferMap.cs index 6377e5eac..e8eec123a 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/BufferMap.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/BufferMap.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Threading; diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs b/src/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs index 6cd6f1599..5bf3d3283 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Commands; +using Ryujinx.Graphics.GAL.Multithreading.Commands; using Ryujinx.Graphics.GAL.Multithreading.Commands.Buffer; using Ryujinx.Graphics.GAL.Multithreading.Commands.CounterEvent; using Ryujinx.Graphics.GAL.Multithreading.Commands.Program; @@ -44,6 +44,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading Register(CommandType.Action); Register(CommandType.CreateBuffer); Register(CommandType.CreateBufferAccess); + Register(CommandType.CreateBufferSparse); Register(CommandType.CreateHostBuffer); Register(CommandType.CreateProgram); Register(CommandType.CreateSampler); diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs b/src/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs index c24a934aa..6be639253 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs @@ -1,10 +1,11 @@ -namespace Ryujinx.Graphics.GAL.Multithreading +namespace Ryujinx.Graphics.GAL.Multithreading { enum CommandType : byte { Action, CreateBuffer, CreateBufferAccess, + CreateBufferSparse, CreateHostBuffer, CreateProgram, CreateSampler, diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/BarrierCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/BarrierCommand.cs index 4a73a3bc7..fd80a127b 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/BarrierCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/BarrierCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct BarrierCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/BeginTransformFeedbackCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/BeginTransformFeedbackCommand.cs index 538ff98d7..7b2f73174 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/BeginTransformFeedbackCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/BeginTransformFeedbackCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct BeginTransformFeedbackCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Buffer/BufferDisposeCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Buffer/BufferDisposeCommand.cs index 03ee8560f..aaf8e5b2d 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Buffer/BufferDisposeCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Buffer/BufferDisposeCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Buffer +namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Buffer { struct BufferDisposeCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Buffer/BufferGetDataCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Buffer/BufferGetDataCommand.cs index 0e3950229..b8f61df05 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Buffer/BufferGetDataCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Buffer/BufferGetDataCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Buffer { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Buffer/BufferSetDataCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Buffer/BufferSetDataCommand.cs index 30daf382a..592699e47 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Buffer/BufferSetDataCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Buffer/BufferSetDataCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using System; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Buffer diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/ClearBufferCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/ClearBufferCommand.cs index 777a8460b..e94da74be 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/ClearBufferCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/ClearBufferCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct ClearBufferCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/ClearRenderTargetColorCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/ClearRenderTargetColorCommand.cs index 3a24e181a..d4417f667 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/ClearRenderTargetColorCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/ClearRenderTargetColorCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct ClearRenderTargetColorCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/ClearRenderTargetDepthStencilCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/ClearRenderTargetDepthStencilCommand.cs index 43c0e89a4..78f81025d 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/ClearRenderTargetDepthStencilCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/ClearRenderTargetDepthStencilCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct ClearRenderTargetDepthStencilCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/CommandBufferBarrierCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/CommandBufferBarrierCommand.cs index 975562333..0403b33fe 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/CommandBufferBarrierCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/CommandBufferBarrierCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct CommandBufferBarrierCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/CopyBufferCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/CopyBufferCommand.cs index 8cd9e7f10..3eeaefb8b 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/CopyBufferCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/CopyBufferCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct CopyBufferCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/CounterEvent/CounterEventDisposeCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/CounterEvent/CounterEventDisposeCommand.cs index fd9868b14..1d5eabcfc 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/CounterEvent/CounterEventDisposeCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/CounterEvent/CounterEventDisposeCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.CounterEvent diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/CounterEvent/CounterEventFlushCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/CounterEvent/CounterEventFlushCommand.cs index 590169bc4..27cde8a8b 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/CounterEvent/CounterEventFlushCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/CounterEvent/CounterEventFlushCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.CounterEvent diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/DispatchComputeCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/DispatchComputeCommand.cs index 1a7c94f4a..65028378f 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/DispatchComputeCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/DispatchComputeCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct DispatchComputeCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/DrawCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/DrawCommand.cs index bd3cb89b7..8acf12ca7 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/DrawCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/DrawCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct DrawIndexedCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/DrawIndexedCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/DrawIndexedCommand.cs index c4d5ce661..8d43d4564 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/DrawIndexedCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/DrawIndexedCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct DrawCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/DrawIndexedIndirectCountCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/DrawIndexedIndirectCountCommand.cs index 1f6966226..2be81fbe0 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/DrawIndexedIndirectCountCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/DrawIndexedIndirectCountCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct DrawIndexedIndirectCountCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/DrawIndirectCountCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/DrawIndirectCountCommand.cs index eae98e4bd..0247aa29c 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/DrawIndirectCountCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/DrawIndirectCountCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct DrawIndirectCountCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/EndHostConditionalRenderingCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/EndHostConditionalRenderingCommand.cs index 5d30a901d..3f20c0105 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/EndHostConditionalRenderingCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/EndHostConditionalRenderingCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct EndHostConditionalRenderingCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/EndTransformFeedbackCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/EndTransformFeedbackCommand.cs index d050f477a..f5d5e5c2b 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/EndTransformFeedbackCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/EndTransformFeedbackCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct EndTransformFeedbackCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/IGALCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/IGALCommand.cs index ea831c8d4..ada6713b3 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/IGALCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/IGALCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { interface IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Program/ProgramCheckLinkCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Program/ProgramCheckLinkCommand.cs index b9c6e2866..e07fad9dd 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Program/ProgramCheckLinkCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Program/ProgramCheckLinkCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Program diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Program/ProgramDisposeCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Program/ProgramDisposeCommand.cs index 839a05bc7..ebe1428d1 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Program/ProgramDisposeCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Program/ProgramDisposeCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Program diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Program/ProgramGetBinaryCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Program/ProgramGetBinaryCommand.cs index b53fc8ac4..9aa72d4b1 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Program/ProgramGetBinaryCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Program/ProgramGetBinaryCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Program diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/ActionCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/ActionCommand.cs index 309a9cd0c..f0695f26d 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/ActionCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/ActionCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using System; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateBufferAccessCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateBufferAccessCommand.cs index 5efa0a7af..3dbc0b066 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateBufferAccessCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateBufferAccessCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer +namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer { struct CreateBufferAccessCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateBufferCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateBufferCommand.cs index 214b3589d..60a6e4bf4 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateBufferCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateBufferCommand.cs @@ -1,16 +1,18 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer +namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer { struct CreateBufferCommand : IGALCommand, IGALCommand { public readonly CommandType CommandType => CommandType.CreateBuffer; private BufferHandle _threadedHandle; private int _size; + private BufferAccess _access; private BufferHandle _storageHint; - public void Set(BufferHandle threadedHandle, int size, BufferHandle storageHint) + public void Set(BufferHandle threadedHandle, int size, BufferAccess access, BufferHandle storageHint) { _threadedHandle = threadedHandle; _size = size; + _access = access; _storageHint = storageHint; } @@ -23,7 +25,7 @@ hint = threaded.Buffers.MapBuffer(command._storageHint); } - threaded.Buffers.AssignBuffer(command._threadedHandle, renderer.CreateBuffer(command._size, hint)); + threaded.Buffers.AssignBuffer(command._threadedHandle, renderer.CreateBuffer(command._size, command._access, hint)); } } } diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateBufferSparseCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateBufferSparseCommand.cs new file mode 100644 index 000000000..965529ad1 --- /dev/null +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateBufferSparseCommand.cs @@ -0,0 +1,25 @@ +using Ryujinx.Graphics.GAL.Multithreading.Model; +using System; + +namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer +{ + struct CreateBufferSparseCommand : IGALCommand, IGALCommand + { + public readonly CommandType CommandType => CommandType.CreateBufferSparse; + private BufferHandle _threadedHandle; + private SpanRef _buffers; + + public void Set(BufferHandle threadedHandle, SpanRef buffers) + { + _threadedHandle = threadedHandle; + _buffers = buffers; + } + + public static void Run(ref CreateBufferSparseCommand command, ThreadedRenderer threaded, IRenderer renderer) + { + Span buffers = command._buffers.Get(threaded); + threaded.Buffers.AssignBuffer(command._threadedHandle, renderer.CreateBufferSparse(threaded.Buffers.MapBufferRanges(buffers))); + command._buffers.Dispose(threaded); + } + } +} diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateHostBufferCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateHostBufferCommand.cs index 1036e997e..0001680b6 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateHostBufferCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateHostBufferCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer +namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer { struct CreateHostBufferCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateProgramCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateProgramCommand.cs index b0d24b99c..2388c79a2 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateProgramCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateProgramCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources.Programs; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateSamplerCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateSamplerCommand.cs index 761882688..ae01bd0c4 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateSamplerCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateSamplerCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateSyncCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateSyncCommand.cs index 138a45915..9e9caa982 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateSyncCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateSyncCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer +namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer { struct CreateSyncCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateTextureCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateTextureCommand.cs index 6ec0daae8..7caf5bc1a 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateTextureCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateTextureCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/GetCapabilitiesCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/GetCapabilitiesCommand.cs index ade13ddfa..d6e6db7d6 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/GetCapabilitiesCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/GetCapabilitiesCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/PreFrameCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/PreFrameCommand.cs index cf26194b7..b9e2944b3 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/PreFrameCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/PreFrameCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer +namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer { struct PreFrameCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/ReportCounterCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/ReportCounterCommand.cs index 659cf4753..18b96f74b 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/ReportCounterCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/ReportCounterCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; using System; diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/ResetCounterCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/ResetCounterCommand.cs index a20a6ca2e..44dd674ed 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/ResetCounterCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/ResetCounterCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer +namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer { struct ResetCounterCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/UpdateCountersCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/UpdateCountersCommand.cs index e04304c11..a6c877a48 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/UpdateCountersCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/UpdateCountersCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer +namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer { struct UpdateCountersCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Sampler/SamplerDisposeCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Sampler/SamplerDisposeCommand.cs index 4a68a35d2..2e4eab5fa 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Sampler/SamplerDisposeCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Sampler/SamplerDisposeCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Sampler diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetAlphaTestCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetAlphaTestCommand.cs index 10bd3c5cd..bee7b866b 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetAlphaTestCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetAlphaTestCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct SetAlphaTestCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetBlendStateCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetBlendStateCommand.cs index de430b782..6fc2c1a2d 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetBlendStateCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetBlendStateCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct SetBlendStateCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetDepthBiasCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetDepthBiasCommand.cs index c8bb8472f..0c46fbda2 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetDepthBiasCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetDepthBiasCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct SetDepthBiasCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetDepthClampCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetDepthClampCommand.cs index b7cd2db99..ec34f4733 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetDepthClampCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetDepthClampCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct SetDepthClampCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetDepthModeCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetDepthModeCommand.cs index 94bb6d490..1f9b1fbcd 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetDepthModeCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetDepthModeCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct SetDepthModeCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetDepthTestCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetDepthTestCommand.cs index 1b316c1af..8df545289 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetDepthTestCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetDepthTestCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct SetDepthTestCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetFaceCullingCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetFaceCullingCommand.cs index 7823ab054..611168f85 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetFaceCullingCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetFaceCullingCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct SetFaceCullingCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetFrontFaceCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetFrontFaceCommand.cs index 5d4694477..9c0b79e48 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetFrontFaceCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetFrontFaceCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct SetFrontFaceCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetImageCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetImageCommand.cs index d24174fea..b4e966ca8 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetImageCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetImageCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; namespace Ryujinx.Graphics.GAL.Multithreading.Commands diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetIndexBufferCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetIndexBufferCommand.cs index 6a06ab9b3..629906dc9 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetIndexBufferCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetIndexBufferCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct SetIndexBufferCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetLineParametersCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetLineParametersCommand.cs index 4928360af..d11d46bb4 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetLineParametersCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetLineParametersCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct SetLineParametersCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetLogicOpStateCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetLogicOpStateCommand.cs index 5aecc7773..71f2e1d8e 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetLogicOpStateCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetLogicOpStateCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct SetLogicOpStateCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetPointParametersCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetPointParametersCommand.cs index a0993fb25..6faa25101 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetPointParametersCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetPointParametersCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct SetPointParametersCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetPrimitiveRestartCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetPrimitiveRestartCommand.cs index 2289d8bdb..9fd5b5415 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetPrimitiveRestartCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetPrimitiveRestartCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct SetPrimitiveRestartCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetPrimitiveTopologyCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetPrimitiveTopologyCommand.cs index 1458a1fc7..c7cb2a2fe 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetPrimitiveTopologyCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetPrimitiveTopologyCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct SetPrimitiveTopologyCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetProgramCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetProgramCommand.cs index 5b0114330..7f1d845b8 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetProgramCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetProgramCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; namespace Ryujinx.Graphics.GAL.Multithreading.Commands diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetRasterizerDiscardCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetRasterizerDiscardCommand.cs index 640911009..61f9246f2 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetRasterizerDiscardCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetRasterizerDiscardCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct SetRasterizerDiscardCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetRenderTargetColorMasksCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetRenderTargetColorMasksCommand.cs index 78d357aec..785c3215f 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetRenderTargetColorMasksCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetRenderTargetColorMasksCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using System; namespace Ryujinx.Graphics.GAL.Multithreading.Commands diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetRenderTargetsCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetRenderTargetsCommand.cs index 13ef32b5b..063cf1e03 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetRenderTargetsCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetRenderTargetsCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; using System.Linq; diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetScissorsCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetScissorsCommand.cs index 9d7d59e24..15ac00de8 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetScissorsCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetScissorsCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; namespace Ryujinx.Graphics.GAL.Multithreading.Commands { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetStencilTestCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetStencilTestCommand.cs index 23bea88b8..044241e6f 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetStencilTestCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetStencilTestCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct SetStencilTestCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetStorageBuffersCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetStorageBuffersCommand.cs index 525576c64..631605571 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetStorageBuffersCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetStorageBuffersCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using System; namespace Ryujinx.Graphics.GAL.Multithreading.Commands diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetTextureAndSamplerCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetTextureAndSamplerCommand.cs index 673da496a..6d63db864 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetTextureAndSamplerCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetTextureAndSamplerCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; using Ryujinx.Graphics.Shader; diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetTransformFeedbackBuffersCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetTransformFeedbackBuffersCommand.cs index cac837d91..35cb09f88 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetTransformFeedbackBuffersCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetTransformFeedbackBuffersCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using System; namespace Ryujinx.Graphics.GAL.Multithreading.Commands diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetUniformBuffersCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetUniformBuffersCommand.cs index 516a2bd3f..ec3777c39 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetUniformBuffersCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetUniformBuffersCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using System; namespace Ryujinx.Graphics.GAL.Multithreading.Commands diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetUserClipDistanceCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetUserClipDistanceCommand.cs index d7500900c..fffa69e62 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetUserClipDistanceCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetUserClipDistanceCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct SetUserClipDistanceCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetVertexAttribsCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetVertexAttribsCommand.cs index 18decb0b2..a8a182047 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetVertexAttribsCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetVertexAttribsCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using System; namespace Ryujinx.Graphics.GAL.Multithreading.Commands diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetVertexBuffersCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetVertexBuffersCommand.cs index bcfb553d8..9138fe429 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetVertexBuffersCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetVertexBuffersCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using System; namespace Ryujinx.Graphics.GAL.Multithreading.Commands diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetViewportsCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetViewportsCommand.cs index 4ad264780..03eae09e3 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetViewportsCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetViewportsCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using System; namespace Ryujinx.Graphics.GAL.Multithreading.Commands diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureCopyToCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureCopyToCommand.cs index ddbf0e679..80e0814fb 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureCopyToCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureCopyToCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureCopyToScaledCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureCopyToScaledCommand.cs index b43ffea56..8e879229a 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureCopyToScaledCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureCopyToScaledCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureCopyToSliceCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureCopyToSliceCommand.cs index 4f5ab36f9..52c569613 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureCopyToSliceCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureCopyToSliceCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureCreateViewCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureCreateViewCommand.cs index 9216e9689..04fbb584a 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureCreateViewCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureCreateViewCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureGetDataCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureGetDataCommand.cs index 38010467e..fa0f4f7ad 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureGetDataCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureGetDataCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureGetDataSliceCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureGetDataSliceCommand.cs index e84cf2d2b..1cb92d663 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureGetDataSliceCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureGetDataSliceCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureReleaseCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureReleaseCommand.cs index a9c528aee..c9727f1a9 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureReleaseCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureReleaseCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetDataCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetDataCommand.cs index 9aa2e4eef..36feeeba7 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetDataCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetDataCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; using System; diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetDataSliceCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetDataSliceCommand.cs index 14fecadfa..c50bfe089 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetDataSliceCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetDataSliceCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; using System; diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetStorageCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetStorageCommand.cs index fafaa5578..ed53d105a 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetStorageCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetStorageCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TextureBarrierCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TextureBarrierCommand.cs index 8b62d1eff..5ad8adfa5 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TextureBarrierCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TextureBarrierCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct TextureBarrierCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TextureBarrierTiledCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TextureBarrierTiledCommand.cs index 1cae4109c..423a7efb7 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TextureBarrierTiledCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TextureBarrierTiledCommand.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands +namespace Ryujinx.Graphics.GAL.Multithreading.Commands { struct TextureBarrierTiledCommand : IGALCommand, IGALCommand { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TryHostConditionalRenderingCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TryHostConditionalRenderingCommand.cs index a06f0b5ad..21e3a0d12 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TryHostConditionalRenderingCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TryHostConditionalRenderingCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; namespace Ryujinx.Graphics.GAL.Multithreading.Commands diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TryHostConditionalRenderingFlushCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TryHostConditionalRenderingFlushCommand.cs index eb920788b..73acef6b8 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TryHostConditionalRenderingFlushCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TryHostConditionalRenderingFlushCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; namespace Ryujinx.Graphics.GAL.Multithreading.Commands diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Window/WindowPresentCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Window/WindowPresentCommand.cs index 67ec35213..4034bc3c6 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Window/WindowPresentCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Window/WindowPresentCommand.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; +using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; using System; diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Model/CircularSpanPool.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Model/CircularSpanPool.cs index 10cab84ce..ec7ab1598 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Model/CircularSpanPool.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Model/CircularSpanPool.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Model/ResultBox.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Model/ResultBox.cs index 7a0be785e..9e136de9c 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Model/ResultBox.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Model/ResultBox.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Model +namespace Ryujinx.Graphics.GAL.Multithreading.Model { public class ResultBox { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Model/SpanRef.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Model/SpanRef.cs index 1ed719a08..faa496f1b 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Model/SpanRef.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Model/SpanRef.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.GAL.Multithreading.Model { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Model/TableRef.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Model/TableRef.cs index e454df214..d3a5a14e8 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Model/TableRef.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Model/TableRef.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Model +namespace Ryujinx.Graphics.GAL.Multithreading.Model { readonly struct TableRef { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ProgramQueue.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ProgramQueue.cs index 87ab2f1b2..cda3518c7 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ProgramQueue.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ProgramQueue.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Resources.Programs; +using Ryujinx.Graphics.GAL.Multithreading.Resources.Programs; using System; using System.Collections.Generic; using System.Threading; diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/Programs/BinaryProgramRequest.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/Programs/BinaryProgramRequest.cs index e4df1c1be..6d250682e 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/Programs/BinaryProgramRequest.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/Programs/BinaryProgramRequest.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Resources.Programs +namespace Ryujinx.Graphics.GAL.Multithreading.Resources.Programs { class BinaryProgramRequest : IProgramRequest { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/Programs/IProgramRequest.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/Programs/IProgramRequest.cs index cdbfe03c6..51fef9f55 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/Programs/IProgramRequest.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/Programs/IProgramRequest.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Resources.Programs +namespace Ryujinx.Graphics.GAL.Multithreading.Resources.Programs { interface IProgramRequest { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/Programs/SourceProgramRequest.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/Programs/SourceProgramRequest.cs index 744b77e1b..9852f5c95 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/Programs/SourceProgramRequest.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/Programs/SourceProgramRequest.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Resources.Programs +namespace Ryujinx.Graphics.GAL.Multithreading.Resources.Programs { class SourceProgramRequest : IProgramRequest { diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedCounterEvent.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedCounterEvent.cs index 2992b4a8c..15db2b9fa 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedCounterEvent.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedCounterEvent.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Commands.CounterEvent; +using Ryujinx.Graphics.GAL.Multithreading.Commands.CounterEvent; using Ryujinx.Graphics.GAL.Multithreading.Model; using System.Threading; diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedProgram.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedProgram.cs index 7cbbce45d..d5a22f669 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedProgram.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedProgram.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Commands.Program; +using Ryujinx.Graphics.GAL.Multithreading.Commands.Program; using Ryujinx.Graphics.GAL.Multithreading.Model; namespace Ryujinx.Graphics.GAL.Multithreading.Resources diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedSampler.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedSampler.cs index 62e628a76..ae3d993a3 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedSampler.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedSampler.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Commands.Sampler; +using Ryujinx.Graphics.GAL.Multithreading.Commands.Sampler; using Ryujinx.Graphics.GAL.Multithreading.Model; namespace Ryujinx.Graphics.GAL.Multithreading.Resources diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedTexture.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedTexture.cs index 68f258539..9ad9e6454 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedTexture.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedTexture.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.GAL.Multithreading.Commands.Texture; using Ryujinx.Graphics.GAL.Multithreading.Model; diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/SyncMap.cs b/src/Ryujinx.Graphics.GAL/Multithreading/SyncMap.cs index d6e416ef2..ecdff4922 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/SyncMap.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/SyncMap.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Threading; diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedHelpers.cs b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedHelpers.cs index 7ddb19e62..dcd0c5b11 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedHelpers.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedHelpers.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading; namespace Ryujinx.Graphics.GAL.Multithreading diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs index 69c67d642..f40d9896c 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Commands; +using Ryujinx.Graphics.GAL.Multithreading.Commands; using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; using Ryujinx.Graphics.Shader; diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs index b11ccb0a3..830fbf2d9 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Common.Configuration; using Ryujinx.Graphics.GAL.Multithreading.Commands; using Ryujinx.Graphics.GAL.Multithreading.Commands.Buffer; @@ -263,10 +263,19 @@ namespace Ryujinx.Graphics.GAL.Multithreading } } - public BufferHandle CreateBuffer(int size, BufferHandle storageHint) + public BufferHandle CreateBuffer(int size, BufferAccess access) { BufferHandle handle = Buffers.CreateBufferHandle(); - New().Set(handle, size, storageHint); + New().Set(handle, size, access); + QueueCommand(); + + return handle; + } + + public BufferHandle CreateBuffer(int size, BufferAccess access, BufferHandle storageHint) + { + BufferHandle handle = Buffers.CreateBufferHandle(); + New().Set(handle, size, access, storageHint); QueueCommand(); return handle; @@ -281,10 +290,10 @@ namespace Ryujinx.Graphics.GAL.Multithreading return handle; } - public BufferHandle CreateBuffer(int size, BufferAccess access) + public BufferHandle CreateBufferSparse(ReadOnlySpan storageBuffers) { BufferHandle handle = Buffers.CreateBufferHandle(); - New().Set(handle, size, access); + New().Set(handle, CopySpan(storageBuffers)); QueueCommand(); return handle; diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs index 4f1b795a4..acda37ef3 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL.Multithreading.Commands.Window; +using Ryujinx.Graphics.GAL.Multithreading.Commands.Window; using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; using System; diff --git a/src/Ryujinx.Graphics.GAL/Origin.cs b/src/Ryujinx.Graphics.GAL/Origin.cs index bc2a21f1c..9d3363268 100644 --- a/src/Ryujinx.Graphics.GAL/Origin.cs +++ b/src/Ryujinx.Graphics.GAL/Origin.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL +namespace Ryujinx.Graphics.GAL { public enum Origin { diff --git a/src/Ryujinx.Graphics.GAL/PinnedSpan.cs b/src/Ryujinx.Graphics.GAL/PinnedSpan.cs index d028f07c3..e2b33f444 100644 --- a/src/Ryujinx.Graphics.GAL/PinnedSpan.cs +++ b/src/Ryujinx.Graphics.GAL/PinnedSpan.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Graphics.GAL/ProgramLinkStatus.cs b/src/Ryujinx.Graphics.GAL/ProgramLinkStatus.cs index 4dd3b4d5d..84f2729ac 100644 --- a/src/Ryujinx.Graphics.GAL/ProgramLinkStatus.cs +++ b/src/Ryujinx.Graphics.GAL/ProgramLinkStatus.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.GAL +namespace Ryujinx.Graphics.GAL { public enum ProgramLinkStatus { diff --git a/src/Ryujinx.Graphics.GAL/ProgramPipelineState.cs b/src/Ryujinx.Graphics.GAL/ProgramPipelineState.cs index 96fd667ad..c16722af7 100644 --- a/src/Ryujinx.Graphics.GAL/ProgramPipelineState.cs +++ b/src/Ryujinx.Graphics.GAL/ProgramPipelineState.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System; namespace Ryujinx.Graphics.GAL diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Compute/ComputeClass.cs b/src/Ryujinx.Graphics.Gpu/Engine/Compute/ComputeClass.cs index 67743de37..ccdbe4748 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Compute/ComputeClass.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Compute/ComputeClass.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Device; +using Ryujinx.Graphics.Device; using Ryujinx.Graphics.Gpu.Engine.InlineToMemory; using Ryujinx.Graphics.Gpu.Engine.Threed; using Ryujinx.Graphics.Gpu.Engine.Types; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Compute/ComputeClassState.cs b/src/Ryujinx.Graphics.Gpu/Engine/Compute/ComputeClassState.cs index 0b192ef6b..18f79cc3a 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Compute/ComputeClassState.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Compute/ComputeClassState.cs @@ -1,4 +1,4 @@ -// This file was auto-generated from NVIDIA official Maxwell definitions. +// This file was auto-generated from NVIDIA official Maxwell definitions. using Ryujinx.Common.Memory; using Ryujinx.Graphics.Gpu.Engine.InlineToMemory; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/ConditionalRenderEnabled.cs b/src/Ryujinx.Graphics.Gpu/Engine/ConditionalRenderEnabled.cs index 52d7f69f2..9edf80684 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/ConditionalRenderEnabled.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/ConditionalRenderEnabled.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Gpu.Engine +namespace Ryujinx.Graphics.Gpu.Engine { /// /// Conditional rendering enable. diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs b/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs index b1921bd51..6dae829ff 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Graphics.Device; using Ryujinx.Graphics.Gpu.Engine.Threed; using Ryujinx.Graphics.Gpu.Memory; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClassState.cs b/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClassState.cs index d85887368..f258c0070 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClassState.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClassState.cs @@ -1,4 +1,4 @@ -// This file was auto-generated from NVIDIA official Maxwell definitions. +// This file was auto-generated from NVIDIA official Maxwell definitions. namespace Ryujinx.Graphics.Gpu.Engine.Dma { diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaTexture.cs b/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaTexture.cs index 8193c4a2c..368158718 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaTexture.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaTexture.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Gpu.Engine.Types; +using Ryujinx.Graphics.Gpu.Engine.Types; namespace Ryujinx.Graphics.Gpu.Engine.Dma { diff --git a/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/CompressedMethod.cs b/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/CompressedMethod.cs index afa4db5ec..21eb5bfa9 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/CompressedMethod.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/CompressedMethod.cs @@ -1,4 +1,4 @@ -// This file was auto-generated from NVIDIA official Maxwell definitions. +// This file was auto-generated from NVIDIA official Maxwell definitions. namespace Ryujinx.Graphics.Gpu.Engine.GPFifo { diff --git a/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPEntry.cs b/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPEntry.cs index 81e28acf4..d28f2fbb5 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPEntry.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPEntry.cs @@ -1,4 +1,4 @@ -// This file was auto-generated from NVIDIA official Maxwell definitions. +// This file was auto-generated from NVIDIA official Maxwell definitions. namespace Ryujinx.Graphics.Gpu.Engine.GPFifo { diff --git a/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoClass.cs b/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoClass.cs index 4bdbd1a03..5bd8ec728 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoClass.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoClass.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Device; +using Ryujinx.Graphics.Device; using Ryujinx.Graphics.Gpu.Engine.MME; using Ryujinx.Graphics.Gpu.Synchronization; using System; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoClassState.cs b/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoClassState.cs index dd6ae1b40..56bebc336 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoClassState.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoClassState.cs @@ -1,4 +1,4 @@ -// This file was auto-generated from NVIDIA official Maxwell definitions. +// This file was auto-generated from NVIDIA official Maxwell definitions. using Ryujinx.Common.Memory; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoDevice.cs b/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoDevice.cs index bb5bc21cb..7d0f026ec 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoDevice.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoDevice.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Gpu.Memory; +using Ryujinx.Graphics.Gpu.Memory; using System; using System.Collections.Concurrent; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoProcessor.cs b/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoProcessor.cs index 180e2a6b6..b57109c7d 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoProcessor.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoProcessor.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Device; +using Ryujinx.Graphics.Device; using Ryujinx.Graphics.Gpu.Engine.Compute; using Ryujinx.Graphics.Gpu.Engine.Dma; using Ryujinx.Graphics.Gpu.Engine.InlineToMemory; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs b/src/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs index e417b9a0a..37d74fdd3 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Graphics.Device; using Ryujinx.Graphics.Texture; using System; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClassState.cs b/src/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClassState.cs index ec5042fda..1aff0441f 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClassState.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClassState.cs @@ -1,4 +1,4 @@ -// This file was auto-generated from NVIDIA official Maxwell definitions. +// This file was auto-generated from NVIDIA official Maxwell definitions. using Ryujinx.Common.Memory; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/MME/AluOperation.cs b/src/Ryujinx.Graphics.Gpu/Engine/MME/AluOperation.cs index 43faa788b..45b24e4ac 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/MME/AluOperation.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/MME/AluOperation.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Gpu.Engine.MME +namespace Ryujinx.Graphics.Gpu.Engine.MME { /// /// GPU Macro Arithmetic and Logic unit operation. diff --git a/src/Ryujinx.Graphics.Gpu/Engine/MME/AluRegOperation.cs b/src/Ryujinx.Graphics.Gpu/Engine/MME/AluRegOperation.cs index c878bd41f..09e5c6f0c 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/MME/AluRegOperation.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/MME/AluRegOperation.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Gpu.Engine.MME +namespace Ryujinx.Graphics.Gpu.Engine.MME { /// /// GPU Macro Arithmetic and Logic unit binary register-to-register operation. diff --git a/src/Ryujinx.Graphics.Gpu/Engine/MME/AssignmentOperation.cs b/src/Ryujinx.Graphics.Gpu/Engine/MME/AssignmentOperation.cs index 592aa5a68..3ad3446f7 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/MME/AssignmentOperation.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/MME/AssignmentOperation.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Gpu.Engine.MME +namespace Ryujinx.Graphics.Gpu.Engine.MME { /// /// GPU Macro assignment operation. diff --git a/src/Ryujinx.Graphics.Gpu/Engine/MME/IMacroEE.cs b/src/Ryujinx.Graphics.Gpu/Engine/MME/IMacroEE.cs index 117961db2..d7b862521 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/MME/IMacroEE.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/MME/IMacroEE.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Device; +using Ryujinx.Graphics.Device; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/MME/Macro.cs b/src/Ryujinx.Graphics.Gpu/Engine/MME/Macro.cs index 65c6aab4a..0cf1f306d 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/MME/Macro.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/MME/Macro.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Device; +using Ryujinx.Graphics.Device; using Ryujinx.Graphics.Gpu.Engine.GPFifo; using System; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLE.cs b/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLE.cs index 7d9e1ec02..7f3772f44 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLE.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLE.cs @@ -5,6 +5,7 @@ using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Engine.GPFifo; using Ryujinx.Graphics.Gpu.Engine.Threed; using Ryujinx.Graphics.Gpu.Engine.Types; +using Ryujinx.Memory.Range; using System; using System.Collections.Generic; @@ -392,12 +393,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME _processor.ThreedClass.DrawIndirect( topology, - indirectBufferAddress, - 0, + new MultiRange(indirectBufferAddress, IndirectIndexedDataEntrySize), + default, 1, IndirectIndexedDataEntrySize, indexCount, - Threed.IndirectDrawType.DrawIndexedIndirect); + IndirectDrawType.DrawIndexedIndirect); } else { @@ -494,13 +495,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME ulong indirectBufferSize = (ulong)maxDrawCount * (ulong)stride; - ulong indirectBufferAddress = bufferCache.TranslateAndCreateBuffer(_processor.MemoryManager, indirectBufferGpuVa, indirectBufferSize); - ulong parameterBufferAddress = bufferCache.TranslateAndCreateBuffer(_processor.MemoryManager, parameterBufferGpuVa, 4); + MultiRange indirectBufferRange = bufferCache.TranslateAndCreateMultiBuffers(_processor.MemoryManager, indirectBufferGpuVa, indirectBufferSize); + MultiRange parameterBufferRange = bufferCache.TranslateAndCreateMultiBuffers(_processor.MemoryManager, parameterBufferGpuVa, 4); _processor.ThreedClass.DrawIndirect( topology, - indirectBufferAddress, - parameterBufferAddress, + indirectBufferRange, + parameterBufferRange, maxDrawCount, stride, indexCount, diff --git a/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLEFunctionName.cs b/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLEFunctionName.cs index 8dca52262..55514c73e 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLEFunctionName.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLEFunctionName.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Gpu.Engine.MME +namespace Ryujinx.Graphics.Gpu.Engine.MME { /// /// Name of the High-level implementation of a Macro function. diff --git a/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLETable.cs b/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLETable.cs index 9a496164d..43b701293 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLETable.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLETable.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Graphics.GAL; using System; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroJit.cs b/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroJit.cs index a23bfef12..0f26490a8 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroJit.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroJit.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Device; +using Ryujinx.Graphics.Device; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroJitCompiler.cs b/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroJitCompiler.cs index d9c26c587..d5229970f 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroJitCompiler.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroJitCompiler.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Device; +using Ryujinx.Graphics.Device; using System; using System.Collections.Generic; using System.Reflection.Emit; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroJitContext.cs b/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroJitContext.cs index 5a71e3f47..01bff8e89 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroJitContext.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/MME/MacroJitContext.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Graphics.Device; using System.Collections.Generic; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/MmeShadowScratch.cs b/src/Ryujinx.Graphics.Gpu/Engine/MmeShadowScratch.cs index 0aa6b82af..b4346add1 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/MmeShadowScratch.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/MmeShadowScratch.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; namespace Ryujinx.Graphics.Gpu.Engine diff --git a/src/Ryujinx.Graphics.Gpu/Engine/ShaderTexture.cs b/src/Ryujinx.Graphics.Gpu/Engine/ShaderTexture.cs index 40d9a97df..492c6ee60 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/ShaderTexture.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/ShaderTexture.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Shader; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/ComputeDraw/VtgAsComputeState.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/ComputeDraw/VtgAsComputeState.cs index d1a333a71..6324e6a15 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/ComputeDraw/VtgAsComputeState.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/ComputeDraw/VtgAsComputeState.cs @@ -370,8 +370,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw { var memoryManager = _channel.MemoryManager; - address = memoryManager.Translate(address); - BufferRange range = memoryManager.Physical.BufferCache.GetBufferRange(address, size); + BufferRange range = memoryManager.Physical.BufferCache.GetBufferRange(memoryManager.GetPhysicalRegions(address, size)); ITexture bufferTexture = _vacContext.EnsureBufferTexture(index + 2, format); bufferTexture.SetStorage(range); @@ -412,9 +411,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw var memoryManager = _channel.MemoryManager; - address = memoryManager.Translate(address + indexOffset); ulong misalign = address & ((ulong)_context.Capabilities.TextureBufferOffsetAlignment - 1); - BufferRange range = memoryManager.Physical.BufferCache.GetBufferRange(address - misalign, size + misalign); + BufferRange range = memoryManager.Physical.BufferCache.GetBufferRange(memoryManager.GetPhysicalRegions(address + indexOffset - misalign, size + misalign)); misalignedOffset = (int)misalign >> shift; SetIndexBufferTexture(reservations, range, format); diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/ConditionalRendering.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/ConditionalRendering.cs index a6b62a4a8..01ef2f9a0 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/ConditionalRendering.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/ConditionalRendering.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Engine.Types; using Ryujinx.Graphics.Gpu.Memory; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/ConstantBufferUpdater.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/ConstantBufferUpdater.cs index e30092cee..2095fcd7a 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/ConstantBufferUpdater.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/ConstantBufferUpdater.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; namespace Ryujinx.Graphics.Gpu.Engine.Threed diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs index 1c31312ce..d8de14de0 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs @@ -1,8 +1,9 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw; using Ryujinx.Graphics.Gpu.Engine.Types; using Ryujinx.Graphics.Gpu.Image; using Ryujinx.Graphics.Gpu.Memory; +using Ryujinx.Memory.Range; using System; namespace Ryujinx.Graphics.Gpu.Engine.Threed @@ -102,6 +103,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed /// Method call argument public void DrawEnd(ThreedClass engine, int argument) { + _drawState.DrawUsesEngineState = true; + DrawEnd( engine, _state.State.IndexBufferState.First, @@ -204,10 +207,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed } else { -#pragma warning disable IDE0059 // Remove unnecessary value assignment - var drawState = _state.State.VertexBufferDrawState; -#pragma warning restore IDE0059 - DrawImpl(engine, drawVertexCount, 1, 0, drawFirstVertex, firstInstance, indexed: false); } @@ -378,6 +377,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed bool oldDrawIndexed = _drawState.DrawIndexed; _drawState.DrawIndexed = true; + _drawState.DrawUsesEngineState = false; engine.ForceStateDirty(IndexBufferCountMethodOffset * 4); DrawEnd(engine, firstIndex, indexCount, 0, 0); @@ -423,6 +423,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed bool oldDrawIndexed = _drawState.DrawIndexed; _drawState.DrawIndexed = false; + _drawState.DrawUsesEngineState = false; engine.ForceStateDirty(VertexBufferFirstMethodOffset * 4); DrawEnd(engine, 0, 0, firstVertex, vertexCount); @@ -543,6 +544,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed _state.State.FirstInstance = (uint)firstInstance; _drawState.DrawIndexed = indexed; + _drawState.DrawUsesEngineState = true; _currentSpecState.SetHasConstantBufferDrawParameters(true); engine.UpdateState(); @@ -630,8 +632,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed /// /// 3D engine where this method is being called /// Primitive topology - /// Address of the buffer with the draw parameters, such as count, first index, etc - /// Address of the buffer with the draw count + /// Memory range of the buffer with the draw parameters, such as count, first index, etc + /// Memory range of the buffer with the draw count /// Maximum number of draws that can be made /// Distance in bytes between each entry on the data pointed to by /// Maximum number of indices that the draw can consume @@ -639,8 +641,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed public void DrawIndirect( ThreedClass engine, PrimitiveTopology topology, - ulong indirectBufferAddress, - ulong parameterBufferAddress, + MultiRange indirectBufferRange, + MultiRange parameterBufferRange, int maxDrawCount, int stride, int indexCount, @@ -675,14 +677,15 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed _drawState.DrawIndexed = indexed; _drawState.DrawIndirect = true; + _drawState.DrawUsesEngineState = true; _currentSpecState.SetHasConstantBufferDrawParameters(true); engine.UpdateState(); if (hasCount) { - var indirectBuffer = memory.BufferCache.GetBufferRange(indirectBufferAddress, (ulong)maxDrawCount * (ulong)stride); - var parameterBuffer = memory.BufferCache.GetBufferRange(parameterBufferAddress, 4); + var indirectBuffer = memory.BufferCache.GetBufferRange(indirectBufferRange); + var parameterBuffer = memory.BufferCache.GetBufferRange(parameterBufferRange); if (indexed) { @@ -695,7 +698,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed } else { - var indirectBuffer = memory.BufferCache.GetBufferRange(indirectBufferAddress, (ulong)stride); + var indirectBuffer = memory.BufferCache.GetBufferRange(indirectBufferRange); if (indexed) { diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/DrawState.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/DrawState.cs index cb43b0025..03b5e3f3b 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/DrawState.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/DrawState.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Shader; namespace Ryujinx.Graphics.Gpu.Engine.Threed @@ -38,6 +38,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed /// public bool DrawIndirect; + /// + /// Indicates that the draw is using the draw parameters on the 3D engine state, rather than inline parameters submitted with the draw command. + /// + public bool DrawUsesEngineState; + /// /// Indicates if any of the currently used vertex shaders reads the instance ID. /// @@ -48,11 +53,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed /// public bool IsAnyVbInstanced; - /// - /// Indicates that the draw is writing the base vertex, base instance and draw index to Constant Buffer 0. - /// - public bool HasConstantBufferDrawParameters; - /// /// Primitive topology for the next draw. /// diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/IbStreamer.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/IbStreamer.cs index 6e15fcfa3..739d32237 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/IbStreamer.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/IbStreamer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Graphics.GAL; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/SemaphoreUpdater.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/SemaphoreUpdater.cs index 247752caf..a9a96d54a 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/SemaphoreUpdater.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/SemaphoreUpdater.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; namespace Ryujinx.Graphics.Gpu.Engine.Threed { diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/SpecializationStateUpdater.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/SpecializationStateUpdater.cs index 4fbbee3bc..dbd4efc8f 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/SpecializationStateUpdater.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/SpecializationStateUpdater.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Engine.Types; using Ryujinx.Graphics.Gpu.Shader; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdateTracker.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdateTracker.cs index 7c7309676..e54855a8f 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdateTracker.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdateTracker.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Device; +using Ryujinx.Graphics.Device; using System; using System.Collections.Generic; using System.Diagnostics; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs index 1ff821569..2b65b4560 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Engine.Threed.Blender; using Ryujinx.Graphics.Gpu.Engine.Types; @@ -47,7 +47,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed private uint _vbEnableMask; private bool _prevDrawIndexed; - private readonly bool _prevDrawIndirect; + private bool _prevDrawIndirect; + private bool _prevDrawUsesEngineState; private IndexType _prevIndexType; private uint _prevFirstVertex; private bool _prevTfEnable; @@ -236,7 +237,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed // method when doing indexed draws, so we need to make sure // to update the vertex buffers if we are doing a regular // draw after a indexed one and vice-versa. - if (_drawState.DrawIndexed != _prevDrawIndexed) + // Some draws also do not update the engine state, so it is possible for it + // to not be dirty even if the vertex counts or other state changed. We need to force it to be dirty in this case. + if (_drawState.DrawIndexed != _prevDrawIndexed || _drawState.DrawUsesEngineState != _prevDrawUsesEngineState) { _updateTracker.ForceDirty(VertexBufferStateIndex); @@ -251,6 +254,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed } _prevDrawIndexed = _drawState.DrawIndexed; + _prevDrawUsesEngineState = _drawState.DrawUsesEngineState; } // Some draw parameters are used to restrict the vertex buffer size, @@ -260,6 +264,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed if (_drawState.DrawIndirect != _prevDrawIndirect) { _updateTracker.ForceDirty(VertexBufferStateIndex); + + _prevDrawIndirect = _drawState.DrawIndirect; } // In some cases, the index type is also used to guess the diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs index df9d1f5c9..ab1d27a1c 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.Device; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Engine.GPFifo; @@ -6,6 +6,7 @@ using Ryujinx.Graphics.Gpu.Engine.InlineToMemory; using Ryujinx.Graphics.Gpu.Engine.Threed.Blender; using Ryujinx.Graphics.Gpu.Engine.Types; using Ryujinx.Graphics.Gpu.Synchronization; +using Ryujinx.Memory.Range; using System; using System.Collections.Generic; using System.Runtime.CompilerServices; @@ -803,22 +804,22 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed /// Performs a indirect draw, with parameters from a GPU buffer. /// /// Primitive topology - /// Address of the buffer with the draw parameters, such as count, first index, etc - /// Address of the buffer with the draw count + /// Memory range of the buffer with the draw parameters, such as count, first index, etc + /// Memory range of the buffer with the draw count /// Maximum number of draws that can be made - /// Distance in bytes between each entry on the data pointed to by + /// Distance in bytes between each entry on the data pointed to by /// Maximum number of indices that the draw can consume /// Type of the indirect draw, which can be indexed or non-indexed, with or without a draw count public void DrawIndirect( PrimitiveTopology topology, - ulong indirectBufferAddress, - ulong parameterBufferAddress, + MultiRange indirectBufferRange, + MultiRange parameterBufferRange, int maxDrawCount, int stride, int indexCount, IndirectDrawType drawType) { - _drawManager.DrawIndirect(this, topology, indirectBufferAddress, parameterBufferAddress, maxDrawCount, stride, indexCount, drawType); + _drawManager.DrawIndirect(this, topology, indirectBufferRange, parameterBufferRange, maxDrawCount, stride, indexCount, drawType); } /// diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs index 45284525c..dd55e7d1d 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Engine.InlineToMemory; using Ryujinx.Graphics.Gpu.Engine.Types; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Twod/TwodClass.cs b/src/Ryujinx.Graphics.Gpu/Engine/Twod/TwodClass.cs index b33fb7f73..0dd9481df 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Twod/TwodClass.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Twod/TwodClass.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Graphics.Device; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Engine.Types; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Twod/TwodClassState.cs b/src/Ryujinx.Graphics.Gpu/Engine/Twod/TwodClassState.cs index edea73273..2ea4709ec 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Twod/TwodClassState.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Twod/TwodClassState.cs @@ -1,4 +1,4 @@ -// This file was auto-generated from NVIDIA official Maxwell definitions. +// This file was auto-generated from NVIDIA official Maxwell definitions. using Ryujinx.Common.Memory; diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Twod/TwodTexture.cs b/src/Ryujinx.Graphics.Gpu/Engine/Twod/TwodTexture.cs index dd6b69000..8e8afb41c 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Twod/TwodTexture.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Twod/TwodTexture.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Gpu.Engine.Types; +using Ryujinx.Graphics.Gpu.Engine.Types; namespace Ryujinx.Graphics.Gpu.Engine.Twod { diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Types/Boolean32.cs b/src/Ryujinx.Graphics.Gpu/Engine/Types/Boolean32.cs index 7293fab9c..0db83da80 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Types/Boolean32.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Types/Boolean32.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Gpu.Engine.Types +namespace Ryujinx.Graphics.Gpu.Engine.Types { /// /// Boolean value, stored as a 32-bits integer in memory. diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Types/GpuVa.cs b/src/Ryujinx.Graphics.Gpu/Engine/Types/GpuVa.cs index b3b0c41ad..404599908 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Types/GpuVa.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Types/GpuVa.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Gpu.Engine.Types +namespace Ryujinx.Graphics.Gpu.Engine.Types { /// /// Split GPU virtual address. diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Types/MemoryLayout.cs b/src/Ryujinx.Graphics.Gpu/Engine/Types/MemoryLayout.cs index 5a4253734..9af5e6103 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Types/MemoryLayout.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Types/MemoryLayout.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Gpu.Engine.Types +namespace Ryujinx.Graphics.Gpu.Engine.Types { /// /// Memory layout parameters, for block linear textures. diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Types/SbDescriptor.cs b/src/Ryujinx.Graphics.Gpu/Engine/Types/SbDescriptor.cs index e92263df0..e1cc8c01d 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Types/SbDescriptor.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Types/SbDescriptor.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Gpu.Engine.Types +namespace Ryujinx.Graphics.Gpu.Engine.Types { /// /// Storage buffer address and size information. diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Types/ZetaFormat.cs b/src/Ryujinx.Graphics.Gpu/Engine/Types/ZetaFormat.cs index 0fa073d7b..e2a044e72 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Types/ZetaFormat.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Types/ZetaFormat.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Image; namespace Ryujinx.Graphics.Gpu.Engine.Types diff --git a/src/Ryujinx.Graphics.Gpu/GpuChannel.cs b/src/Ryujinx.Graphics.Gpu/GpuChannel.cs index d70c9645e..33618a15b 100644 --- a/src/Ryujinx.Graphics.Gpu/GpuChannel.cs +++ b/src/Ryujinx.Graphics.Gpu/GpuChannel.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Engine.GPFifo; using Ryujinx.Graphics.Gpu.Image; using Ryujinx.Graphics.Gpu.Memory; diff --git a/src/Ryujinx.Graphics.Gpu/GpuContext.cs b/src/Ryujinx.Graphics.Gpu/GpuContext.cs index a50852b05..aa0084fdc 100644 --- a/src/Ryujinx.Graphics.Gpu/GpuContext.cs +++ b/src/Ryujinx.Graphics.Gpu/GpuContext.cs @@ -1,4 +1,5 @@ using Ryujinx.Common; +using Ryujinx.Graphics.Device; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Engine.GPFifo; using Ryujinx.Graphics.Gpu.Memory; @@ -106,6 +107,8 @@ namespace Ryujinx.Graphics.Gpu private long _modifiedSequence; private readonly ulong _firstTimestamp; + private readonly ManualResetEvent _gpuReadyEvent; + /// /// Creates a new instance of the GPU emulation context. /// @@ -121,6 +124,7 @@ namespace Ryujinx.Graphics.Gpu Window = new Window(this); HostInitalized = new ManualResetEvent(false); + _gpuReadyEvent = new ManualResetEvent(false); SyncActions = new List(); SyncpointActions = new List(); @@ -160,6 +164,22 @@ namespace Ryujinx.Graphics.Gpu return new MemoryManager(physicalMemory); } + /// + /// Creates a new device memory manager. + /// + /// ID of the process that owns the memory manager + /// The memory manager + /// Thrown when is invalid + public DeviceMemoryManager CreateDeviceMemoryManager(ulong pid) + { + if (!PhysicalMemoryRegistry.TryGetValue(pid, out var physicalMemory)) + { + throw new ArgumentException("The PID is invalid or the process was not registered", nameof(pid)); + } + + return physicalMemory.CreateDeviceMemoryManager(); + } + /// /// Registers virtual memory used by a process for GPU memory access, caching and read/write tracking. /// @@ -216,7 +236,7 @@ namespace Ryujinx.Graphics.Gpu /// Gets a sequence number for resource modification ordering. This increments on each call. /// /// A sequence number for resource modification ordering - public long GetModifiedSequence() + internal long GetModifiedSequence() { return _modifiedSequence++; } @@ -225,7 +245,7 @@ namespace Ryujinx.Graphics.Gpu /// Gets the value of the GPU timer. /// /// The current GPU timestamp - public ulong GetTimestamp() + internal ulong GetTimestamp() { // Guest timestamp will start at 0, instead of host value. ulong ticks = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds) - _firstTimestamp; @@ -262,6 +282,16 @@ namespace Ryujinx.Graphics.Gpu { physicalMemory.ShaderCache.Initialize(cancellationToken); } + + _gpuReadyEvent.Set(); + } + + /// + /// Waits until the GPU is ready to receive commands. + /// + public void WaitUntilGpuReady() + { + _gpuReadyEvent.WaitOne(); } /// @@ -399,6 +429,7 @@ namespace Ryujinx.Graphics.Gpu { GPFifo.Dispose(); HostInitalized.Dispose(); + _gpuReadyEvent.Dispose(); // Has to be disposed before processing deferred actions, as it will produce some. foreach (var physicalMemory in PhysicalMemoryRegistry.Values) diff --git a/src/Ryujinx.Graphics.Gpu/Image/ITextureDescriptor.cs b/src/Ryujinx.Graphics.Gpu/Image/ITextureDescriptor.cs index 378de44b6..d287acc22 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/ITextureDescriptor.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/ITextureDescriptor.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Gpu.Image +namespace Ryujinx.Graphics.Gpu.Image { interface ITextureDescriptor { diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs index 8eca18b48..963bd947d 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs @@ -382,7 +382,7 @@ namespace Ryujinx.Graphics.Gpu.Image { ref BufferBounds bounds = ref _channel.BufferManager.GetUniformBufferBounds(_isCompute, stageIndex, textureBufferIndex); - cachedTextureBuffer = MemoryMarshal.Cast(_channel.MemoryManager.Physical.GetSpan(bounds.Address, (int)bounds.Size)); + cachedTextureBuffer = MemoryMarshal.Cast(_channel.MemoryManager.Physical.GetSpan(bounds.Range)); cachedTextureBufferIndex = textureBufferIndex; if (samplerBufferIndex == textureBufferIndex) @@ -396,7 +396,7 @@ namespace Ryujinx.Graphics.Gpu.Image { ref BufferBounds bounds = ref _channel.BufferManager.GetUniformBufferBounds(_isCompute, stageIndex, samplerBufferIndex); - cachedSamplerBuffer = MemoryMarshal.Cast(_channel.MemoryManager.Physical.GetSpan(bounds.Address, (int)bounds.Size)); + cachedSamplerBuffer = MemoryMarshal.Cast(_channel.MemoryManager.Physical.GetSpan(bounds.Range)); cachedSamplerBufferIndex = samplerBufferIndex; } } @@ -524,7 +524,7 @@ namespace Ryujinx.Graphics.Gpu.Image // Ensure that the buffer texture is using the correct buffer as storage. // Buffers are frequently re-created to accommodate larger data, so we need to re-bind // to ensure we're not using a old buffer that was already deleted. - _channel.BufferManager.SetBufferTextureStorage(stage, hostTexture, texture.Range.GetSubRange(0).Address, texture.Size, bindingInfo, bindingInfo.Format, false); + _channel.BufferManager.SetBufferTextureStorage(stage, hostTexture, texture.Range, bindingInfo, bindingInfo.Format, false); // Cache is not used for buffer texture, it must always rebind. state.CachedTexture = null; @@ -661,7 +661,7 @@ namespace Ryujinx.Graphics.Gpu.Image format = texture.Format; } - _channel.BufferManager.SetBufferTextureStorage(stage, hostTexture, texture.Range.GetSubRange(0).Address, texture.Size, bindingInfo, format, true); + _channel.BufferManager.SetBufferTextureStorage(stage, hostTexture, texture.Range, bindingInfo, format, true); // Cache is not used for buffer texture, it must always rebind. state.CachedTexture = null; diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs index 6b92c0aaf..5743c89c0 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs @@ -790,8 +790,12 @@ namespace Ryujinx.Graphics.Gpu.Image texture = new Texture(_context, _physicalMemory, info, sizeInfo, range.Value, scaleMode); + // If the new texture is larger than the existing one, we need to fill the remaining space with CPU data, + // otherwise we only need the data that is copied from the existing texture, without loading the CPU data. + bool updateNewTexture = texture.Width > overlap.Width || texture.Height > overlap.Height; + texture.InitializeGroup(true, true, new List()); - texture.InitializeData(false, false); + texture.InitializeData(false, updateNewTexture); overlap.SynchronizeMemory(); overlap.CreateCopyDependency(texture, oInfo.FirstLayer, oInfo.FirstLevel, true); diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureDependency.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureDependency.cs index 269ddbd97..45a5a3973 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/TextureDependency.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/TextureDependency.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Gpu.Image +namespace Ryujinx.Graphics.Gpu.Image { /// /// One side of a two-way dependency between one texture view and another. diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs index b93f3832d..fb2097444 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Memory; using Ryujinx.Graphics.Texture; @@ -1630,12 +1630,6 @@ namespace Ryujinx.Graphics.Gpu.Image return; } - // If size is zero, we have nothing to flush. - if (size == 0) - { - return; - } - // There is a small gap here where the action is removed but _actionRegistered is still 1. // In this case it will skip registering the action, but here we are already handling it, // so there shouldn't be any issue as it's the same handler for all actions. diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureGroupHandle.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureGroupHandle.cs index 72b743906..d345ec2db 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/TextureGroupHandle.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/TextureGroupHandle.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Gpu.Synchronization; +using Ryujinx.Graphics.Gpu.Synchronization; using Ryujinx.Memory.Tracking; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureManager.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureManager.cs index fa278bbd9..3bf0beefd 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/TextureManager.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/TextureManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Engine.Types; using Ryujinx.Graphics.Gpu.Shader; using System; diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureMatchQuality.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureMatchQuality.cs index 67835e954..b918911bc 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/TextureMatchQuality.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/TextureMatchQuality.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Gpu.Image +namespace Ryujinx.Graphics.Gpu.Image { enum TextureMatchQuality { diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureScaleMode.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureScaleMode.cs index 5d8e14db3..aa316a9f0 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/TextureScaleMode.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/TextureScaleMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Gpu.Image +namespace Ryujinx.Graphics.Gpu.Image { /// /// The scale mode for a given texture. diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureViewCompatibility.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureViewCompatibility.cs index 3f3bfdfef..22476c397 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/TextureViewCompatibility.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/TextureViewCompatibility.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Gpu.Image +namespace Ryujinx.Graphics.Gpu.Image { /// /// The level of view compatibility one texture has to another. diff --git a/src/Ryujinx.Graphics.Gpu/Memory/Buffer.cs b/src/Ryujinx.Graphics.Gpu/Memory/Buffer.cs index c9286a619..12461e96e 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/Buffer.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/Buffer.cs @@ -43,6 +43,11 @@ namespace Ryujinx.Graphics.Gpu.Memory /// public int UnmappedSequence { get; private set; } + /// + /// Indicates if the buffer can be used in a sparse buffer mapping. + /// + public bool SparseCompatible { get; } + /// /// Ranges of the buffer that have been modified on the GPU. /// Ranges defined here cannot be updated from CPU until a CPU waiting sync point is reached. @@ -77,15 +82,25 @@ namespace Ryujinx.Graphics.Gpu.Memory /// Physical memory where the buffer is mapped /// Start address of the buffer /// Size of the buffer in bytes + /// Indicates if the buffer can be used in a sparse buffer mapping /// Buffers which this buffer contains, and will inherit tracking handles from - public Buffer(GpuContext context, PhysicalMemory physicalMemory, ulong address, ulong size, IEnumerable baseBuffers = null) + public Buffer( + GpuContext context, + PhysicalMemory physicalMemory, + ulong address, + ulong size, + bool sparseCompatible, + IEnumerable baseBuffers = null) { _context = context; _physicalMemory = physicalMemory; Address = address; Size = size; + SparseCompatible = sparseCompatible; - Handle = context.Renderer.CreateBuffer((int)size, baseBuffers?.MaxBy(x => x.Size).Handle ?? BufferHandle.Null); + BufferAccess access = sparseCompatible ? BufferAccess.SparseCompatible : BufferAccess.Default; + + Handle = context.Renderer.CreateBuffer((int)size, access, baseBuffers?.MaxBy(x => x.Size).Handle ?? BufferHandle.Null); _useGranular = size > GranularBufferThreshold; diff --git a/src/Ryujinx.Graphics.Gpu/Memory/BufferBounds.cs b/src/Ryujinx.Graphics.Gpu/Memory/BufferBounds.cs index a9ea04cef..aed3268ae 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/BufferBounds.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/BufferBounds.cs @@ -1,4 +1,5 @@ using Ryujinx.Graphics.Shader; +using Ryujinx.Memory.Range; namespace Ryujinx.Graphics.Gpu.Memory { @@ -8,30 +9,28 @@ namespace Ryujinx.Graphics.Gpu.Memory readonly struct BufferBounds { /// - /// Region virtual address. + /// Physical memory ranges where the buffer is mapped. /// - public ulong Address { get; } - - /// - /// Region size in bytes. - /// - public ulong Size { get; } + public MultiRange Range { get; } /// /// Buffer usage flags. /// public BufferUsageFlags Flags { get; } + /// + /// Indicates that the backing memory for the buffer does not exist. + /// + public bool IsUnmapped => Range.IsUnmapped; + /// /// Creates a new buffer region. /// - /// Region address - /// Region size + /// Physical memory ranges where the buffer is mapped /// Buffer usage flags - public BufferBounds(ulong address, ulong size, BufferUsageFlags flags = BufferUsageFlags.None) + public BufferBounds(MultiRange range, BufferUsageFlags flags = BufferUsageFlags.None) { - Address = address; - Size = size; + Range = range; Flags = flags; } } diff --git a/src/Ryujinx.Graphics.Gpu/Memory/BufferCache.cs b/src/Ryujinx.Graphics.Gpu/Memory/BufferCache.cs index 05cc312c7..bd9aa39c8 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/BufferCache.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/BufferCache.cs @@ -11,12 +11,24 @@ namespace Ryujinx.Graphics.Gpu.Memory /// class BufferCache : IDisposable { - private const int OverlapsBufferInitialCapacity = 10; - private const int OverlapsBufferMaxCapacity = 10000; + /// + /// Initial size for the array holding overlaps. + /// + public const int OverlapsBufferInitialCapacity = 10; + + /// + /// Maximum size that an array holding overlaps may have after trimming. + /// + public const int OverlapsBufferMaxCapacity = 10000; private const ulong BufferAlignmentSize = 0x1000; private const ulong BufferAlignmentMask = BufferAlignmentSize - 1; + /// + /// Alignment required for sparse buffer mappings. + /// + public const ulong SparseBufferAlignmentSize = 0x10000; + private const ulong MaxDynamicGrowthSize = 0x100000; private readonly GpuContext _context; @@ -27,6 +39,7 @@ namespace Ryujinx.Graphics.Gpu.Memory /// Must lock for any access from other threads. /// private readonly RangeList _buffers; + private readonly MultiRangeList _multiRangeBuffers; private Buffer[] _bufferOverlaps; @@ -47,6 +60,7 @@ namespace Ryujinx.Graphics.Gpu.Memory _physicalMemory = physicalMemory; _buffers = new RangeList(); + _multiRangeBuffers = new MultiRangeList(); _bufferOverlaps = new Buffer[OverlapsBufferInitialCapacity]; @@ -66,45 +80,100 @@ namespace Ryujinx.Graphics.Gpu.Memory Buffer[] overlaps = new Buffer[10]; int overlapCount; - ulong address = ((MemoryManager)sender).Translate(e.Address); - ulong size = e.Size; + MultiRange range = ((MemoryManager)sender).GetPhysicalRegions(e.Address, e.Size); - lock (_buffers) + for (int index = 0; index < range.Count; index++) { - overlapCount = _buffers.FindOverlaps(address, size, ref overlaps); - } + MemoryRange subRange = range.GetSubRange(index); - for (int i = 0; i < overlapCount; i++) - { - overlaps[i].Unmapped(address, size); + lock (_buffers) + { + overlapCount = _buffers.FindOverlaps(subRange.Address, subRange.Size, ref overlaps); + } + + for (int i = 0; i < overlapCount; i++) + { + overlaps[i].Unmapped(subRange.Address, subRange.Size); + } } } /// /// Performs address translation of the GPU virtual address, and creates a - /// new buffer, if needed, for the specified range. + /// new buffer, if needed, for the specified contiguous range. /// /// GPU memory manager where the buffer is mapped /// Start GPU virtual address of the buffer /// Size in bytes of the buffer - /// CPU virtual address of the buffer, after address translation - public ulong TranslateAndCreateBuffer(MemoryManager memoryManager, ulong gpuVa, ulong size) + /// Contiguous physical range of the buffer, after address translation + public MultiRange TranslateAndCreateBuffer(MemoryManager memoryManager, ulong gpuVa, ulong size) { if (gpuVa == 0) { - return 0; + return new MultiRange(MemoryManager.PteUnmapped, size); } ulong address = memoryManager.Translate(gpuVa); - if (address == MemoryManager.PteUnmapped) + if (address != MemoryManager.PteUnmapped) { - return 0; + CreateBuffer(address, size); } - CreateBuffer(address, size); + return new MultiRange(address, size); + } - return address; + /// + /// Performs address translation of the GPU virtual address, and creates + /// new buffers, if needed, for the specified range. + /// + /// GPU memory manager where the buffer is mapped + /// Start GPU virtual address of the buffer + /// Size in bytes of the buffer + /// Physical ranges of the buffer, after address translation + public MultiRange TranslateAndCreateMultiBuffers(MemoryManager memoryManager, ulong gpuVa, ulong size) + { + if (gpuVa == 0) + { + return new MultiRange(MemoryManager.PteUnmapped, size); + } + + bool supportsSparse = _context.Capabilities.SupportsSparseBuffer; + + // Fast path not taken for non-contiguous ranges, + // since multi-range buffers are not coalesced, so a buffer that covers + // the entire cached range might not actually exist. + if (memoryManager.VirtualBufferCache.TryGetOrAddRange(gpuVa, size, supportsSparse, out MultiRange range) && + range.Count == 1) + { + return range; + } + + CreateBuffer(range); + + return range; + } + + /// + /// Creates a new buffer for the specified range, if it does not yet exist. + /// This can be used to ensure the existance of a buffer. + /// + /// Physical ranges of memory where the buffer data is located + public void CreateBuffer(MultiRange range) + { + if (range.Count > 1) + { + CreateMultiRangeBuffer(range); + } + else + { + MemoryRange subRange = range.GetSubRange(0); + + if (subRange.Address != MemoryManager.PteUnmapped) + { + CreateBuffer(subRange.Address, subRange.Size); + } + } } /// @@ -118,7 +187,6 @@ namespace Ryujinx.Graphics.Gpu.Memory ulong endAddress = address + size; ulong alignedAddress = address & ~BufferAlignmentMask; - ulong alignedEndAddress = (endAddress + BufferAlignmentMask) & ~BufferAlignmentMask; // The buffer must have the size of at least one page. @@ -130,6 +198,108 @@ namespace Ryujinx.Graphics.Gpu.Memory CreateBufferAligned(alignedAddress, alignedEndAddress - alignedAddress); } + /// + /// Creates a new buffer for the specified range, if it does not yet exist. + /// This can be used to ensure the existance of a buffer. + /// + /// Address of the buffer in memory + /// Size of the buffer in bytes + /// Alignment of the start address of the buffer in bytes + public void CreateBuffer(ulong address, ulong size, ulong alignment) + { + ulong alignmentMask = alignment - 1; + ulong pageAlignmentMask = BufferAlignmentMask; + ulong endAddress = address + size; + + ulong alignedAddress = address & ~alignmentMask; + ulong alignedEndAddress = (endAddress + pageAlignmentMask) & ~pageAlignmentMask; + + // The buffer must have the size of at least one page. + if (alignedEndAddress == alignedAddress) + { + alignedEndAddress += pageAlignmentMask; + } + + CreateBufferAligned(alignedAddress, alignedEndAddress - alignedAddress, alignment); + } + + /// + /// Creates a buffer for a memory region composed of multiple physical ranges, + /// if it does not exist yet. + /// + /// Physical ranges of memory + private void CreateMultiRangeBuffer(MultiRange range) + { + // Ensure all non-contiguous buffer we might use are sparse aligned. + for (int i = 0; i < range.Count; i++) + { + MemoryRange subRange = range.GetSubRange(i); + + if (subRange.Address != MemoryManager.PteUnmapped) + { + CreateBuffer(subRange.Address, subRange.Size, SparseBufferAlignmentSize); + } + } + + // Create sparse buffer. + MultiRangeBuffer[] overlaps = new MultiRangeBuffer[10]; + + int overlapCount = _multiRangeBuffers.FindOverlaps(range, ref overlaps); + + for (int index = 0; index < overlapCount; index++) + { + if (overlaps[index].Range.Contains(range)) + { + return; + } + } + + for (int index = 0; index < overlapCount; index++) + { + if (range.Contains(overlaps[index].Range)) + { + _multiRangeBuffers.Remove(overlaps[index]); + overlaps[index].Dispose(); + } + } + + BufferRange[] storages = new BufferRange[range.Count]; + MemoryRange[] alignedSubRanges = new MemoryRange[range.Count]; + + ulong alignmentMask = SparseBufferAlignmentSize - 1; + + for (int i = 0; i < range.Count; i++) + { + MemoryRange subRange = range.GetSubRange(i); + + if (subRange.Address != MemoryManager.PteUnmapped) + { + ulong endAddress = subRange.Address + subRange.Size; + + ulong alignedAddress = subRange.Address & ~alignmentMask; + ulong alignedEndAddress = (endAddress + alignmentMask) & ~alignmentMask; + ulong alignedSize = alignedEndAddress - alignedAddress; + + Buffer buffer = _buffers.FindFirstOverlap(alignedAddress, alignedSize); + BufferRange bufferRange = buffer.GetRange(alignedAddress, alignedSize, false); + + storages[i] = bufferRange; + alignedSubRanges[i] = new MemoryRange(alignedAddress, alignedSize); + } + else + { + ulong alignedSize = (subRange.Size + alignmentMask) & ~alignmentMask; + + storages[i] = new BufferRange(BufferHandle.Null, 0, (int)alignedSize); + alignedSubRanges[i] = new MemoryRange(MemoryManager.PteUnmapped, alignedSize); + } + } + + MultiRangeBuffer multiRangeBuffer = new(_context, new MultiRange(alignedSubRanges), storages); + + _multiRangeBuffers.Add(multiRangeBuffer); + } + /// /// Performs address translation of the GPU virtual address, and attempts to force /// the buffer in the region as dirty. @@ -150,7 +320,8 @@ namespace Ryujinx.Graphics.Gpu.Memory result.EndGpuAddress < gpuVa + size || result.UnmappedSequence != result.Buffer.UnmappedSequence) { - ulong address = TranslateAndCreateBuffer(memoryManager, gpuVa, size); + MultiRange range = TranslateAndCreateBuffer(memoryManager, gpuVa, size); + ulong address = range.GetSubRange(0).Address; result = new BufferCacheEntry(address, gpuVa, GetBuffer(address, size)); _dirtyCache[gpuVa] = result; @@ -184,7 +355,8 @@ namespace Ryujinx.Graphics.Gpu.Memory result.EndGpuAddress < alignedEndGpuVa || result.UnmappedSequence != result.Buffer.UnmappedSequence) { - ulong address = TranslateAndCreateBuffer(memoryManager, alignedGpuVa, size); + MultiRange range = TranslateAndCreateBuffer(memoryManager, alignedGpuVa, size); + ulong address = range.GetSubRange(0).Address; result = new BufferCacheEntry(address, alignedGpuVa, GetBuffer(address, size)); _modifiedCache[alignedGpuVa] = result; @@ -204,7 +376,8 @@ namespace Ryujinx.Graphics.Gpu.Memory /// Size in bytes of the buffer private void CreateBufferAligned(ulong address, ulong size) { - int overlapsCount = _buffers.FindOverlapsNonOverlapping(address, size, ref _bufferOverlaps); + Buffer[] overlaps = _bufferOverlaps; + int overlapsCount = _buffers.FindOverlapsNonOverlapping(address, size, ref overlaps); if (overlapsCount != 0) { @@ -215,9 +388,12 @@ namespace Ryujinx.Graphics.Gpu.Memory // old buffer(s) to the new buffer. ulong endAddress = address + size; + Buffer overlap0 = overlaps[0]; - if (_bufferOverlaps[0].Address > address || _bufferOverlaps[0].EndAddress < endAddress) + if (overlap0.Address > address || overlap0.EndAddress < endAddress) { + bool anySparseCompatible = false; + // Check if the following conditions are met: // - We have a single overlap. // - The overlap starts at or before the requested range. That is, the overlap happens at the end. @@ -228,23 +404,25 @@ namespace Ryujinx.Graphics.Gpu.Memory // Allowing for 2 pages (rather than just one) is necessary to catch cases where the // range crosses a page, and after alignment, ends having a size of 2 pages. if (overlapsCount == 1 && - address >= _bufferOverlaps[0].Address && - endAddress - _bufferOverlaps[0].EndAddress <= BufferAlignmentSize * 2) + address >= overlap0.Address && + endAddress - overlap0.EndAddress <= BufferAlignmentSize * 2) { // Try to grow the buffer by 1.5x of its current size. // This improves performance in the cases where the buffer is resized often by small amounts. - ulong existingSize = _bufferOverlaps[0].Size; + ulong existingSize = overlap0.Size; ulong growthSize = (existingSize + Math.Min(existingSize >> 1, MaxDynamicGrowthSize)) & ~BufferAlignmentMask; size = Math.Max(size, growthSize); endAddress = address + size; - overlapsCount = _buffers.FindOverlapsNonOverlapping(address, size, ref _bufferOverlaps); + overlapsCount = _buffers.FindOverlapsNonOverlapping(address, size, ref overlaps); } for (int index = 0; index < overlapsCount; index++) { - Buffer buffer = _bufferOverlaps[index]; + Buffer buffer = overlaps[index]; + + anySparseCompatible |= buffer.SparseCompatible; address = Math.Min(address, buffer.Address); endAddress = Math.Max(endAddress, buffer.EndAddress); @@ -257,35 +435,13 @@ namespace Ryujinx.Graphics.Gpu.Memory ulong newSize = endAddress - address; - Buffer newBuffer = new(_context, _physicalMemory, address, newSize, _bufferOverlaps.Take(overlapsCount)); - - lock (_buffers) - { - _buffers.Add(newBuffer); - } - - for (int index = 0; index < overlapsCount; index++) - { - Buffer buffer = _bufferOverlaps[index]; - - int dstOffset = (int)(buffer.Address - newBuffer.Address); - - buffer.CopyTo(newBuffer, dstOffset); - newBuffer.InheritModifiedRanges(buffer); - - buffer.DecrementReferenceCount(); - } - - newBuffer.SynchronizeMemory(address, newSize); - - // Existing buffers were modified, we need to rebind everything. - NotifyBuffersModified?.Invoke(); + CreateBufferAligned(address, newSize, anySparseCompatible, overlaps, overlapsCount); } } else { // No overlap, just create a new buffer. - Buffer buffer = new(_context, _physicalMemory, address, size); + Buffer buffer = new(_context, _physicalMemory, address, size, sparseCompatible: false); lock (_buffers) { @@ -296,6 +452,151 @@ namespace Ryujinx.Graphics.Gpu.Memory ShrinkOverlapsBufferIfNeeded(); } + /// + /// Creates a new buffer for the specified range, if needed. + /// If a buffer where this range can be fully contained already exists, + /// then the creation of a new buffer is not necessary. + /// + /// Address of the buffer in guest memory + /// Size in bytes of the buffer + /// Alignment of the start address of the buffer + private void CreateBufferAligned(ulong address, ulong size, ulong alignment) + { + Buffer[] overlaps = _bufferOverlaps; + int overlapsCount = _buffers.FindOverlapsNonOverlapping(address, size, ref overlaps); + bool sparseAligned = alignment >= SparseBufferAlignmentSize; + + if (overlapsCount != 0) + { + // If the buffer already exists, make sure if covers the entire range, + // and make sure it is properly aligned, otherwise sparse mapping may fail. + + ulong endAddress = address + size; + Buffer overlap0 = overlaps[0]; + + if (overlap0.Address > address || + overlap0.EndAddress < endAddress || + (overlap0.Address & (alignment - 1)) != 0 || + (!overlap0.SparseCompatible && sparseAligned)) + { + // We need to make sure the new buffer is properly aligned. + // However, after the range is aligned, it is possible that it + // overlaps more buffers, so try again after each extension + // and ensure we cover all overlaps. + + int oldOverlapsCount; + + do + { + for (int index = 0; index < overlapsCount; index++) + { + Buffer buffer = overlaps[index]; + + address = Math.Min(address, buffer.Address); + endAddress = Math.Max(endAddress, buffer.EndAddress); + } + + address &= ~(alignment - 1); + + oldOverlapsCount = overlapsCount; + overlapsCount = _buffers.FindOverlapsNonOverlapping(address, endAddress - address, ref overlaps); + } + while (oldOverlapsCount != overlapsCount); + + lock (_buffers) + { + for (int index = 0; index < overlapsCount; index++) + { + _buffers.Remove(overlaps[index]); + } + } + + ulong newSize = endAddress - address; + + CreateBufferAligned(address, newSize, sparseAligned, overlaps, overlapsCount); + } + } + else + { + // No overlap, just create a new buffer. + Buffer buffer = new(_context, _physicalMemory, address, size, sparseAligned); + + lock (_buffers) + { + _buffers.Add(buffer); + } + } + + ShrinkOverlapsBufferIfNeeded(); + } + + /// + /// Creates a new buffer for the specified range, if needed. + /// If a buffer where this range can be fully contained already exists, + /// then the creation of a new buffer is not necessary. + /// + /// Address of the buffer in guest memory + /// Size in bytes of the buffer + /// Indicates if the buffer can be used in a sparse buffer mapping + /// Buffers overlapping the range + /// Total of overlaps + private void CreateBufferAligned(ulong address, ulong size, bool sparseCompatible, Buffer[] overlaps, int overlapsCount) + { + Buffer newBuffer = new Buffer(_context, _physicalMemory, address, size, sparseCompatible, overlaps.Take(overlapsCount)); + + lock (_buffers) + { + _buffers.Add(newBuffer); + } + + for (int index = 0; index < overlapsCount; index++) + { + Buffer buffer = overlaps[index]; + + int dstOffset = (int)(buffer.Address - newBuffer.Address); + + buffer.CopyTo(newBuffer, dstOffset); + newBuffer.InheritModifiedRanges(buffer); + + buffer.DecrementReferenceCount(); + } + + newBuffer.SynchronizeMemory(address, size); + + // Existing buffers were modified, we need to rebind everything. + NotifyBuffersModified?.Invoke(); + + RecreateMultiRangeBuffers(address, size); + } + + /// + /// Recreates all the multi-range buffers that overlaps a given physical memory range. + /// + /// Start address of the range + /// Size of the range in bytes + private void RecreateMultiRangeBuffers(ulong address, ulong size) + { + if ((address & (SparseBufferAlignmentSize - 1)) != 0 || (size & (SparseBufferAlignmentSize - 1)) != 0) + { + return; + } + + MultiRangeBuffer[] overlaps = new MultiRangeBuffer[10]; + + int overlapCount = _multiRangeBuffers.FindOverlaps(address, size, ref overlaps); + + for (int index = 0; index < overlapCount; index++) + { + _multiRangeBuffers.Remove(overlaps[index]); + overlaps[index].Dispose(); + } + + for (int index = 0; index < overlapCount; index++) + { + CreateMultiRangeBuffer(overlaps[index].Range); + } + } + /// /// Resizes the temporary buffer used for range list intersection results, if it has grown too much. /// @@ -319,9 +620,63 @@ namespace Ryujinx.Graphics.Gpu.Memory /// Size in bytes of the copy public void CopyBuffer(MemoryManager memoryManager, ulong srcVa, ulong dstVa, ulong size) { - ulong srcAddress = TranslateAndCreateBuffer(memoryManager, srcVa, size); - ulong dstAddress = TranslateAndCreateBuffer(memoryManager, dstVa, size); + MultiRange srcRange = TranslateAndCreateMultiBuffers(memoryManager, srcVa, size); + MultiRange dstRange = TranslateAndCreateMultiBuffers(memoryManager, dstVa, size); + if (srcRange.Count == 1 && dstRange.Count == 1) + { + CopyBufferSingleRange(memoryManager, srcRange.GetSubRange(0).Address, dstRange.GetSubRange(0).Address, size); + } + else + { + ulong copiedSize = 0; + ulong srcOffset = 0; + ulong dstOffset = 0; + int srcRangeIndex = 0; + int dstRangeIndex = 0; + + while (copiedSize < size) + { + if (srcRange.GetSubRange(srcRangeIndex).Size == srcOffset) + { + srcRangeIndex++; + srcOffset = 0; + } + + if (dstRange.GetSubRange(dstRangeIndex).Size == dstOffset) + { + dstRangeIndex++; + dstOffset = 0; + } + + MemoryRange srcSubRange = srcRange.GetSubRange(srcRangeIndex); + MemoryRange dstSubRange = dstRange.GetSubRange(dstRangeIndex); + + ulong srcSize = srcSubRange.Size - srcOffset; + ulong dstSize = dstSubRange.Size - dstOffset; + ulong copySize = Math.Min(srcSize, dstSize); + + CopyBufferSingleRange(memoryManager, srcSubRange.Address + srcOffset, dstSubRange.Address + dstOffset, copySize); + + srcOffset += copySize; + dstOffset += copySize; + copiedSize += copySize; + } + } + } + + /// + /// Copy a buffer data from a given address to another. + /// + /// + /// This does a GPU side copy. + /// + /// GPU memory manager where the buffer is mapped + /// Physical address of the copy source + /// Physical address of the copy destination + /// Size in bytes of the copy + private void CopyBufferSingleRange(MemoryManager memoryManager, ulong srcAddress, ulong dstAddress, ulong size) + { Buffer srcBuffer = GetBuffer(srcAddress, size); Buffer dstBuffer = GetBuffer(dstAddress, size); @@ -360,39 +715,98 @@ namespace Ryujinx.Graphics.Gpu.Memory /// Value to be written into the buffer public void ClearBuffer(MemoryManager memoryManager, ulong gpuVa, ulong size, uint value) { - ulong address = TranslateAndCreateBuffer(memoryManager, gpuVa, size); + MultiRange range = TranslateAndCreateMultiBuffers(memoryManager, gpuVa, size); - Buffer buffer = GetBuffer(address, size); + for (int index = 0; index < range.Count; index++) + { + MemoryRange subRange = range.GetSubRange(index); + Buffer buffer = GetBuffer(subRange.Address, subRange.Size); - int offset = (int)(address - buffer.Address); + int offset = (int)(subRange.Address - buffer.Address); - _context.Renderer.Pipeline.ClearBuffer(buffer.Handle, offset, (int)size, value); + _context.Renderer.Pipeline.ClearBuffer(buffer.Handle, offset, (int)subRange.Size, value); - memoryManager.Physical.FillTrackedResource(address, size, value, ResourceKind.Buffer); + memoryManager.Physical.FillTrackedResource(subRange.Address, subRange.Size, value, ResourceKind.Buffer); + } } /// - /// Gets a buffer sub-range from a start address til a page boundary after the given size. + /// Gets a buffer sub-range starting at a given memory address, aligned to the next page boundary. /// - /// Start address of the memory range - /// Size in bytes of the memory range + /// Physical regions of memory where the buffer is mapped /// Whether the buffer will be written to by this use /// The buffer sub-range starting at the given memory address - public BufferRange GetBufferRangeAligned(ulong address, ulong size, bool write = false) + public BufferRange GetBufferRangeAligned(MultiRange range, bool write = false) { - return GetBuffer(address, size, write).GetRangeAligned(address, size, write); + if (range.Count > 1) + { + return GetBuffer(range, write).GetRange(range); + } + else + { + MemoryRange subRange = range.GetSubRange(0); + return GetBuffer(subRange.Address, subRange.Size, write).GetRangeAligned(subRange.Address, subRange.Size, write); + } } /// /// Gets a buffer sub-range for a given memory range. /// - /// Start address of the memory range - /// Size in bytes of the memory range + /// Physical regions of memory where the buffer is mapped /// Whether the buffer will be written to by this use /// The buffer sub-range for the given range - public BufferRange GetBufferRange(ulong address, ulong size, bool write = false) + public BufferRange GetBufferRange(MultiRange range, bool write = false) { - return GetBuffer(address, size, write).GetRange(address, size, write); + if (range.Count > 1) + { + return GetBuffer(range, write).GetRange(range); + } + else + { + MemoryRange subRange = range.GetSubRange(0); + return GetBuffer(subRange.Address, subRange.Size, write).GetRange(subRange.Address, subRange.Size, write); + } + } + + /// + /// Gets a buffer for a given memory range. + /// A buffer overlapping with the specified range is assumed to already exist on the cache. + /// + /// Physical regions of memory where the buffer is mapped + /// Whether the buffer will be written to by this use + /// The buffer where the range is fully contained + private MultiRangeBuffer GetBuffer(MultiRange range, bool write = false) + { + for (int i = 0; i < range.Count; i++) + { + MemoryRange subRange = range.GetSubRange(i); + + Buffer subBuffer = _buffers.FindFirstOverlap(subRange.Address, subRange.Size); + + subBuffer.SynchronizeMemory(subRange.Address, subRange.Size); + + if (write) + { + subBuffer.SignalModified(subRange.Address, subRange.Size); + } + } + + MultiRangeBuffer[] overlaps = new MultiRangeBuffer[10]; + + int overlapCount = _multiRangeBuffers.FindOverlaps(range, ref overlaps); + + MultiRangeBuffer buffer = null; + + for (int i = 0; i < overlapCount; i++) + { + if (overlaps[i].Range.Contains(range)) + { + buffer = overlaps[i]; + break; + } + } + + return buffer; } /// @@ -426,12 +840,33 @@ namespace Ryujinx.Graphics.Gpu.Memory return buffer; } + /// + /// Performs guest to host memory synchronization of a given memory range. + /// + /// Physical regions of memory where the buffer is mapped + public void SynchronizeBufferRange(MultiRange range) + { + if (range.Count == 1) + { + MemoryRange subRange = range.GetSubRange(0); + SynchronizeBufferRange(subRange.Address, subRange.Size); + } + else + { + for (int index = 0; index < range.Count; index++) + { + MemoryRange subRange = range.GetSubRange(index); + SynchronizeBufferRange(subRange.Address, subRange.Size); + } + } + } + /// /// Performs guest to host memory synchronization of a given memory range. /// /// Start address of the memory range /// Size in bytes of the memory range - public void SynchronizeBufferRange(ulong address, ulong size) + private void SynchronizeBufferRange(ulong address, ulong size) { if (size != 0) { @@ -491,7 +926,7 @@ namespace Ryujinx.Graphics.Gpu.Memory /// /// Disposes all buffers in the cache. - /// It's an error to use the buffer manager after disposal. + /// It's an error to use the buffer cache after disposal. /// public void Dispose() { diff --git a/src/Ryujinx.Graphics.Gpu/Memory/BufferCacheEntry.cs b/src/Ryujinx.Graphics.Gpu/Memory/BufferCacheEntry.cs index fa38b54e7..ef919c2b0 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/BufferCacheEntry.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/BufferCacheEntry.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Gpu.Memory +namespace Ryujinx.Graphics.Gpu.Memory { /// /// A cached entry for easily locating a buffer that is used often internally. diff --git a/src/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs b/src/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs index 8e9b4b858..c65602b5b 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs @@ -1,8 +1,9 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Image; using Ryujinx.Graphics.Gpu.Shader; using Ryujinx.Graphics.Shader; +using Ryujinx.Memory.Range; using System; using System.Collections.Generic; using System.Runtime.CompilerServices; @@ -62,18 +63,19 @@ namespace Ryujinx.Graphics.Gpu.Memory Bindings = new BufferDescriptor[count]; Buffers = new BufferBounds[count]; Unaligned = new bool[count]; + + Buffers.AsSpan().Fill(new BufferBounds(new MultiRange(MemoryManager.PteUnmapped, 0UL))); } /// /// Sets the region of a buffer at a given slot. /// /// Buffer slot - /// Region virtual address - /// Region size in bytes + /// Physical memory regions where the buffer is mapped /// Buffer usage flags - public void SetBounds(int index, ulong address, ulong size, BufferUsageFlags flags = BufferUsageFlags.None) + public void SetBounds(int index, MultiRange range, BufferUsageFlags flags = BufferUsageFlags.None) { - Buffers[index] = new BufferBounds(address, size, flags); + Buffers[index] = new BufferBounds(range, flags); } /// @@ -120,6 +122,7 @@ namespace Ryujinx.Graphics.Gpu.Memory _context = context; _channel = channel; + _indexBuffer.Range = new MultiRange(MemoryManager.PteUnmapped, 0UL); _vertexBuffers = new VertexBuffer[Constants.TotalVertexBuffers]; _transformFeedbackBuffers = new BufferBounds[Constants.TotalTransformFeedbackBuffers]; @@ -150,10 +153,9 @@ namespace Ryujinx.Graphics.Gpu.Memory /// Type of each index buffer element public void SetIndexBuffer(ulong gpuVa, ulong size, IndexType type) { - ulong address = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size); + MultiRange range = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size); - _indexBuffer.Address = address; - _indexBuffer.Size = size; + _indexBuffer.Range = range; _indexBuffer.Type = type; _indexBufferDirty = true; @@ -181,16 +183,15 @@ namespace Ryujinx.Graphics.Gpu.Memory /// Vertex divisor of the buffer, for instanced draws public void SetVertexBuffer(int index, ulong gpuVa, ulong size, int stride, int divisor) { - ulong address = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size); + MultiRange range = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size); - _vertexBuffers[index].Address = address; - _vertexBuffers[index].Size = size; + _vertexBuffers[index].Range = range; _vertexBuffers[index].Stride = stride; _vertexBuffers[index].Divisor = divisor; _vertexBuffersDirty = true; - if (address != 0) + if (!range.IsUnmapped) { _vertexBuffersEnableMask |= 1u << index; } @@ -209,9 +210,9 @@ namespace Ryujinx.Graphics.Gpu.Memory /// Size in bytes of the transform feedback buffer public void SetTransformFeedbackBuffer(int index, ulong gpuVa, ulong size) { - ulong address = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size); + MultiRange range = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateMultiBuffers(_channel.MemoryManager, gpuVa, size); - _transformFeedbackBuffers[index] = new BufferBounds(address, size); + _transformFeedbackBuffers[index] = new BufferBounds(range); _transformFeedbackBuffersDirty = true; } @@ -256,9 +257,9 @@ namespace Ryujinx.Graphics.Gpu.Memory gpuVa = BitUtils.AlignDown(gpuVa, (ulong)_context.Capabilities.StorageBufferOffsetAlignment); - ulong address = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size); + MultiRange range = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateMultiBuffers(_channel.MemoryManager, gpuVa, size); - _cpStorageBuffers.SetBounds(index, address, size, flags); + _cpStorageBuffers.SetBounds(index, range, flags); } /// @@ -280,15 +281,14 @@ namespace Ryujinx.Graphics.Gpu.Memory gpuVa = BitUtils.AlignDown(gpuVa, (ulong)_context.Capabilities.StorageBufferOffsetAlignment); - ulong address = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size); + MultiRange range = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateMultiBuffers(_channel.MemoryManager, gpuVa, size); - if (buffers.Buffers[index].Address != address || - buffers.Buffers[index].Size != size) + if (!buffers.Buffers[index].Range.Equals(range)) { _gpStorageBuffersDirty = true; } - buffers.SetBounds(index, address, size, flags); + buffers.SetBounds(index, range, flags); } /// @@ -300,9 +300,9 @@ namespace Ryujinx.Graphics.Gpu.Memory /// Size in bytes of the storage buffer public void SetComputeUniformBuffer(int index, ulong gpuVa, ulong size) { - ulong address = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size); + MultiRange range = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size); - _cpUniformBuffers.SetBounds(index, address, size); + _cpUniformBuffers.SetBounds(index, range); } /// @@ -315,9 +315,9 @@ namespace Ryujinx.Graphics.Gpu.Memory /// Size in bytes of the storage buffer public void SetGraphicsUniformBuffer(int stage, int index, ulong gpuVa, ulong size) { - ulong address = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size); + MultiRange range = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size); - _gpUniformBuffers[stage].SetBounds(index, address, size); + _gpUniformBuffers[stage].SetBounds(index, range); _gpUniformBuffersDirty = true; } @@ -379,7 +379,7 @@ namespace Ryujinx.Graphics.Gpu.Memory for (int i = 0; i < _cpUniformBuffers.Buffers.Length; i++) { - if (_cpUniformBuffers.Buffers[i].Address != 0) + if (!_cpUniformBuffers.Buffers[i].IsUnmapped) { mask |= 1u << i; } @@ -399,7 +399,7 @@ namespace Ryujinx.Graphics.Gpu.Memory for (int i = 0; i < _gpUniformBuffers[stage].Buffers.Length; i++) { - if (_gpUniformBuffers[stage].Buffers[i].Address != 0) + if (!_gpUniformBuffers[stage].Buffers[i].IsUnmapped) { mask |= 1u << i; } @@ -415,7 +415,7 @@ namespace Ryujinx.Graphics.Gpu.Memory /// The uniform buffer address, or an undefined value if the buffer is not currently bound public ulong GetComputeUniformBufferAddress(int index) { - return _cpUniformBuffers.Buffers[index].Address; + return _cpUniformBuffers.Buffers[index].Range.GetSubRange(0).Address; } /// @@ -426,7 +426,7 @@ namespace Ryujinx.Graphics.Gpu.Memory /// The uniform buffer address, or an undefined value if the buffer is not currently bound public ulong GetGraphicsUniformBufferAddress(int stage, int index) { - return _gpUniformBuffers[stage].Buffers[index].Address; + return _gpUniformBuffers[stage].Buffers[index].Range.GetSubRange(0).Address; } /// @@ -477,7 +477,7 @@ namespace Ryujinx.Graphics.Gpu.Memory foreach (var binding in _bufferTextures) { var isStore = binding.BindingInfo.Flags.HasFlag(TextureUsageFlags.ImageStore); - var range = _channel.MemoryManager.Physical.BufferCache.GetBufferRange(binding.Address, binding.Size, isStore); + var range = _channel.MemoryManager.Physical.BufferCache.GetBufferRange(binding.Range, isStore); binding.Texture.SetStorage(range); // The texture must be rebound to use the new storage if it was updated. @@ -511,16 +511,16 @@ namespace Ryujinx.Graphics.Gpu.Memory { _indexBufferDirty = false; - if (_indexBuffer.Address != 0) + if (!_indexBuffer.Range.IsUnmapped) { - BufferRange buffer = bufferCache.GetBufferRange(_indexBuffer.Address, _indexBuffer.Size); + BufferRange buffer = bufferCache.GetBufferRange(_indexBuffer.Range); _context.Renderer.Pipeline.SetIndexBuffer(buffer, _indexBuffer.Type); } } - else if (_indexBuffer.Address != 0) + else if (!_indexBuffer.Range.IsUnmapped) { - bufferCache.SynchronizeBufferRange(_indexBuffer.Address, _indexBuffer.Size); + bufferCache.SynchronizeBufferRange(_indexBuffer.Range); } } else if (_rebind) @@ -540,12 +540,12 @@ namespace Ryujinx.Graphics.Gpu.Memory { VertexBuffer vb = _vertexBuffers[index]; - if (vb.Address == 0) + if (vb.Range.IsUnmapped) { continue; } - BufferRange buffer = bufferCache.GetBufferRange(vb.Address, vb.Size); + BufferRange buffer = bufferCache.GetBufferRange(vb.Range); vertexBuffers[index] = new VertexBufferDescriptor(buffer, vb.Stride, vb.Divisor); } @@ -558,12 +558,12 @@ namespace Ryujinx.Graphics.Gpu.Memory { VertexBuffer vb = _vertexBuffers[index]; - if (vb.Address == 0) + if (vb.Range.IsUnmapped) { continue; } - bufferCache.SynchronizeBufferRange(vb.Address, vb.Size); + bufferCache.SynchronizeBufferRange(vb.Range); } } @@ -579,13 +579,13 @@ namespace Ryujinx.Graphics.Gpu.Memory { BufferBounds tfb = _transformFeedbackBuffers[index]; - if (tfb.Address == 0) + if (tfb.IsUnmapped) { tfbs[index] = BufferRange.Empty; continue; } - tfbs[index] = bufferCache.GetBufferRange(tfb.Address, tfb.Size, write: true); + tfbs[index] = bufferCache.GetBufferRange(tfb.Range, write: true); } _context.Renderer.Pipeline.SetTransformFeedbackBuffers(tfbs); @@ -600,21 +600,39 @@ namespace Ryujinx.Graphics.Gpu.Memory { BufferBounds tfb = _transformFeedbackBuffers[index]; - if (tfb.Address == 0) + if (tfb.IsUnmapped) { buffers[index] = new BufferAssignment(index, BufferRange.Empty); } else { - ulong endAddress = tfb.Address + tfb.Size; - ulong address = BitUtils.AlignDown(tfb.Address, (ulong)alignment); - ulong size = endAddress - address; + MultiRange range = tfb.Range; + ulong address0 = range.GetSubRange(0).Address; + ulong address = BitUtils.AlignDown(address0, (ulong)alignment); - int tfeOffset = ((int)tfb.Address & (alignment - 1)) / 4; + if (range.Count == 1) + { + range = new MultiRange(address, range.GetSubRange(0).Size + (address0 - address)); + } + else + { + MemoryRange[] subRanges = new MemoryRange[range.Count]; + + subRanges[0] = new MemoryRange(address, range.GetSubRange(0).Size + (address0 - address)); + + for (int i = 1; i < range.Count; i++) + { + subRanges[i] = range.GetSubRange(i); + } + + range = new MultiRange(subRanges); + } + + int tfeOffset = ((int)address0 & (alignment - 1)) / 4; _context.SupportBufferUpdater.SetTfeOffset(index, tfeOffset); - buffers[index] = new BufferAssignment(index, bufferCache.GetBufferRange(address, size, write: true)); + buffers[index] = new BufferAssignment(index, bufferCache.GetBufferRange(range, write: true)); } } @@ -627,12 +645,12 @@ namespace Ryujinx.Graphics.Gpu.Memory { BufferBounds tfb = _transformFeedbackBuffers[index]; - if (tfb.Address == 0) + if (tfb.IsUnmapped) { continue; } - bufferCache.SynchronizeBufferRange(tfb.Address, tfb.Size); + bufferCache.SynchronizeBufferRange(tfb.Range); } } @@ -688,12 +706,12 @@ namespace Ryujinx.Graphics.Gpu.Memory BufferBounds bounds = buffers.Buffers[bindingInfo.Slot]; - if (bounds.Address != 0) + if (!bounds.IsUnmapped) { var isWrite = bounds.Flags.HasFlag(BufferUsageFlags.Write); var range = isStorage - ? bufferCache.GetBufferRangeAligned(bounds.Address, bounds.Size, isWrite) - : bufferCache.GetBufferRange(bounds.Address, bounds.Size); + ? bufferCache.GetBufferRangeAligned(bounds.Range, isWrite) + : bufferCache.GetBufferRange(bounds.Range); ranges[rangesCount++] = new BufferAssignment(bindingInfo.Binding, range); } @@ -725,12 +743,12 @@ namespace Ryujinx.Graphics.Gpu.Memory BufferBounds bounds = buffers.Buffers[bindingInfo.Slot]; - if (bounds.Address != 0) + if (!bounds.IsUnmapped) { var isWrite = bounds.Flags.HasFlag(BufferUsageFlags.Write); var range = isStorage - ? bufferCache.GetBufferRangeAligned(bounds.Address, bounds.Size, isWrite) - : bufferCache.GetBufferRange(bounds.Address, bounds.Size); + ? bufferCache.GetBufferRangeAligned(bounds.Range, isWrite) + : bufferCache.GetBufferRange(bounds.Range); ranges[rangesCount++] = new BufferAssignment(bindingInfo.Binding, range); } @@ -778,12 +796,12 @@ namespace Ryujinx.Graphics.Gpu.Memory BufferBounds bounds = buffers.Buffers[binding.Slot]; - if (bounds.Address == 0) + if (bounds.IsUnmapped) { continue; } - _channel.MemoryManager.Physical.BufferCache.SynchronizeBufferRange(bounds.Address, bounds.Size); + _channel.MemoryManager.Physical.BufferCache.SynchronizeBufferRange(bounds.Range); } } } @@ -793,23 +811,21 @@ namespace Ryujinx.Graphics.Gpu.Memory /// /// Shader stage accessing the texture /// Buffer texture - /// Address of the buffer in memory - /// Size of the buffer in bytes + /// Physical ranges of memory where the buffer texture data is located /// Binding info for the buffer texture /// Format of the buffer texture /// Whether the binding is for an image or a sampler public void SetBufferTextureStorage( ShaderStage stage, ITexture texture, - ulong address, - ulong size, + MultiRange range, TextureBindingInfo bindingInfo, Format format, bool isImage) { - _channel.MemoryManager.Physical.BufferCache.CreateBuffer(address, size); + _channel.MemoryManager.Physical.BufferCache.CreateBuffer(range); - _bufferTextures.Add(new BufferTextureBinding(stage, texture, address, size, bindingInfo, format, isImage)); + _bufferTextures.Add(new BufferTextureBinding(stage, texture, range, bindingInfo, format, isImage)); } /// diff --git a/src/Ryujinx.Graphics.Gpu/Memory/BufferMigration.cs b/src/Ryujinx.Graphics.Gpu/Memory/BufferMigration.cs index e020c0c39..0a5268031 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/BufferMigration.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/BufferMigration.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.Gpu.Memory { diff --git a/src/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs b/src/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs index 160a9aff7..6ada8a4b2 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Pools; +using Ryujinx.Common.Pools; using Ryujinx.Memory.Range; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.Graphics.Gpu/Memory/BufferTextureBinding.cs b/src/Ryujinx.Graphics.Gpu/Memory/BufferTextureBinding.cs index b7a0e7264..bf0beffa2 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/BufferTextureBinding.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/BufferTextureBinding.cs @@ -1,6 +1,7 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Image; using Ryujinx.Graphics.Shader; +using Ryujinx.Memory.Range; namespace Ryujinx.Graphics.Gpu.Memory { @@ -20,14 +21,9 @@ namespace Ryujinx.Graphics.Gpu.Memory public ITexture Texture { get; } /// - /// The base address of the buffer binding. + /// Physical ranges of memory where the buffer texture data is located. /// - public ulong Address { get; } - - /// - /// The size of the buffer binding in bytes. - /// - public ulong Size { get; } + public MultiRange Range { get; } /// /// The image or sampler binding info for the buffer texture. @@ -49,24 +45,21 @@ namespace Ryujinx.Graphics.Gpu.Memory /// /// Shader stage accessing the texture /// Buffer texture - /// Base address - /// Size in bytes + /// Physical ranges of memory where the buffer texture data is located /// Binding info /// Binding format /// Whether the binding is for an image or a sampler public BufferTextureBinding( ShaderStage stage, ITexture texture, - ulong address, - ulong size, + MultiRange range, TextureBindingInfo bindingInfo, Format format, bool isImage) { Stage = stage; Texture = texture; - Address = address; - Size = size; + Range = range; BindingInfo = bindingInfo; Format = format; IsImage = isImage; diff --git a/src/Ryujinx.Graphics.Gpu/Memory/CounterCache.cs b/src/Ryujinx.Graphics.Gpu/Memory/CounterCache.cs index 6dcc52cb6..24966df41 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/CounterCache.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/CounterCache.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using System.Collections.Generic; namespace Ryujinx.Graphics.Gpu.Memory diff --git a/src/Ryujinx.Graphics.Gpu/Memory/GpuRegionHandle.cs b/src/Ryujinx.Graphics.Gpu/Memory/GpuRegionHandle.cs index 9f73de4e2..bdb7cf2c2 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/GpuRegionHandle.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/GpuRegionHandle.cs @@ -1,4 +1,4 @@ -using Ryujinx.Memory.Tracking; +using Ryujinx.Memory.Tracking; using System; namespace Ryujinx.Graphics.Gpu.Memory diff --git a/src/Ryujinx.Graphics.Gpu/Memory/IndexBuffer.cs b/src/Ryujinx.Graphics.Gpu/Memory/IndexBuffer.cs index c72fa50e5..04114a955 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/IndexBuffer.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/IndexBuffer.cs @@ -1,4 +1,5 @@ using Ryujinx.Graphics.GAL; +using Ryujinx.Memory.Range; namespace Ryujinx.Graphics.Gpu.Memory { @@ -7,9 +8,7 @@ namespace Ryujinx.Graphics.Gpu.Memory /// struct IndexBuffer { - public ulong Address; - public ulong Size; - + public MultiRange Range; public IndexType Type; } } diff --git a/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs b/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs index 6af12de11..74d527051 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs @@ -39,6 +39,11 @@ namespace Ryujinx.Graphics.Gpu.Memory /// internal PhysicalMemory Physical { get; } + /// + /// Virtual buffer cache. + /// + internal VirtualBufferCache VirtualBufferCache { get; } + /// /// Cache of GPU counters. /// @@ -51,10 +56,12 @@ namespace Ryujinx.Graphics.Gpu.Memory internal MemoryManager(PhysicalMemory physicalMemory) { Physical = physicalMemory; + VirtualBufferCache = new VirtualBufferCache(this); CounterCache = new CounterCache(); _pageTable = new ulong[PtLvl0Size][]; MemoryUnmapped += Physical.TextureCache.MemoryUnmappedHandler; MemoryUnmapped += Physical.BufferCache.MemoryUnmappedHandler; + MemoryUnmapped += VirtualBufferCache.MemoryUnmappedHandler; MemoryUnmapped += CounterCache.MemoryUnmappedHandler; } @@ -322,49 +329,6 @@ namespace Ryujinx.Graphics.Gpu.Memory } } - /// - /// Writes data to GPU mapped memory, stopping at the first unmapped page at the memory region, if any. - /// - /// GPU virtual address to write the data into - /// The data to be written - public void WriteMapped(ulong va, ReadOnlySpan data) - { - if (IsContiguous(va, data.Length)) - { - Physical.Write(Translate(va), data); - } - else - { - int offset = 0, size; - - if ((va & PageMask) != 0) - { - ulong pa = Translate(va); - - size = Math.Min(data.Length, (int)PageSize - (int)(va & PageMask)); - - if (pa != PteUnmapped && Physical.IsMapped(pa)) - { - Physical.Write(pa, data[..size]); - } - - offset += size; - } - - for (; offset < data.Length; offset += size) - { - ulong pa = Translate(va + (ulong)offset); - - size = Math.Min(data.Length - offset, (int)PageSize); - - if (pa != PteUnmapped && Physical.IsMapped(pa)) - { - Physical.Write(pa, data.Slice(offset, size)); - } - } - } - } - /// /// Runs remap actions that are added to an unmap event. /// These must run after the mapping completes. @@ -508,6 +472,11 @@ namespace Ryujinx.Graphics.Gpu.Memory regionSize += Math.Min(endVa - va, PageSize); } + if (regions.Count == 0) + { + return new MultiRange(regionStart, regionSize); + } + regions.Add(new MemoryRange(regionStart, regionSize)); return new MultiRange(regions.ToArray()); diff --git a/src/Ryujinx.Graphics.Gpu/Memory/MultiRangeBuffer.cs b/src/Ryujinx.Graphics.Gpu/Memory/MultiRangeBuffer.cs new file mode 100644 index 000000000..e039a7a43 --- /dev/null +++ b/src/Ryujinx.Graphics.Gpu/Memory/MultiRangeBuffer.cs @@ -0,0 +1,60 @@ +using Ryujinx.Graphics.GAL; +using Ryujinx.Memory.Range; +using System; + +namespace Ryujinx.Graphics.Gpu.Memory +{ + /// + /// Buffer, used to store vertex and index data, uniform and storage buffers, and others. + /// + class MultiRangeBuffer : IMultiRangeItem, IDisposable + { + private readonly GpuContext _context; + + /// + /// Host buffer handle. + /// + public BufferHandle Handle { get; } + + /// + /// Range of memory where the data is located. + /// + public MultiRange Range { get; } + + /// + /// Creates a new instance of the buffer. + /// + /// GPU context that the buffer belongs to + /// Range of memory where the data is mapped + /// Backing memory for the buffers + public MultiRangeBuffer(GpuContext context, MultiRange range, ReadOnlySpan storages) + { + _context = context; + Range = range; + Handle = context.Renderer.CreateBufferSparse(storages); + } + + /// + /// Gets a sub-range from the buffer. + /// + /// + /// This can be used to bind and use sub-ranges of the buffer on the host API. + /// + /// Range of memory where the data is mapped + /// The buffer sub-range + public BufferRange GetRange(MultiRange range) + { + int offset = Range.FindOffset(range); + + return new BufferRange(Handle, offset, (int)range.GetSize()); + } + + /// + /// Disposes the host buffer. + /// + public void Dispose() + { + _context.Renderer.DeleteBuffer(Handle); + } + } +} diff --git a/src/Ryujinx.Graphics.Gpu/Memory/MultiRangeWritableBlock.cs b/src/Ryujinx.Graphics.Gpu/Memory/MultiRangeWritableBlock.cs index 155dda7bd..9236886d8 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/MultiRangeWritableBlock.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/MultiRangeWritableBlock.cs @@ -1,4 +1,4 @@ -using Ryujinx.Memory; +using Ryujinx.Memory; using Ryujinx.Memory.Range; using System; diff --git a/src/Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs b/src/Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs index 1ca6071bd..69a3054a4 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs @@ -1,4 +1,5 @@ using Ryujinx.Cpu; +using Ryujinx.Graphics.Device; using Ryujinx.Graphics.Gpu.Image; using Ryujinx.Graphics.Gpu.Shader; using Ryujinx.Memory; @@ -82,6 +83,15 @@ namespace Ryujinx.Graphics.Gpu.Memory } } + /// + /// Creates a new device memory manager. + /// + /// The memory manager + public DeviceMemoryManager CreateDeviceMemoryManager() + { + return new DeviceMemoryManager(_cpuMemory); + } + /// /// Gets a host pointer for a given range of application memory. /// If the memory region is not a single contiguous block, this method returns 0. diff --git a/src/Ryujinx.Graphics.Gpu/Memory/SupportBufferUpdater.cs b/src/Ryujinx.Graphics.Gpu/Memory/SupportBufferUpdater.cs index fb141db42..fc444f49c 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/SupportBufferUpdater.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/SupportBufferUpdater.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Shader; using System; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Graphics.Gpu/Memory/UnmapEventArgs.cs b/src/Ryujinx.Graphics.Gpu/Memory/UnmapEventArgs.cs index 837b5aab4..83fb1fcee 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/UnmapEventArgs.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/UnmapEventArgs.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; namespace Ryujinx.Graphics.Gpu.Memory diff --git a/src/Ryujinx.Graphics.Gpu/Memory/VertexBuffer.cs b/src/Ryujinx.Graphics.Gpu/Memory/VertexBuffer.cs index ac334881d..206e1b48c 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/VertexBuffer.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/VertexBuffer.cs @@ -1,3 +1,5 @@ +using Ryujinx.Memory.Range; + namespace Ryujinx.Graphics.Gpu.Memory { /// @@ -5,8 +7,7 @@ namespace Ryujinx.Graphics.Gpu.Memory /// struct VertexBuffer { - public ulong Address; - public ulong Size; + public MultiRange Range; public int Stride; public int Divisor; } diff --git a/src/Ryujinx.Graphics.Gpu/Memory/VirtualBufferCache.cs b/src/Ryujinx.Graphics.Gpu/Memory/VirtualBufferCache.cs new file mode 100644 index 000000000..858c5e3b0 --- /dev/null +++ b/src/Ryujinx.Graphics.Gpu/Memory/VirtualBufferCache.cs @@ -0,0 +1,238 @@ +using Ryujinx.Memory.Range; +using System; +using System.Collections.Concurrent; +using System.Threading; + +namespace Ryujinx.Graphics.Gpu.Memory +{ + /// + /// Virtual buffer cache. + /// + class VirtualBufferCache + { + private readonly MemoryManager _memoryManager; + + /// + /// Represents a GPU virtual memory range. + /// + private readonly struct VirtualRange : IRange + { + /// + /// GPU virtual address where the range starts. + /// + public ulong Address { get; } + + /// + /// Size of the range in bytes. + /// + public ulong Size { get; } + + /// + /// GPU virtual address where the range ends. + /// + public ulong EndAddress => Address + Size; + + /// + /// Physical regions where the GPU virtual region is mapped. + /// + public MultiRange Range { get; } + + /// + /// Creates a new virtual memory range. + /// + /// GPU virtual address where the range starts + /// Size of the range in bytes + /// Physical regions where the GPU virtual region is mapped + public VirtualRange(ulong address, ulong size, MultiRange range) + { + Address = address; + Size = size; + Range = range; + } + + /// + /// Checks if a given range overlaps with the buffer. + /// + /// Start address of the range + /// Size in bytes of the range + /// True if the range overlaps, false otherwise + public bool OverlapsWith(ulong address, ulong size) + { + return Address < address + size && address < EndAddress; + } + } + + private readonly RangeList _virtualRanges; + private VirtualRange[] _virtualRangeOverlaps; + private readonly ConcurrentQueue _deferredUnmaps; + private int _hasDeferredUnmaps; + + /// + /// Creates a new instance of the virtual buffer cache. + /// + /// Memory manager that the virtual buffer cache belongs to + public VirtualBufferCache(MemoryManager memoryManager) + { + _memoryManager = memoryManager; + _virtualRanges = new RangeList(); + _virtualRangeOverlaps = new VirtualRange[BufferCache.OverlapsBufferInitialCapacity]; + _deferredUnmaps = new ConcurrentQueue(); + } + + /// + /// Handles removal of buffers written to a memory region being unmapped. + /// + /// Sender object + /// Event arguments + public void MemoryUnmappedHandler(object sender, UnmapEventArgs e) + { + void EnqueueUnmap() + { + _deferredUnmaps.Enqueue(new VirtualRange(e.Address, e.Size, default)); + + Interlocked.Exchange(ref _hasDeferredUnmaps, 1); + } + + e.AddRemapAction(EnqueueUnmap); + } + + /// + /// Tries to get a existing, cached physical range for the specified virtual region. + /// If no cached range is found, a new one is created and added. + /// + /// GPU virtual address to get the physical range from + /// Size in bytes of the region + /// Indicates host support for sparse buffer mapping of non-contiguous ranges + /// Physical range for the specified GPU virtual region + /// True if the range already existed, false if a new one was created and added + public bool TryGetOrAddRange(ulong gpuVa, ulong size, bool supportsSparse, out MultiRange range) + { + VirtualRange[] overlaps = _virtualRangeOverlaps; + int overlapsCount; + + if (Interlocked.Exchange(ref _hasDeferredUnmaps, 0) != 0) + { + while (_deferredUnmaps.TryDequeue(out VirtualRange unmappedRange)) + { + overlapsCount = _virtualRanges.FindOverlapsNonOverlapping(unmappedRange.Address, unmappedRange.Size, ref overlaps); + + for (int index = 0; index < overlapsCount; index++) + { + _virtualRanges.Remove(overlaps[index]); + } + } + } + + bool found = false; + + ulong originalVa = gpuVa; + + overlapsCount = _virtualRanges.FindOverlapsNonOverlapping(gpuVa, size, ref overlaps); + + if (overlapsCount != 0) + { + // The virtual range already exists. We just need to check if our range fits inside + // the existing one, and if not, we must extend the existing one. + + ulong endAddress = gpuVa + size; + VirtualRange overlap0 = overlaps[0]; + + if (overlap0.Address > gpuVa || overlap0.EndAddress < endAddress) + { + for (int index = 0; index < overlapsCount; index++) + { + VirtualRange virtualRange = overlaps[index]; + + gpuVa = Math.Min(gpuVa, virtualRange.Address); + endAddress = Math.Max(endAddress, virtualRange.EndAddress); + + _virtualRanges.Remove(virtualRange); + } + + ulong newSize = endAddress - gpuVa; + MultiRange newRange = _memoryManager.GetPhysicalRegions(gpuVa, newSize); + + _virtualRanges.Add(new(gpuVa, newSize, newRange)); + + range = newRange.Slice(originalVa - gpuVa, size); + } + else + { + found = true; + range = overlap0.Range.Slice(gpuVa - overlap0.Address, size); + } + } + else + { + // No overlap, just create a new virtual range. + range = _memoryManager.GetPhysicalRegions(gpuVa, size); + + VirtualRange virtualRange = new(gpuVa, size, range); + + _virtualRanges.Add(virtualRange); + } + + ShrinkOverlapsBufferIfNeeded(); + + // If the the range is not properly aligned for sparse mapping, + // or if the host does not support sparse mapping, let's just + // force it to a single range. + // This might cause issues in some applications that uses sparse + // mappings. + if (!IsSparseAligned(range) || !supportsSparse) + { + range = new MultiRange(range.GetSubRange(0).Address, size); + } + + return found; + } + + /// + /// Checks if the physical memory ranges are valid for sparse mapping, + /// which requires all sub-ranges to be 64KB aligned. + /// + /// Range to check + /// True if the range is valid for sparse mapping, false otherwise + private static bool IsSparseAligned(MultiRange range) + { + if (range.Count == 1) + { + return (range.GetSubRange(0).Address & (BufferCache.SparseBufferAlignmentSize - 1)) == 0; + } + + for (int i = 0; i < range.Count; i++) + { + MemoryRange subRange = range.GetSubRange(i); + + // Check if address is aligned. The address of the first sub-range can + // be misaligned as it is at the start. + if (i > 0 && + subRange.Address != MemoryManager.PteUnmapped && + (subRange.Address & (BufferCache.SparseBufferAlignmentSize - 1)) != 0) + { + return false; + } + + // Check if the size is aligned. The size of the last sub-range can + // be misaligned as it is at the end. + if (i < range.Count - 1 && (subRange.Size & (BufferCache.SparseBufferAlignmentSize - 1)) != 0) + { + return false; + } + } + + return true; + } + + /// + /// Resizes the temporary buffer used for range list intersection results, if it has grown too much. + /// + private void ShrinkOverlapsBufferIfNeeded() + { + if (_virtualRangeOverlaps.Length > BufferCache.OverlapsBufferMaxCapacity) + { + Array.Resize(ref _virtualRangeOverlaps, BufferCache.OverlapsBufferMaxCapacity); + } + } + } +} diff --git a/src/Ryujinx.Graphics.Gpu/Shader/CachedShaderBindings.cs b/src/Ryujinx.Graphics.Gpu/Shader/CachedShaderBindings.cs index 1734f08a2..4e1cb4e12 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/CachedShaderBindings.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/CachedShaderBindings.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Engine; using Ryujinx.Graphics.Gpu.Image; using Ryujinx.Graphics.Shader; diff --git a/src/Ryujinx.Graphics.Gpu/Shader/CachedShaderProgram.cs b/src/Ryujinx.Graphics.Gpu/Shader/CachedShaderProgram.cs index 600c8a985..4f56dcac2 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/CachedShaderProgram.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/CachedShaderProgram.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using System; namespace Ryujinx.Graphics.Gpu.Shader diff --git a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs index ef39a4812..efbf68e00 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs @@ -23,7 +23,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache private const ushort FileFormatVersionMajor = 1; private const ushort FileFormatVersionMinor = 2; private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor; - private const uint CodeGenVersion = 5958; + private const uint CodeGenVersion = 6253; private const string SharedTocFileName = "shared.toc"; private const string SharedDataFileName = "shared.data"; diff --git a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheOutputStreams.cs b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheOutputStreams.cs index 1e0df2647..a7ad53574 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheOutputStreams.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheOutputStreams.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; namespace Ryujinx.Graphics.Gpu.Shader.DiskCache diff --git a/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs b/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs index 1d84d0e46..95763f31d 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Graphics.Gpu.Image; using Ryujinx.Graphics.Shader; using Ryujinx.Graphics.Shader.Translation; diff --git a/src/Ryujinx.Graphics.Gpu/Shader/HashTable/HashState.cs b/src/Ryujinx.Graphics.Gpu/Shader/HashTable/HashState.cs index 836b8663a..cb1cf5bbb 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/HashTable/HashState.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/HashTable/HashState.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; namespace Ryujinx.Graphics.Gpu.Shader.HashTable diff --git a/src/Ryujinx.Graphics.Gpu/Shader/HashTable/IDataAccessor.cs b/src/Ryujinx.Graphics.Gpu/Shader/HashTable/IDataAccessor.cs index c982cd9f6..5aecd155c 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/HashTable/IDataAccessor.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/HashTable/IDataAccessor.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.Gpu.Shader.HashTable { diff --git a/src/Ryujinx.Graphics.Gpu/Shader/HashTable/PartitionHashTable.cs b/src/Ryujinx.Graphics.Gpu/Shader/HashTable/PartitionHashTable.cs index c8c8dfcb3..3971526e5 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/HashTable/PartitionHashTable.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/HashTable/PartitionHashTable.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Numerics; diff --git a/src/Ryujinx.Graphics.Gpu/Shader/HashTable/PartitionedHashTable.cs b/src/Ryujinx.Graphics.Gpu/Shader/HashTable/PartitionedHashTable.cs index 341d3114f..b4c18058c 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/HashTable/PartitionedHashTable.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/HashTable/PartitionedHashTable.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics; diff --git a/src/Ryujinx.Graphics.Gpu/Shader/HashTable/SmartDataAccessor.cs b/src/Ryujinx.Graphics.Gpu/Shader/HashTable/SmartDataAccessor.cs index 17853e90a..d0eabba28 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/HashTable/SmartDataAccessor.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/HashTable/SmartDataAccessor.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; namespace Ryujinx.Graphics.Gpu.Shader.HashTable diff --git a/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs index f7d465b3b..de556df13 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs @@ -168,7 +168,8 @@ namespace Ryujinx.Graphics.Gpu.Shader _graphicsShaderCache, _computeShaderCache, _diskCacheHostStorage, - ShaderCacheStateUpdate, cancellationToken); + ShaderCacheStateUpdate, + cancellationToken); loader.LoadShaders(); @@ -737,8 +738,8 @@ namespace Ryujinx.Graphics.Gpu.Shader codeA ??= memoryManager.GetSpan(vertexA.Address, vertexA.Size).ToArray(); codeB ??= memoryManager.GetSpan(currentStage.Address, currentStage.Size).ToArray(); - byte[] cb1DataA = memoryManager.Physical.GetSpan(cb1DataAddress, vertexA.Cb1DataSize).ToArray(); - byte[] cb1DataB = memoryManager.Physical.GetSpan(cb1DataAddress, currentStage.Cb1DataSize).ToArray(); + byte[] cb1DataA = ReadArray(memoryManager, cb1DataAddress, vertexA.Cb1DataSize); + byte[] cb1DataB = ReadArray(memoryManager, cb1DataAddress, currentStage.Cb1DataSize); ShaderDumpPaths pathsA = default; ShaderDumpPaths pathsB = default; @@ -777,7 +778,7 @@ namespace Ryujinx.Graphics.Gpu.Shader ? channel.BufferManager.GetComputeUniformBufferAddress(1) : channel.BufferManager.GetGraphicsUniformBufferAddress(StageToStageIndex(context.Stage), 1); - byte[] cb1Data = memoryManager.Physical.GetSpan(cb1DataAddress, context.Cb1DataSize).ToArray(); + byte[] cb1Data = ReadArray(memoryManager, cb1DataAddress, context.Cb1DataSize); code ??= memoryManager.GetSpan(context.Address, context.Size).ToArray(); ShaderDumpPaths paths = dumper?.Dump(code, context.Stage == ShaderStage.Compute) ?? default; @@ -788,6 +789,23 @@ namespace Ryujinx.Graphics.Gpu.Shader return new TranslatedShader(new CachedShaderStage(program.Info, code, cb1Data), program); } + /// + /// Reads data from physical memory, returns an empty array if the memory is unmapped or size is 0. + /// + /// Memory manager with the physical memory to read from + /// Physical address of the region to read + /// Size in bytes of the data + /// An array with the data at the specified memory location + private static byte[] ReadArray(MemoryManager memoryManager, ulong address, int size) + { + if (address == MemoryManager.PteUnmapped || size == 0) + { + return Array.Empty(); + } + + return memoryManager.Physical.GetSpan(address, size).ToArray(); + } + /// /// Gets the index of a stage from a . /// diff --git a/src/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs b/src/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs index a41f761bd..1477b7382 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs @@ -611,7 +611,7 @@ namespace Ryujinx.Graphics.Gpu.Shader { ref BufferBounds bounds = ref channel.BufferManager.GetUniformBufferBounds(isCompute, stageIndex, textureBufferIndex); - cachedTextureBuffer = MemoryMarshal.Cast(channel.MemoryManager.Physical.GetSpan(bounds.Address, (int)bounds.Size)); + cachedTextureBuffer = MemoryMarshal.Cast(channel.MemoryManager.Physical.GetSpan(bounds.Range)); cachedTextureBufferIndex = textureBufferIndex; if (samplerBufferIndex == textureBufferIndex) @@ -625,7 +625,7 @@ namespace Ryujinx.Graphics.Gpu.Shader { ref BufferBounds bounds = ref channel.BufferManager.GetUniformBufferBounds(isCompute, stageIndex, samplerBufferIndex); - cachedSamplerBuffer = MemoryMarshal.Cast(channel.MemoryManager.Physical.GetSpan(bounds.Address, (int)bounds.Size)); + cachedSamplerBuffer = MemoryMarshal.Cast(channel.MemoryManager.Physical.GetSpan(bounds.Range)); cachedSamplerBufferIndex = samplerBufferIndex; } diff --git a/src/Ryujinx.Graphics.Gpu/Synchronization/HostSyncFlags.cs b/src/Ryujinx.Graphics.Gpu/Synchronization/HostSyncFlags.cs index 1b4df37e2..810c2b4a8 100644 --- a/src/Ryujinx.Graphics.Gpu/Synchronization/HostSyncFlags.cs +++ b/src/Ryujinx.Graphics.Gpu/Synchronization/HostSyncFlags.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.Gpu.Synchronization { diff --git a/src/Ryujinx.Graphics.Gpu/Synchronization/SynchronizationManager.cs b/src/Ryujinx.Graphics.Gpu/Synchronization/SynchronizationManager.cs index 2d5eede58..1042a4db8 100644 --- a/src/Ryujinx.Graphics.Gpu/Synchronization/SynchronizationManager.cs +++ b/src/Ryujinx.Graphics.Gpu/Synchronization/SynchronizationManager.cs @@ -1,4 +1,5 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; +using Ryujinx.Graphics.Device; using System; using System.Threading; @@ -7,7 +8,7 @@ namespace Ryujinx.Graphics.Gpu.Synchronization /// /// GPU synchronization manager. /// - public class SynchronizationManager + public class SynchronizationManager : ISynchronizationManager { /// /// The maximum number of syncpoints supported by the GM20B. @@ -29,12 +30,7 @@ namespace Ryujinx.Graphics.Gpu.Synchronization } } - /// - /// Increment the value of a syncpoint with a given id. - /// - /// The id of the syncpoint - /// Thrown when id >= MaxHardwareSyncpoints - /// The incremented value of the syncpoint + /// public uint IncrementSyncpoint(uint id) { ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(id, (uint)MaxHardwareSyncpoints); @@ -42,12 +38,7 @@ namespace Ryujinx.Graphics.Gpu.Synchronization return _syncpoints[id].Increment(); } - /// - /// Get the value of a syncpoint with a given id. - /// - /// The id of the syncpoint - /// Thrown when id >= MaxHardwareSyncpoints - /// The value of the syncpoint + /// public uint GetSyncpointValue(uint id) { ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(id, (uint)MaxHardwareSyncpoints); @@ -84,15 +75,7 @@ namespace Ryujinx.Graphics.Gpu.Synchronization _syncpoints[id].UnregisterCallback(waiterInformation); } - /// - /// Wait on a syncpoint with a given id at a target threshold. - /// The callback will be called once the threshold is reached and will automatically be unregistered. - /// - /// The id of the syncpoint - /// The target threshold - /// The timeout - /// Thrown when id >= MaxHardwareSyncpoints - /// True if timed out + /// public bool WaitOnSyncpoint(uint id, uint threshold, TimeSpan timeout) { ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(id, (uint)MaxHardwareSyncpoints); diff --git a/src/Ryujinx.Graphics.Gpu/Synchronization/Syncpoint.cs b/src/Ryujinx.Graphics.Gpu/Synchronization/Syncpoint.cs index 16f4d971b..a1626c853 100644 --- a/src/Ryujinx.Graphics.Gpu/Synchronization/Syncpoint.cs +++ b/src/Ryujinx.Graphics.Gpu/Synchronization/Syncpoint.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Threading; diff --git a/src/Ryujinx.Graphics.Gpu/Synchronization/SyncpointWaiterHandle.cs b/src/Ryujinx.Graphics.Gpu/Synchronization/SyncpointWaiterHandle.cs index dd2a5812f..e75b1e895 100644 --- a/src/Ryujinx.Graphics.Gpu/Synchronization/SyncpointWaiterHandle.cs +++ b/src/Ryujinx.Graphics.Gpu/Synchronization/SyncpointWaiterHandle.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.Gpu.Synchronization { diff --git a/src/Ryujinx.Graphics.Host1x/ClassId.cs b/src/Ryujinx.Graphics.Host1x/ClassId.cs index 6da461ef8..8cba6b88c 100644 --- a/src/Ryujinx.Graphics.Host1x/ClassId.cs +++ b/src/Ryujinx.Graphics.Host1x/ClassId.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Host1x +namespace Ryujinx.Graphics.Host1x { public enum ClassId { diff --git a/src/Ryujinx.Graphics.Host1x/Devices.cs b/src/Ryujinx.Graphics.Host1x/Devices.cs index 95c67c9c4..9de2b81a9 100644 --- a/src/Ryujinx.Graphics.Host1x/Devices.cs +++ b/src/Ryujinx.Graphics.Host1x/Devices.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Device; +using Ryujinx.Graphics.Device; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.Graphics.Host1x/Host1xClass.cs b/src/Ryujinx.Graphics.Host1x/Host1xClass.cs index 6f5ba3256..3ffc87ba5 100644 --- a/src/Ryujinx.Graphics.Host1x/Host1xClass.cs +++ b/src/Ryujinx.Graphics.Host1x/Host1xClass.cs @@ -1,5 +1,4 @@ -using Ryujinx.Graphics.Device; -using Ryujinx.Graphics.Gpu.Synchronization; +using Ryujinx.Graphics.Device; using System.Collections.Generic; using System.Threading; @@ -7,10 +6,10 @@ namespace Ryujinx.Graphics.Host1x { public class Host1xClass : IDeviceState { - private readonly SynchronizationManager _syncMgr; + private readonly ISynchronizationManager _syncMgr; private readonly DeviceState _state; - public Host1xClass(SynchronizationManager syncMgr) + public Host1xClass(ISynchronizationManager syncMgr) { _syncMgr = syncMgr; _state = new DeviceState(new Dictionary diff --git a/src/Ryujinx.Graphics.Host1x/Host1xClassRegisters.cs b/src/Ryujinx.Graphics.Host1x/Host1xClassRegisters.cs index 9eeb18d10..28f5d24b0 100644 --- a/src/Ryujinx.Graphics.Host1x/Host1xClassRegisters.cs +++ b/src/Ryujinx.Graphics.Host1x/Host1xClassRegisters.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Host1x { diff --git a/src/Ryujinx.Graphics.Host1x/Host1xDevice.cs b/src/Ryujinx.Graphics.Host1x/Host1xDevice.cs index 73dabaf42..2db74ce5e 100644 --- a/src/Ryujinx.Graphics.Host1x/Host1xDevice.cs +++ b/src/Ryujinx.Graphics.Host1x/Host1xDevice.cs @@ -1,7 +1,6 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.Graphics.Device; -using Ryujinx.Graphics.Gpu.Synchronization; using System; using System.Numerics; @@ -35,7 +34,7 @@ namespace Ryujinx.Graphics.Host1x private int _mask; private bool _incrementing; - public Host1xDevice(SynchronizationManager syncMgr) + public Host1xDevice(ISynchronizationManager syncMgr) { _syncptIncrMgr = new SyncptIncrManager(syncMgr); _commandQueue = new AsyncWorkQueue(Process, "Ryujinx.Host1xProcessor"); diff --git a/src/Ryujinx.Graphics.Host1x/OpCode.cs b/src/Ryujinx.Graphics.Host1x/OpCode.cs index 39b19b1d1..c2d2b59e4 100644 --- a/src/Ryujinx.Graphics.Host1x/OpCode.cs +++ b/src/Ryujinx.Graphics.Host1x/OpCode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Host1x +namespace Ryujinx.Graphics.Host1x { enum OpCode { diff --git a/src/Ryujinx.Graphics.Host1x/Ryujinx.Graphics.Host1x.csproj b/src/Ryujinx.Graphics.Host1x/Ryujinx.Graphics.Host1x.csproj index 22959fad8..d631d039f 100644 --- a/src/Ryujinx.Graphics.Host1x/Ryujinx.Graphics.Host1x.csproj +++ b/src/Ryujinx.Graphics.Host1x/Ryujinx.Graphics.Host1x.csproj @@ -6,7 +6,6 @@ - diff --git a/src/Ryujinx.Graphics.Host1x/SyncptIncrManager.cs b/src/Ryujinx.Graphics.Host1x/SyncptIncrManager.cs index fe8c87395..a5ee1198c 100644 --- a/src/Ryujinx.Graphics.Host1x/SyncptIncrManager.cs +++ b/src/Ryujinx.Graphics.Host1x/SyncptIncrManager.cs @@ -1,11 +1,11 @@ -using Ryujinx.Graphics.Gpu.Synchronization; +using Ryujinx.Graphics.Device; using System.Collections.Generic; namespace Ryujinx.Graphics.Host1x { class SyncptIncrManager { - private readonly SynchronizationManager _syncMgr; + private readonly ISynchronizationManager _syncMgr; private readonly struct SyncptIncr { @@ -27,7 +27,7 @@ namespace Ryujinx.Graphics.Host1x private uint _currentId; - public SyncptIncrManager(SynchronizationManager syncMgr) + public SyncptIncrManager(ISynchronizationManager syncMgr) { _syncMgr = syncMgr; } diff --git a/src/Ryujinx.Graphics.Host1x/ThiDevice.cs b/src/Ryujinx.Graphics.Host1x/ThiDevice.cs index ecdf0f75c..02871efbd 100644 --- a/src/Ryujinx.Graphics.Host1x/ThiDevice.cs +++ b/src/Ryujinx.Graphics.Host1x/ThiDevice.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Graphics.Device; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.Graphics.Host1x/ThiRegisters.cs b/src/Ryujinx.Graphics.Host1x/ThiRegisters.cs index 74e646952..bb7534d8a 100644 --- a/src/Ryujinx.Graphics.Host1x/ThiRegisters.cs +++ b/src/Ryujinx.Graphics.Host1x/ThiRegisters.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Host1x { diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/FFmpegContext.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/FFmpegContext.cs index 284a35a24..0767cc9d6 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/FFmpegContext.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/FFmpegContext.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Graphics.Nvdec.FFmpeg.Native; using System; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/H264/Decoder.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/H264/Decoder.cs index 7dd643ce3..14877dd55 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/H264/Decoder.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/H264/Decoder.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Nvdec.FFmpeg.Native; +using Ryujinx.Graphics.Nvdec.FFmpeg.Native; using Ryujinx.Graphics.Video; using System; diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/H264/SpsAndPpsReconstruction.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/H264/SpsAndPpsReconstruction.cs index 82c5932b7..6d012f89a 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/H264/SpsAndPpsReconstruction.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/H264/SpsAndPpsReconstruction.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.Video; using System; diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec.cs index 434b9b29b..0267000c8 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native { diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec501.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec501.cs index 7b82b5ddf..9084f4024 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec501.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec501.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native { diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecContext.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecContext.cs index a9605c63f..c743ab33e 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecContext.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecContext.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System; namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecID.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecID.cs index b371de9e8..0af076413 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecID.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecID.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native +namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native { enum AVCodecID { diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVFrame.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVFrame.cs index cdc9ebfdc..a1eb7a090 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVFrame.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVFrame.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System; namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVLog.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVLog.cs index fda014a88..642e48972 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVLog.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVLog.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native +namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native { enum AVLog { diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVPacket.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVPacket.cs index 47b9bef98..8df4e26a7 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVPacket.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVPacket.cs @@ -1,4 +1,4 @@ -using AVBufferRef = System.IntPtr; +using AVBufferRef = System.IntPtr; namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native { diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVRational.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVRational.cs index cad5fde0b..15ed3278f 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVRational.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVRational.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native +namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native { public struct AVRational { diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodec.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodec.cs index 89a33697c..ceb8a3b01 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodec.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodec.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native { diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodecLegacy.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodecLegacy.cs index 630e2c179..03eba311c 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodecLegacy.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodecLegacy.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native { diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFmpegApi.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFmpegApi.cs index e04b1fc49..5167ff9fe 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFmpegApi.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFmpegApi.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Reflection; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Surface.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Surface.cs index 959791b6e..65fb7b4ad 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Surface.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Surface.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Nvdec.FFmpeg.Native; +using Ryujinx.Graphics.Nvdec.FFmpeg.Native; using Ryujinx.Graphics.Video; using System; diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Vp8/Decoder.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Vp8/Decoder.cs index 5e38c8c8e..0733e385b 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Vp8/Decoder.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Vp8/Decoder.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Nvdec.FFmpeg.Native; +using Ryujinx.Graphics.Nvdec.FFmpeg.Native; using Ryujinx.Graphics.Video; using System; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/BitDepth.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/BitDepth.cs index b7b709536..a43c83580 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/BitDepth.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/BitDepth.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9 +namespace Ryujinx.Graphics.Nvdec.Vp9 { internal enum BitDepth { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/CodecErr.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/CodecErr.cs index 39a26f66f..3bd149df4 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/CodecErr.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/CodecErr.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9 +namespace Ryujinx.Graphics.Nvdec.Vp9 { internal enum CodecErr { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Common/BitUtils.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Common/BitUtils.cs index 86981930e..807f1293e 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Common/BitUtils.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Common/BitUtils.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using System.Numerics; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Common/MemoryUtil.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Common/MemoryUtil.cs index 909a94832..afdc6b0b2 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Common/MemoryUtil.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Common/MemoryUtil.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; namespace Ryujinx.Graphics.Nvdec.Vp9.Common diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Constants.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Constants.cs index 0ce44b294..17efb203b 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Constants.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Constants.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9 +namespace Ryujinx.Graphics.Nvdec.Vp9 { internal static class Constants { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/DecodeFrame.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/DecodeFrame.cs index 6940d187f..5f03e1afc 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/DecodeFrame.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/DecodeFrame.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.Nvdec.Vp9.Common; using Ryujinx.Graphics.Nvdec.Vp9.Dsp; using Ryujinx.Graphics.Nvdec.Vp9.Types; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/DecodeMv.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/DecodeMv.cs index 8c25c700b..091490bfa 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/DecodeMv.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/DecodeMv.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.Nvdec.Vp9.Dsp; using Ryujinx.Graphics.Nvdec.Vp9.Types; using Ryujinx.Graphics.Video; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Decoder.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Decoder.cs index fea184f15..57057d5f9 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Decoder.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Decoder.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.Nvdec.Vp9.Common; using Ryujinx.Graphics.Nvdec.Vp9.Types; using Ryujinx.Graphics.Video; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Detokenize.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Detokenize.cs index 8e5f124b6..c255f7486 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Detokenize.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Detokenize.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.Nvdec.Vp9.Dsp; using Ryujinx.Graphics.Nvdec.Vp9.Types; using Ryujinx.Graphics.Video; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/Convolve.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/Convolve.cs index 5d4c4b840..9e279dd21 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/Convolve.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/Convolve.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.Nvdec.Vp9.Common; using System.Diagnostics; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/Filter.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/Filter.cs index 169628977..a32221e09 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/Filter.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/Filter.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp +namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp { internal static class Filter { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/IntraPred.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/IntraPred.cs index 8db78ab03..8a570ed59 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/IntraPred.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/IntraPred.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Nvdec.Vp9.Common; +using Ryujinx.Graphics.Nvdec.Vp9.Common; namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/InvTxfm.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/InvTxfm.cs index 68da7c496..c4f45bfda 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/InvTxfm.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/InvTxfm.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Nvdec.Vp9.Common; +using Ryujinx.Graphics.Nvdec.Vp9.Common; using System; using System.Diagnostics; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/Prob.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/Prob.cs index 83b427907..4d75b35df 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/Prob.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/Prob.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Nvdec.Vp9.Common; +using Ryujinx.Graphics.Nvdec.Vp9.Common; using System; using System.Diagnostics; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/Reader.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/Reader.cs index 090426e7c..60a20b43f 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/Reader.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/Reader.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System; using System.Buffers.Binary; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/TxfmCommon.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/TxfmCommon.cs index e041f2e0b..209f19510 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/TxfmCommon.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/TxfmCommon.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp +namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp { internal static class TxfmCommon { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Idct.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Idct.cs index 1ee7f68bc..ebebf0ef9 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Idct.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Idct.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Nvdec.Vp9.Common; +using Ryujinx.Graphics.Nvdec.Vp9.Common; using Ryujinx.Graphics.Nvdec.Vp9.Types; using System; using static Ryujinx.Graphics.Nvdec.Vp9.Dsp.InvTxfm; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/InternalErrorException.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/InternalErrorException.cs index baa0ab998..d4ba0d88b 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/InternalErrorException.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/InternalErrorException.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.Nvdec.Vp9 { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/InternalErrorInfo.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/InternalErrorInfo.cs index 68e9cb4bb..cfec81ed1 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/InternalErrorInfo.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/InternalErrorInfo.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9 +namespace Ryujinx.Graphics.Nvdec.Vp9 { internal struct InternalErrorInfo { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/LoopFilter.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/LoopFilter.cs index 1c9f83b49..9b2564d70 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/LoopFilter.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/LoopFilter.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.Nvdec.Vp9.Common; using Ryujinx.Graphics.Nvdec.Vp9.Types; using System; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Luts.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Luts.cs index 7320c0943..5245b3f32 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Luts.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Luts.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.Nvdec.Vp9.Types; using System; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/PredCommon.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/PredCommon.cs index 9b0c44b76..1f391f6eb 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/PredCommon.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/PredCommon.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Nvdec.Vp9.Types; +using Ryujinx.Graphics.Nvdec.Vp9.Types; using System.Diagnostics; namespace Ryujinx.Graphics.Nvdec.Vp9 diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/QuantCommon.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/QuantCommon.cs index ea858222e..8e8fafdb1 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/QuantCommon.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/QuantCommon.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Nvdec.Vp9.Types; +using Ryujinx.Graphics.Nvdec.Vp9.Types; using System; using System.Diagnostics; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/ReconInter.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/ReconInter.cs index a357cd15b..fdb68291a 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/ReconInter.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/ReconInter.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.Nvdec.Vp9.Types; using System; using System.Diagnostics; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/ReconIntra.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/ReconIntra.cs index 270ff8b7e..768c9acf4 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/ReconIntra.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/ReconIntra.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Nvdec.Vp9.Common; +using Ryujinx.Graphics.Nvdec.Vp9.Common; using Ryujinx.Graphics.Nvdec.Vp9.Types; using System; using static Ryujinx.Graphics.Nvdec.Vp9.Dsp.IntraPred; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/TileBuffer.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/TileBuffer.cs index c5a25e6bc..b6adb95ff 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/TileBuffer.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/TileBuffer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Nvdec.Vp9 { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/TileWorkerData.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/TileWorkerData.cs index 333a077a0..a9a7d566e 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/TileWorkerData.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/TileWorkerData.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.Nvdec.Vp9.Dsp; using Ryujinx.Graphics.Nvdec.Vp9.Types; using Ryujinx.Graphics.Video; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/BModeInfo.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/BModeInfo.cs index 4c8e33c30..4ff82820e 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/BModeInfo.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/BModeInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Nvdec.Vp9.Types { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/BlockSize.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/BlockSize.cs index 34fa9487e..c7d4f7cc4 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/BlockSize.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/BlockSize.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9.Types +namespace Ryujinx.Graphics.Nvdec.Vp9.Types { internal enum BlockSize { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Buf2D.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Buf2D.cs index 180d5e341..1313a2e1f 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Buf2D.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Buf2D.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Nvdec.Vp9.Types { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/FrameType.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/FrameType.cs index 3d2093030..21f021c5b 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/FrameType.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/FrameType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9.Types +namespace Ryujinx.Graphics.Nvdec.Vp9.Types { internal enum FrameType { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/LoopFilter.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/LoopFilter.cs index 8dc33bda8..d2b295476 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/LoopFilter.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/LoopFilter.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Nvdec.Vp9.Types { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/LoopFilterInfoN.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/LoopFilterInfoN.cs index 0ac38a7b9..be6243071 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/LoopFilterInfoN.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/LoopFilterInfoN.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Nvdec.Vp9.Types { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/LoopFilterMask.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/LoopFilterMask.cs index 4aff843a1..879cbe15b 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/LoopFilterMask.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/LoopFilterMask.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Nvdec.Vp9.Types { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/LoopFilterThresh.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/LoopFilterThresh.cs index c0af5495e..546213215 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/LoopFilterThresh.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/LoopFilterThresh.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Nvdec.Vp9.Types { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MacroBlockD.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MacroBlockD.cs index 5cdc0d2df..6305664df 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MacroBlockD.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MacroBlockD.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.Video; namespace Ryujinx.Graphics.Nvdec.Vp9.Types diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MacroBlockDPlane.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MacroBlockDPlane.cs index ae4ec6f41..df21a8d49 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MacroBlockDPlane.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MacroBlockDPlane.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Nvdec.Vp9.Types { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/ModeInfo.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/ModeInfo.cs index 8af7b6f90..e97ed424c 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/ModeInfo.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/ModeInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Diagnostics; namespace Ryujinx.Graphics.Nvdec.Vp9.Types diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MotionVectorContext.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MotionVectorContext.cs index a9a603bf0..bad5af280 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MotionVectorContext.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MotionVectorContext.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9.Types +namespace Ryujinx.Graphics.Nvdec.Vp9.Types { internal enum MotionVectorContext { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Mv.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Mv.cs index c78a80d0d..9ccb51503 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Mv.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Mv.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.Video; using System; using System.Diagnostics; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Mv32.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Mv32.cs index fb25d18e9..5231ca6a6 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Mv32.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Mv32.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9.Types +namespace Ryujinx.Graphics.Nvdec.Vp9.Types { internal struct Mv32 { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MvClassType.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MvClassType.cs index 68a0b59af..188eee0b0 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MvClassType.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MvClassType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9.Types +namespace Ryujinx.Graphics.Nvdec.Vp9.Types { internal enum MvClassType { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MvJointType.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MvJointType.cs index a20cb6d0b..8cccf90cd 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MvJointType.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MvJointType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9.Types +namespace Ryujinx.Graphics.Nvdec.Vp9.Types { internal enum MvJointType { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MvRef.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MvRef.cs index 71949a09b..1d32a0927 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MvRef.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/MvRef.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Nvdec.Vp9.Types { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/PartitionType.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/PartitionType.cs index 78f4fb260..c47557abf 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/PartitionType.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/PartitionType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9.Types +namespace Ryujinx.Graphics.Nvdec.Vp9.Types { internal enum PartitionType { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/PlaneType.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/PlaneType.cs index d62594567..8b01cf3a1 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/PlaneType.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/PlaneType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9.Types +namespace Ryujinx.Graphics.Nvdec.Vp9.Types { internal enum PlaneType { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Position.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Position.cs index 0d3b56f67..cee2fbe83 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Position.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Position.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9.Types +namespace Ryujinx.Graphics.Nvdec.Vp9.Types { internal struct Position { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/PredictionMode.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/PredictionMode.cs index fbf542043..2d81b547e 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/PredictionMode.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/PredictionMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9.Types +namespace Ryujinx.Graphics.Nvdec.Vp9.Types { internal enum PredictionMode { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/RefBuffer.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/RefBuffer.cs index 9942dd053..0fbb84514 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/RefBuffer.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/RefBuffer.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9.Types +namespace Ryujinx.Graphics.Nvdec.Vp9.Types { internal struct RefBuffer { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/ReferenceMode.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/ReferenceMode.cs index 5d9f189d2..aff3cbb07 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/ReferenceMode.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/ReferenceMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9.Types +namespace Ryujinx.Graphics.Nvdec.Vp9.Types { internal enum ReferenceMode { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/ScaleFactors.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/ScaleFactors.cs index ba89d6e39..8e2ec4249 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/ScaleFactors.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/ScaleFactors.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.CompilerServices; using static Ryujinx.Graphics.Nvdec.Vp9.Dsp.Convolve; using static Ryujinx.Graphics.Nvdec.Vp9.Dsp.Filter; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/SegLvlFeatures.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/SegLvlFeatures.cs index 8d04d18b8..eb47abdfd 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/SegLvlFeatures.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/SegLvlFeatures.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9.Types +namespace Ryujinx.Graphics.Nvdec.Vp9.Types { internal enum SegLvlFeatures { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Segmentation.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Segmentation.cs index c0fbdc51e..f2415fc09 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Segmentation.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Segmentation.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Diagnostics; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Surface.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Surface.cs index 7f34faa5b..372b1d2b4 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Surface.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Surface.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.Video; using System; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/TileInfo.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/TileInfo.cs index 232d4ccb2..a3eea81a2 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/TileInfo.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/TileInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Nvdec.Vp9.Common; +using Ryujinx.Graphics.Nvdec.Vp9.Common; using System; using System.Diagnostics; diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/TxMode.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/TxMode.cs index 80c963fe0..b3a05ed9a 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/TxMode.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/TxMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9.Types +namespace Ryujinx.Graphics.Nvdec.Vp9.Types { public enum TxMode { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/TxSize.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/TxSize.cs index bcc70ebab..0342087b8 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/TxSize.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/TxSize.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9.Types +namespace Ryujinx.Graphics.Nvdec.Vp9.Types { public enum TxSize { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/TxType.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/TxType.cs index 1ae436e96..e7b37c925 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/TxType.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/TxType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Vp9.Types +namespace Ryujinx.Graphics.Nvdec.Vp9.Types { internal enum TxType { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Vp9Common.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Vp9Common.cs index 8dd0879eb..2456e9068 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Vp9Common.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Vp9Common.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.Nvdec.Vp9.Common; using Ryujinx.Graphics.Video; diff --git a/src/Ryujinx.Graphics.Nvdec/ApplicationId.cs b/src/Ryujinx.Graphics.Nvdec/ApplicationId.cs index ada12f8d3..5914e73c6 100644 --- a/src/Ryujinx.Graphics.Nvdec/ApplicationId.cs +++ b/src/Ryujinx.Graphics.Nvdec/ApplicationId.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec +namespace Ryujinx.Graphics.Nvdec { public enum ApplicationId { diff --git a/src/Ryujinx.Graphics.Nvdec/H264Decoder.cs b/src/Ryujinx.Graphics.Nvdec/H264Decoder.cs index c99d4a176..6058f72d6 100644 --- a/src/Ryujinx.Graphics.Nvdec/H264Decoder.cs +++ b/src/Ryujinx.Graphics.Nvdec/H264Decoder.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Nvdec.FFmpeg.H264; +using Ryujinx.Graphics.Nvdec.FFmpeg.H264; using Ryujinx.Graphics.Nvdec.Image; using Ryujinx.Graphics.Nvdec.Types.H264; using Ryujinx.Graphics.Video; @@ -12,10 +12,10 @@ namespace Ryujinx.Graphics.Nvdec public static void Decode(NvdecDecoderContext context, ResourceManager rm, ref NvdecRegisters state) { - PictureInfo pictureInfo = rm.Gmm.DeviceRead(state.SetDrvPicSetupOffset); + PictureInfo pictureInfo = rm.MemoryManager.DeviceRead(state.SetDrvPicSetupOffset); H264PictureInfo info = pictureInfo.Convert(); - ReadOnlySpan bitstream = rm.Gmm.DeviceGetSpan(state.SetInBufBaseOffset, (int)pictureInfo.BitstreamSize); + ReadOnlySpan bitstream = rm.MemoryManager.DeviceGetSpan(state.SetInBufBaseOffset, (int)pictureInfo.BitstreamSize); int width = (int)pictureInfo.PicWidthInMbs * MbSizeInPixels; int height = (int)pictureInfo.PicHeightInMbs * MbSizeInPixels; @@ -34,7 +34,7 @@ namespace Ryujinx.Graphics.Nvdec if (outputSurface.Field == FrameField.Progressive) { SurfaceWriter.Write( - rm.Gmm, + rm.MemoryManager, outputSurface, lumaOffset + pictureInfo.LumaFrameOffset, chromaOffset + pictureInfo.ChromaFrameOffset); @@ -42,7 +42,7 @@ namespace Ryujinx.Graphics.Nvdec else { SurfaceWriter.WriteInterlaced( - rm.Gmm, + rm.MemoryManager, outputSurface, lumaOffset + pictureInfo.LumaTopFieldOffset, chromaOffset + pictureInfo.ChromaTopFieldOffset, diff --git a/src/Ryujinx.Graphics.Nvdec/Image/SurfaceCache.cs b/src/Ryujinx.Graphics.Nvdec/Image/SurfaceCache.cs index dc1196732..7359b3309 100644 --- a/src/Ryujinx.Graphics.Nvdec/Image/SurfaceCache.cs +++ b/src/Ryujinx.Graphics.Nvdec/Image/SurfaceCache.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Gpu.Memory; +using Ryujinx.Graphics.Device; using Ryujinx.Graphics.Video; using System; using System.Diagnostics; @@ -27,11 +27,11 @@ namespace Ryujinx.Graphics.Nvdec.Image private readonly CacheItem[] _pool = new CacheItem[MaxItems]; - private readonly MemoryManager _gmm; + private readonly DeviceMemoryManager _mm; - public SurfaceCache(MemoryManager gmm) + public SurfaceCache(DeviceMemoryManager mm) { - _gmm = gmm; + _mm = mm; } public ISurface Get(IDecoder decoder, uint lumaOffset, uint chromaOffset, int width, int height) @@ -77,7 +77,7 @@ namespace Ryujinx.Graphics.Nvdec.Image if ((lumaOffset | chromaOffset) != 0) { - SurfaceReader.Read(_gmm, surface, lumaOffset, chromaOffset); + SurfaceReader.Read(_mm, surface, lumaOffset, chromaOffset); } MoveToFront(i); @@ -100,7 +100,7 @@ namespace Ryujinx.Graphics.Nvdec.Image if ((lumaOffset | chromaOffset) != 0) { - SurfaceReader.Read(_gmm, surface, lumaOffset, chromaOffset); + SurfaceReader.Read(_mm, surface, lumaOffset, chromaOffset); } MoveToFront(MaxItems - 1); diff --git a/src/Ryujinx.Graphics.Nvdec/Image/SurfaceCommon.cs b/src/Ryujinx.Graphics.Nvdec/Image/SurfaceCommon.cs index 6087f5b10..14bc113f5 100644 --- a/src/Ryujinx.Graphics.Nvdec/Image/SurfaceCommon.cs +++ b/src/Ryujinx.Graphics.Nvdec/Image/SurfaceCommon.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Texture; +using Ryujinx.Graphics.Texture; using Ryujinx.Graphics.Video; using System; diff --git a/src/Ryujinx.Graphics.Nvdec/Image/SurfaceReader.cs b/src/Ryujinx.Graphics.Nvdec/Image/SurfaceReader.cs index 598b71992..f510c128d 100644 --- a/src/Ryujinx.Graphics.Nvdec/Image/SurfaceReader.cs +++ b/src/Ryujinx.Graphics.Nvdec/Image/SurfaceReader.cs @@ -1,5 +1,5 @@ -using Ryujinx.Common; -using Ryujinx.Graphics.Gpu.Memory; +using Ryujinx.Common; +using Ryujinx.Graphics.Device; using Ryujinx.Graphics.Texture; using Ryujinx.Graphics.Video; using System; @@ -11,13 +11,13 @@ namespace Ryujinx.Graphics.Nvdec.Image { static class SurfaceReader { - public static void Read(MemoryManager gmm, ISurface surface, uint lumaOffset, uint chromaOffset) + public static void Read(DeviceMemoryManager mm, ISurface surface, uint lumaOffset, uint chromaOffset) { int width = surface.Width; int height = surface.Height; int stride = surface.Stride; - ReadOnlySpan luma = gmm.DeviceGetSpan(lumaOffset, GetBlockLinearSize(width, height, 1)); + ReadOnlySpan luma = mm.DeviceGetSpan(lumaOffset, GetBlockLinearSize(width, height, 1)); ReadLuma(surface.YPlane.AsSpan(), luma, stride, width, height); @@ -25,7 +25,7 @@ namespace Ryujinx.Graphics.Nvdec.Image int uvHeight = surface.UvHeight; int uvStride = surface.UvStride; - ReadOnlySpan chroma = gmm.DeviceGetSpan(chromaOffset, GetBlockLinearSize(uvWidth, uvHeight, 2)); + ReadOnlySpan chroma = mm.DeviceGetSpan(chromaOffset, GetBlockLinearSize(uvWidth, uvHeight, 2)); ReadChroma(surface.UPlane.AsSpan(), surface.VPlane.AsSpan(), chroma, uvStride, uvWidth, uvHeight); } diff --git a/src/Ryujinx.Graphics.Nvdec/Image/SurfaceWriter.cs b/src/Ryujinx.Graphics.Nvdec/Image/SurfaceWriter.cs index dd67252af..043be1f2b 100644 --- a/src/Ryujinx.Graphics.Nvdec/Image/SurfaceWriter.cs +++ b/src/Ryujinx.Graphics.Nvdec/Image/SurfaceWriter.cs @@ -1,5 +1,5 @@ -using Ryujinx.Common; -using Ryujinx.Graphics.Gpu.Memory; +using Ryujinx.Common; +using Ryujinx.Graphics.Device; using Ryujinx.Graphics.Texture; using Ryujinx.Graphics.Video; using System; @@ -12,11 +12,11 @@ namespace Ryujinx.Graphics.Nvdec.Image { static class SurfaceWriter { - public static void Write(MemoryManager gmm, ISurface surface, uint lumaOffset, uint chromaOffset) + public static void Write(DeviceMemoryManager mm, ISurface surface, uint lumaOffset, uint chromaOffset) { int lumaSize = GetBlockLinearSize(surface.Width, surface.Height, 1); - using var luma = gmm.GetWritableRegion(ExtendOffset(lumaOffset), lumaSize); + using var luma = mm.GetWritableRegion(ExtendOffset(lumaOffset), lumaSize); WriteLuma( luma.Memory.Span, @@ -27,7 +27,7 @@ namespace Ryujinx.Graphics.Nvdec.Image int chromaSize = GetBlockLinearSize(surface.UvWidth, surface.UvHeight, 2); - using var chroma = gmm.GetWritableRegion(ExtendOffset(chromaOffset), chromaSize); + using var chroma = mm.GetWritableRegion(ExtendOffset(chromaOffset), chromaSize); WriteChroma( chroma.Memory.Span, @@ -39,7 +39,7 @@ namespace Ryujinx.Graphics.Nvdec.Image } public static void WriteInterlaced( - MemoryManager gmm, + DeviceMemoryManager mm, ISurface surface, uint lumaTopOffset, uint chromaTopOffset, @@ -48,8 +48,8 @@ namespace Ryujinx.Graphics.Nvdec.Image { int lumaSize = GetBlockLinearSize(surface.Width, surface.Height / 2, 1); - using var lumaTop = gmm.GetWritableRegion(ExtendOffset(lumaTopOffset), lumaSize); - using var lumaBottom = gmm.GetWritableRegion(ExtendOffset(lumaBottomOffset), lumaSize); + using var lumaTop = mm.GetWritableRegion(ExtendOffset(lumaTopOffset), lumaSize); + using var lumaBottom = mm.GetWritableRegion(ExtendOffset(lumaBottomOffset), lumaSize); WriteLuma( lumaTop.Memory.Span, @@ -67,8 +67,8 @@ namespace Ryujinx.Graphics.Nvdec.Image int chromaSize = GetBlockLinearSize(surface.UvWidth, surface.UvHeight / 2, 2); - using var chromaTop = gmm.GetWritableRegion(ExtendOffset(chromaTopOffset), chromaSize); - using var chromaBottom = gmm.GetWritableRegion(ExtendOffset(chromaBottomOffset), chromaSize); + using var chromaTop = mm.GetWritableRegion(ExtendOffset(chromaTopOffset), chromaSize); + using var chromaBottom = mm.GetWritableRegion(ExtendOffset(chromaBottomOffset), chromaSize); WriteChroma( chromaTop.Memory.Span, diff --git a/src/Ryujinx.Graphics.Nvdec/MemoryExtensions.cs b/src/Ryujinx.Graphics.Nvdec/MemoryExtensions.cs index 2855a8c7f..1477ed914 100644 --- a/src/Ryujinx.Graphics.Nvdec/MemoryExtensions.cs +++ b/src/Ryujinx.Graphics.Nvdec/MemoryExtensions.cs @@ -1,23 +1,23 @@ -using Ryujinx.Graphics.Gpu.Memory; +using Ryujinx.Graphics.Device; using System; namespace Ryujinx.Graphics.Nvdec { static class MemoryExtensions { - public static T DeviceRead(this MemoryManager gmm, uint offset) where T : unmanaged + public static T DeviceRead(this DeviceMemoryManager gmm, uint offset) where T : unmanaged { - return gmm.Read((ulong)offset << 8); + return gmm.Read(ExtendOffset(offset)); } - public static ReadOnlySpan DeviceGetSpan(this MemoryManager gmm, uint offset, int size) + public static ReadOnlySpan DeviceGetSpan(this DeviceMemoryManager gmm, uint offset, int size) { - return gmm.GetSpan((ulong)offset << 8, size); + return gmm.GetSpan(ExtendOffset(offset), size); } - public static void DeviceWrite(this MemoryManager gmm, uint offset, ReadOnlySpan data) + public static void DeviceWrite(this DeviceMemoryManager gmm, uint offset, ReadOnlySpan data) { - gmm.Write((ulong)offset << 8, data); + gmm.Write(ExtendOffset(offset), data); } public static ulong ExtendOffset(uint offset) diff --git a/src/Ryujinx.Graphics.Nvdec/NvdecDevice.cs b/src/Ryujinx.Graphics.Nvdec/NvdecDevice.cs index 833ee2d42..29e260d63 100644 --- a/src/Ryujinx.Graphics.Nvdec/NvdecDevice.cs +++ b/src/Ryujinx.Graphics.Nvdec/NvdecDevice.cs @@ -1,6 +1,5 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Graphics.Device; -using Ryujinx.Graphics.Gpu.Memory; using Ryujinx.Graphics.Nvdec.Image; using System.Collections.Concurrent; using System.Collections.Generic; @@ -17,9 +16,9 @@ namespace Ryujinx.Graphics.Nvdec private readonly ConcurrentDictionary _contexts; private NvdecDecoderContext _currentContext; - public NvdecDevice(MemoryManager gmm) + public NvdecDevice(DeviceMemoryManager mm) { - _rm = new ResourceManager(gmm, new SurfaceCache(gmm)); + _rm = new ResourceManager(mm, new SurfaceCache(mm)); _state = new DeviceState(new Dictionary { { nameof(NvdecRegisters.Execute), new RwCallback(Execute, null) }, diff --git a/src/Ryujinx.Graphics.Nvdec/NvdecRegisters.cs b/src/Ryujinx.Graphics.Nvdec/NvdecRegisters.cs index 5effcb498..bc325715a 100644 --- a/src/Ryujinx.Graphics.Nvdec/NvdecRegisters.cs +++ b/src/Ryujinx.Graphics.Nvdec/NvdecRegisters.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Nvdec { diff --git a/src/Ryujinx.Graphics.Nvdec/ResourceManager.cs b/src/Ryujinx.Graphics.Nvdec/ResourceManager.cs index 08d242586..da0ded912 100644 --- a/src/Ryujinx.Graphics.Nvdec/ResourceManager.cs +++ b/src/Ryujinx.Graphics.Nvdec/ResourceManager.cs @@ -1,16 +1,16 @@ -using Ryujinx.Graphics.Gpu.Memory; +using Ryujinx.Graphics.Device; using Ryujinx.Graphics.Nvdec.Image; namespace Ryujinx.Graphics.Nvdec { readonly struct ResourceManager { - public MemoryManager Gmm { get; } + public DeviceMemoryManager MemoryManager { get; } public SurfaceCache Cache { get; } - public ResourceManager(MemoryManager gmm, SurfaceCache cache) + public ResourceManager(DeviceMemoryManager mm, SurfaceCache cache) { - Gmm = gmm; + MemoryManager = mm; Cache = cache; } } diff --git a/src/Ryujinx.Graphics.Nvdec/Ryujinx.Graphics.Nvdec.csproj b/src/Ryujinx.Graphics.Nvdec/Ryujinx.Graphics.Nvdec.csproj index fd49a7c80..6c00e9a7c 100644 --- a/src/Ryujinx.Graphics.Nvdec/Ryujinx.Graphics.Nvdec.csproj +++ b/src/Ryujinx.Graphics.Nvdec/Ryujinx.Graphics.Nvdec.csproj @@ -8,7 +8,6 @@ - diff --git a/src/Ryujinx.Graphics.Nvdec/Types/H264/PictureInfo.cs b/src/Ryujinx.Graphics.Nvdec/Types/H264/PictureInfo.cs index aff88a965..26ba2ea69 100644 --- a/src/Ryujinx.Graphics.Nvdec/Types/H264/PictureInfo.cs +++ b/src/Ryujinx.Graphics.Nvdec/Types/H264/PictureInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.Video; namespace Ryujinx.Graphics.Nvdec.Types.H264 diff --git a/src/Ryujinx.Graphics.Nvdec/Types/H264/ReferenceFrame.cs b/src/Ryujinx.Graphics.Nvdec/Types/H264/ReferenceFrame.cs index 9ab9d1320..c310abd67 100644 --- a/src/Ryujinx.Graphics.Nvdec/Types/H264/ReferenceFrame.cs +++ b/src/Ryujinx.Graphics.Nvdec/Types/H264/ReferenceFrame.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Nvdec.Types.H264 { diff --git a/src/Ryujinx.Graphics.Nvdec/Types/Vp8/PictureInfo.cs b/src/Ryujinx.Graphics.Nvdec/Types/Vp8/PictureInfo.cs index 1c4e36c90..a495cfc89 100644 --- a/src/Ryujinx.Graphics.Nvdec/Types/Vp8/PictureInfo.cs +++ b/src/Ryujinx.Graphics.Nvdec/Types/Vp8/PictureInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.Video; namespace Ryujinx.Graphics.Nvdec.Types.Vp8 diff --git a/src/Ryujinx.Graphics.Nvdec/Types/Vp9/BackwardUpdates.cs b/src/Ryujinx.Graphics.Nvdec/Types/Vp9/BackwardUpdates.cs index 661e6cdd7..20e815132 100644 --- a/src/Ryujinx.Graphics.Nvdec/Types/Vp9/BackwardUpdates.cs +++ b/src/Ryujinx.Graphics.Nvdec/Types/Vp9/BackwardUpdates.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.Video; namespace Ryujinx.Graphics.Nvdec.Types.Vp9 diff --git a/src/Ryujinx.Graphics.Nvdec/Types/Vp9/EntropyProbs.cs b/src/Ryujinx.Graphics.Nvdec/Types/Vp9/EntropyProbs.cs index dd5221b18..82a09866a 100644 --- a/src/Ryujinx.Graphics.Nvdec/Types/Vp9/EntropyProbs.cs +++ b/src/Ryujinx.Graphics.Nvdec/Types/Vp9/EntropyProbs.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.Video; namespace Ryujinx.Graphics.Nvdec.Types.Vp9 diff --git a/src/Ryujinx.Graphics.Nvdec/Types/Vp9/FrameFlags.cs b/src/Ryujinx.Graphics.Nvdec/Types/Vp9/FrameFlags.cs index 966620811..ac4cc486a 100644 --- a/src/Ryujinx.Graphics.Nvdec/Types/Vp9/FrameFlags.cs +++ b/src/Ryujinx.Graphics.Nvdec/Types/Vp9/FrameFlags.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Types.Vp9 +namespace Ryujinx.Graphics.Nvdec.Types.Vp9 { enum FrameFlags : uint { diff --git a/src/Ryujinx.Graphics.Nvdec/Types/Vp9/FrameSize.cs b/src/Ryujinx.Graphics.Nvdec/Types/Vp9/FrameSize.cs index 31c08a529..d41c7da13 100644 --- a/src/Ryujinx.Graphics.Nvdec/Types/Vp9/FrameSize.cs +++ b/src/Ryujinx.Graphics.Nvdec/Types/Vp9/FrameSize.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Types.Vp9 +namespace Ryujinx.Graphics.Nvdec.Types.Vp9 { struct FrameSize { diff --git a/src/Ryujinx.Graphics.Nvdec/Types/Vp9/FrameStats.cs b/src/Ryujinx.Graphics.Nvdec/Types/Vp9/FrameStats.cs index 9b0325cf0..47f17e4ed 100644 --- a/src/Ryujinx.Graphics.Nvdec/Types/Vp9/FrameStats.cs +++ b/src/Ryujinx.Graphics.Nvdec/Types/Vp9/FrameStats.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Nvdec.Types.Vp9 +namespace Ryujinx.Graphics.Nvdec.Types.Vp9 { struct FrameStats { diff --git a/src/Ryujinx.Graphics.Nvdec/Types/Vp9/LoopFilter.cs b/src/Ryujinx.Graphics.Nvdec/Types/Vp9/LoopFilter.cs index ebef7f677..139bd87b4 100644 --- a/src/Ryujinx.Graphics.Nvdec/Types/Vp9/LoopFilter.cs +++ b/src/Ryujinx.Graphics.Nvdec/Types/Vp9/LoopFilter.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Nvdec.Types.Vp9 { diff --git a/src/Ryujinx.Graphics.Nvdec/Types/Vp9/PictureInfo.cs b/src/Ryujinx.Graphics.Nvdec/Types/Vp9/PictureInfo.cs index 371680dee..24c18b94c 100644 --- a/src/Ryujinx.Graphics.Nvdec/Types/Vp9/PictureInfo.cs +++ b/src/Ryujinx.Graphics.Nvdec/Types/Vp9/PictureInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.Video; namespace Ryujinx.Graphics.Nvdec.Types.Vp9 diff --git a/src/Ryujinx.Graphics.Nvdec/Types/Vp9/Segmentation.cs b/src/Ryujinx.Graphics.Nvdec/Types/Vp9/Segmentation.cs index ab9954c68..098becc28 100644 --- a/src/Ryujinx.Graphics.Nvdec/Types/Vp9/Segmentation.cs +++ b/src/Ryujinx.Graphics.Nvdec/Types/Vp9/Segmentation.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Nvdec.Types.Vp9 { diff --git a/src/Ryujinx.Graphics.Nvdec/Vp8Decoder.cs b/src/Ryujinx.Graphics.Nvdec/Vp8Decoder.cs index e56b23d73..3d2543c49 100644 --- a/src/Ryujinx.Graphics.Nvdec/Vp8Decoder.cs +++ b/src/Ryujinx.Graphics.Nvdec/Vp8Decoder.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Nvdec.FFmpeg.Vp8; +using Ryujinx.Graphics.Nvdec.FFmpeg.Vp8; using Ryujinx.Graphics.Nvdec.Image; using Ryujinx.Graphics.Nvdec.Types.Vp8; using Ryujinx.Graphics.Video; @@ -10,8 +10,8 @@ namespace Ryujinx.Graphics.Nvdec { public static void Decode(NvdecDecoderContext context, ResourceManager rm, ref NvdecRegisters state) { - PictureInfo pictureInfo = rm.Gmm.DeviceRead(state.SetDrvPicSetupOffset); - ReadOnlySpan bitstream = rm.Gmm.DeviceGetSpan(state.SetInBufBaseOffset, (int)pictureInfo.VLDBufferSize); + PictureInfo pictureInfo = rm.MemoryManager.DeviceRead(state.SetDrvPicSetupOffset); + ReadOnlySpan bitstream = rm.MemoryManager.DeviceGetSpan(state.SetInBufBaseOffset, (int)pictureInfo.VLDBufferSize); Decoder decoder = context.GetVp8Decoder(); @@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.Nvdec if (decoder.Decode(ref info, outputSurface, bitstream)) { - SurfaceWriter.Write(rm.Gmm, outputSurface, lumaOffset, chromaOffset); + SurfaceWriter.Write(rm.MemoryManager, outputSurface, lumaOffset, chromaOffset); } rm.Cache.Put(outputSurface); diff --git a/src/Ryujinx.Graphics.Nvdec/Vp9Decoder.cs b/src/Ryujinx.Graphics.Nvdec/Vp9Decoder.cs index f78bb7028..5ed508647 100644 --- a/src/Ryujinx.Graphics.Nvdec/Vp9Decoder.cs +++ b/src/Ryujinx.Graphics.Nvdec/Vp9Decoder.cs @@ -1,5 +1,5 @@ -using Ryujinx.Common; -using Ryujinx.Graphics.Gpu.Memory; +using Ryujinx.Common; +using Ryujinx.Graphics.Device; using Ryujinx.Graphics.Nvdec.Image; using Ryujinx.Graphics.Nvdec.Types.Vp9; using Ryujinx.Graphics.Nvdec.Vp9; @@ -17,8 +17,8 @@ namespace Ryujinx.Graphics.Nvdec public unsafe static void Decode(ResourceManager rm, ref NvdecRegisters state) { - PictureInfo pictureInfo = rm.Gmm.DeviceRead(state.SetDrvPicSetupOffset); - EntropyProbs entropy = rm.Gmm.DeviceRead(state.Vp9SetProbTabBufOffset); + PictureInfo pictureInfo = rm.MemoryManager.DeviceRead(state.SetDrvPicSetupOffset); + EntropyProbs entropy = rm.MemoryManager.DeviceRead(state.Vp9SetProbTabBufOffset); ISurface Rent(uint lumaOffset, uint chromaOffset, FrameSize size) { @@ -38,19 +38,19 @@ namespace Ryujinx.Graphics.Nvdec entropy.Convert(ref info.Entropy); - ReadOnlySpan bitstream = rm.Gmm.DeviceGetSpan(state.SetInBufBaseOffset, (int)pictureInfo.BitstreamSize); + ReadOnlySpan bitstream = rm.MemoryManager.DeviceGetSpan(state.SetInBufBaseOffset, (int)pictureInfo.BitstreamSize); ReadOnlySpan mvsIn = ReadOnlySpan.Empty; if (info.UsePrevInFindMvRefs) { - mvsIn = GetMvsInput(rm.Gmm, pictureInfo.CurrentFrameSize, state.Vp9SetColMvReadBufOffset); + mvsIn = GetMvsInput(rm.MemoryManager, pictureInfo.CurrentFrameSize, state.Vp9SetColMvReadBufOffset); } int miCols = BitUtils.DivRoundUp(pictureInfo.CurrentFrameSize.Width, 8); int miRows = BitUtils.DivRoundUp(pictureInfo.CurrentFrameSize.Height, 8); - using var mvsRegion = rm.Gmm.GetWritableRegion(ExtendOffset(state.Vp9SetColMvWriteBufOffset), miRows * miCols * 16); + using var mvsRegion = rm.MemoryManager.GetWritableRegion(ExtendOffset(state.Vp9SetColMvWriteBufOffset), miRows * miCols * 16); Span mvsOut = MemoryMarshal.Cast(mvsRegion.Memory.Span); @@ -59,10 +59,10 @@ namespace Ryujinx.Graphics.Nvdec if (_decoder.Decode(ref info, currentSurface, bitstream, mvsIn, mvsOut)) { - SurfaceWriter.Write(rm.Gmm, currentSurface, lumaOffset, chromaOffset); + SurfaceWriter.Write(rm.MemoryManager, currentSurface, lumaOffset, chromaOffset); } - WriteBackwardUpdates(rm.Gmm, state.Vp9SetCtxCounterBufOffset, ref info.BackwardUpdateCounts); + WriteBackwardUpdates(rm.MemoryManager, state.Vp9SetCtxCounterBufOffset, ref info.BackwardUpdateCounts); rm.Cache.Put(lastSurface); rm.Cache.Put(goldenSurface); @@ -70,17 +70,17 @@ namespace Ryujinx.Graphics.Nvdec rm.Cache.Put(currentSurface); } - private static ReadOnlySpan GetMvsInput(MemoryManager gmm, FrameSize size, uint offset) + private static ReadOnlySpan GetMvsInput(DeviceMemoryManager mm, FrameSize size, uint offset) { int miCols = BitUtils.DivRoundUp(size.Width, 8); int miRows = BitUtils.DivRoundUp(size.Height, 8); - return MemoryMarshal.Cast(gmm.DeviceGetSpan(offset, miRows * miCols * 16)); + return MemoryMarshal.Cast(mm.DeviceGetSpan(offset, miRows * miCols * 16)); } - private static void WriteBackwardUpdates(MemoryManager gmm, uint offset, ref Vp9BackwardUpdates counts) + private static void WriteBackwardUpdates(DeviceMemoryManager mm, uint offset, ref Vp9BackwardUpdates counts) { - using var backwardUpdatesRegion = gmm.GetWritableRegion(ExtendOffset(offset), Unsafe.SizeOf()); + using var backwardUpdatesRegion = mm.GetWritableRegion(ExtendOffset(offset), Unsafe.SizeOf()); ref var backwardUpdates = ref MemoryMarshal.Cast(backwardUpdatesRegion.Memory.Span)[0]; diff --git a/src/Ryujinx.Graphics.OpenGL/Constants.cs b/src/Ryujinx.Graphics.OpenGL/Constants.cs index 38fedea0d..e38808b74 100644 --- a/src/Ryujinx.Graphics.OpenGL/Constants.cs +++ b/src/Ryujinx.Graphics.OpenGL/Constants.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.OpenGL +namespace Ryujinx.Graphics.OpenGL { static class Constants { diff --git a/src/Ryujinx.Graphics.OpenGL/Effects/FxaaPostProcessingEffect.cs b/src/Ryujinx.Graphics.OpenGL/Effects/FxaaPostProcessingEffect.cs index 93654ac70..4e92efe6d 100644 --- a/src/Ryujinx.Graphics.OpenGL/Effects/FxaaPostProcessingEffect.cs +++ b/src/Ryujinx.Graphics.OpenGL/Effects/FxaaPostProcessingEffect.cs @@ -1,4 +1,4 @@ -using OpenTK.Graphics.OpenGL; +using OpenTK.Graphics.OpenGL; using Ryujinx.Common; using Ryujinx.Graphics.OpenGL.Image; diff --git a/src/Ryujinx.Graphics.OpenGL/Effects/ShaderHelper.cs b/src/Ryujinx.Graphics.OpenGL/Effects/ShaderHelper.cs index 976b3410b..c25fe5b25 100644 --- a/src/Ryujinx.Graphics.OpenGL/Effects/ShaderHelper.cs +++ b/src/Ryujinx.Graphics.OpenGL/Effects/ShaderHelper.cs @@ -1,4 +1,4 @@ -using OpenTK.Graphics.OpenGL; +using OpenTK.Graphics.OpenGL; namespace Ryujinx.Graphics.OpenGL.Effects { diff --git a/src/Ryujinx.Graphics.OpenGL/Effects/SmaaPostProcessingEffect.cs b/src/Ryujinx.Graphics.OpenGL/Effects/SmaaPostProcessingEffect.cs index b3f6cb1e5..46dda13f2 100644 --- a/src/Ryujinx.Graphics.OpenGL/Effects/SmaaPostProcessingEffect.cs +++ b/src/Ryujinx.Graphics.OpenGL/Effects/SmaaPostProcessingEffect.cs @@ -1,4 +1,4 @@ -using OpenTK.Graphics.OpenGL; +using OpenTK.Graphics.OpenGL; using Ryujinx.Common; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.OpenGL.Image; diff --git a/src/Ryujinx.Graphics.OpenGL/EnumConversion.cs b/src/Ryujinx.Graphics.OpenGL/EnumConversion.cs index 417dc3f60..a92c1ce89 100644 --- a/src/Ryujinx.Graphics.OpenGL/EnumConversion.cs +++ b/src/Ryujinx.Graphics.OpenGL/EnumConversion.cs @@ -1,4 +1,4 @@ -using OpenTK.Graphics.OpenGL; +using OpenTK.Graphics.OpenGL; using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Shader; diff --git a/src/Ryujinx.Graphics.OpenGL/Handle.cs b/src/Ryujinx.Graphics.OpenGL/Handle.cs index 4b2f05e67..b63e8f946 100644 --- a/src/Ryujinx.Graphics.OpenGL/Handle.cs +++ b/src/Ryujinx.Graphics.OpenGL/Handle.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using System.Diagnostics; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Graphics.OpenGL/Helper/GLXHelper.cs b/src/Ryujinx.Graphics.OpenGL/Helper/GLXHelper.cs index 963549463..ce2b20f7d 100644 --- a/src/Ryujinx.Graphics.OpenGL/Helper/GLXHelper.cs +++ b/src/Ryujinx.Graphics.OpenGL/Helper/GLXHelper.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; using System.Runtime.Versioning; diff --git a/src/Ryujinx.Graphics.OpenGL/Helper/WGLHelper.cs b/src/Ryujinx.Graphics.OpenGL/Helper/WGLHelper.cs index df497ae24..be12ff999 100644 --- a/src/Ryujinx.Graphics.OpenGL/Helper/WGLHelper.cs +++ b/src/Ryujinx.Graphics.OpenGL/Helper/WGLHelper.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; using System.Runtime.Versioning; diff --git a/src/Ryujinx.Graphics.OpenGL/IOpenGLContext.cs b/src/Ryujinx.Graphics.OpenGL/IOpenGLContext.cs index b1f6d72d2..a11b9cb29 100644 --- a/src/Ryujinx.Graphics.OpenGL/IOpenGLContext.cs +++ b/src/Ryujinx.Graphics.OpenGL/IOpenGLContext.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.OpenGL.Helper; +using Ryujinx.Graphics.OpenGL.Helper; using System; namespace Ryujinx.Graphics.OpenGL diff --git a/src/Ryujinx.Graphics.OpenGL/Image/ITextureInfo.cs b/src/Ryujinx.Graphics.OpenGL/Image/ITextureInfo.cs index 4c8d7fefc..fecde6dd0 100644 --- a/src/Ryujinx.Graphics.OpenGL/Image/ITextureInfo.cs +++ b/src/Ryujinx.Graphics.OpenGL/Image/ITextureInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; namespace Ryujinx.Graphics.OpenGL.Image { diff --git a/src/Ryujinx.Graphics.OpenGL/Image/TextureBase.cs b/src/Ryujinx.Graphics.OpenGL/Image/TextureBase.cs index 070a36b5e..df8453830 100644 --- a/src/Ryujinx.Graphics.OpenGL/Image/TextureBase.cs +++ b/src/Ryujinx.Graphics.OpenGL/Image/TextureBase.cs @@ -1,4 +1,4 @@ -using OpenTK.Graphics.OpenGL; +using OpenTK.Graphics.OpenGL; using Ryujinx.Graphics.GAL; namespace Ryujinx.Graphics.OpenGL.Image diff --git a/src/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs b/src/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs index c177ae9c6..f140b276a 100644 --- a/src/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs +++ b/src/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs @@ -1,4 +1,4 @@ -using OpenTK.Graphics.OpenGL; +using OpenTK.Graphics.OpenGL; using Ryujinx.Common.Memory; using Ryujinx.Graphics.GAL; using System; diff --git a/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs b/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs index bd2f0a84f..a6e6a4a92 100644 --- a/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs +++ b/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs @@ -1,4 +1,4 @@ -using OpenTK.Graphics.OpenGL; +using OpenTK.Graphics.OpenGL; using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; @@ -57,16 +57,11 @@ namespace Ryujinx.Graphics.OpenGL ResourcePool = new ResourcePool(); } - public BufferHandle CreateBuffer(int size, BufferHandle storageHint) - { - return CreateBuffer(size, GAL.BufferAccess.Default); - } - public BufferHandle CreateBuffer(int size, GAL.BufferAccess access) { BufferCount++; - if (access == GAL.BufferAccess.FlushPersistent) + if (access.HasFlag(GAL.BufferAccess.FlushPersistent)) { BufferHandle handle = Buffer.CreatePersistent(size); @@ -80,11 +75,21 @@ namespace Ryujinx.Graphics.OpenGL } } + public BufferHandle CreateBuffer(int size, GAL.BufferAccess access, BufferHandle storageHint) + { + return CreateBuffer(size, access); + } + public BufferHandle CreateBuffer(nint pointer, int size) { throw new NotSupportedException(); } + public BufferHandle CreateBufferSparse(ReadOnlySpan storageBuffers) + { + throw new NotSupportedException(); + } + public IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info) { return new Program(shaders, info.FragmentOutputMap); @@ -116,7 +121,7 @@ namespace Ryujinx.Graphics.OpenGL public HardwareInfo GetHardwareInfo() { - return new HardwareInfo(GpuVendor, GpuRenderer); + return new HardwareInfo(GpuVendor, GpuRenderer, GpuVendor); // OpenGL does not provide a driver name, vendor name is closest analogue. } public PinnedSpan GetBufferData(BufferHandle buffer, int offset, int size) @@ -148,6 +153,7 @@ namespace Ryujinx.Graphics.OpenGL supportsR4G4B4A4Format: true, supportsSnormBufferTextureFormat: false, supports5BitComponentFormat: true, + supportsSparseBuffer: false, supportsBlendEquationAdvanced: HwCapabilities.SupportsBlendEquationAdvanced, supportsFragmentShaderInterlock: HwCapabilities.SupportsFragmentShaderInterlock, supportsFragmentShaderOrderingIntel: HwCapabilities.SupportsFragmentShaderOrdering, diff --git a/src/Ryujinx.Graphics.OpenGL/Queries/BufferedQuery.cs b/src/Ryujinx.Graphics.OpenGL/Queries/BufferedQuery.cs index 1470f5aaa..0a85970d7 100644 --- a/src/Ryujinx.Graphics.OpenGL/Queries/BufferedQuery.cs +++ b/src/Ryujinx.Graphics.OpenGL/Queries/BufferedQuery.cs @@ -1,4 +1,4 @@ -using OpenTK.Graphics.OpenGL; +using OpenTK.Graphics.OpenGL; using Ryujinx.Common.Logging; using System; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Graphics.OpenGL/Queries/CounterQueue.cs b/src/Ryujinx.Graphics.OpenGL/Queries/CounterQueue.cs index c430ffc34..345a99ffa 100644 --- a/src/Ryujinx.Graphics.OpenGL/Queries/CounterQueue.cs +++ b/src/Ryujinx.Graphics.OpenGL/Queries/CounterQueue.cs @@ -1,4 +1,4 @@ -using OpenTK.Graphics.OpenGL; +using OpenTK.Graphics.OpenGL; using Ryujinx.Graphics.GAL; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.Graphics.OpenGL/Queries/CounterQueueEvent.cs b/src/Ryujinx.Graphics.OpenGL/Queries/CounterQueueEvent.cs index 7d2249068..32b75c615 100644 --- a/src/Ryujinx.Graphics.OpenGL/Queries/CounterQueueEvent.cs +++ b/src/Ryujinx.Graphics.OpenGL/Queries/CounterQueueEvent.cs @@ -1,4 +1,4 @@ -using OpenTK.Graphics.OpenGL; +using OpenTK.Graphics.OpenGL; using Ryujinx.Graphics.GAL; using System; using System.Threading; diff --git a/src/Ryujinx.Graphics.OpenGL/ResourcePool.cs b/src/Ryujinx.Graphics.OpenGL/ResourcePool.cs index 20ef9e87a..6385f57b5 100644 --- a/src/Ryujinx.Graphics.OpenGL/ResourcePool.cs +++ b/src/Ryujinx.Graphics.OpenGL/ResourcePool.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.OpenGL.Image; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.Graphics.OpenGL/Sync.cs b/src/Ryujinx.Graphics.OpenGL/Sync.cs index b7ee3d3c1..eba1638a3 100644 --- a/src/Ryujinx.Graphics.OpenGL/Sync.cs +++ b/src/Ryujinx.Graphics.OpenGL/Sync.cs @@ -1,4 +1,4 @@ -using OpenTK.Graphics.OpenGL; +using OpenTK.Graphics.OpenGL; using Ryujinx.Common.Logging; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.Graphics.Shader/BufferUsageFlags.cs b/src/Ryujinx.Graphics.Shader/BufferUsageFlags.cs index a69fa46a4..10b984831 100644 --- a/src/Ryujinx.Graphics.Shader/BufferUsageFlags.cs +++ b/src/Ryujinx.Graphics.Shader/BufferUsageFlags.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.Shader { diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs index 53267c60b..17c3eefe3 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; +using Ryujinx.Graphics.Shader.IntermediateRepresentation; using Ryujinx.Graphics.Shader.StructuredIr; using Ryujinx.Graphics.Shader.Translation; using Spv.Generator; diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs index 45933a21b..4ff61d9f2 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; +using Ryujinx.Graphics.Shader.IntermediateRepresentation; using Ryujinx.Graphics.Shader.StructuredIr; using Ryujinx.Graphics.Shader.Translation; using Spv.Generator; diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/EnumConversion.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/EnumConversion.cs index 2bb7e8369..d444588e8 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/EnumConversion.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/EnumConversion.cs @@ -1,4 +1,4 @@ -using System; +using System; using static Spv.Specification; namespace Ryujinx.Graphics.Shader.CodeGen.Spirv diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs index 50a73ab83..601753cb0 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; +using Ryujinx.Graphics.Shader.IntermediateRepresentation; using Ryujinx.Graphics.Shader.StructuredIr; using Ryujinx.Graphics.Shader.Translation; using System; diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/OperationResult.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/OperationResult.cs index a6e8e91f6..5be634c74 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/OperationResult.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/OperationResult.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Shader.Translation; +using Ryujinx.Graphics.Shader.Translation; using Spv.Generator; namespace Ryujinx.Graphics.Shader.CodeGen.Spirv diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvDelegates.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvDelegates.cs index 0fa954e15..3716d76d9 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvDelegates.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvDelegates.cs @@ -1,4 +1,4 @@ -using FuncBinaryInstruction = System.Func; +using FuncBinaryInstruction = System.Func; using FuncQuaternaryInstruction = System.Func; using FuncTernaryInstruction = System.Func; using FuncUnaryInstruction = System.Func; diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs index a1e9054f6..ccfdc46d0 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Graphics.Shader.IntermediateRepresentation; using Ryujinx.Graphics.Shader.StructuredIr; using Ryujinx.Graphics.Shader.Translation; diff --git a/src/Ryujinx.Graphics.Shader/IGpuAccessor.cs b/src/Ryujinx.Graphics.Shader/IGpuAccessor.cs index 29a5435e3..df6d29dc5 100644 --- a/src/Ryujinx.Graphics.Shader/IGpuAccessor.cs +++ b/src/Ryujinx.Graphics.Shader/IGpuAccessor.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Shader.CodeGen; +using Ryujinx.Graphics.Shader.CodeGen; using System; namespace Ryujinx.Graphics.Shader diff --git a/src/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs b/src/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs index 55f7d5778..06daa26a0 100644 --- a/src/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs +++ b/src/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs @@ -578,12 +578,7 @@ namespace Ryujinx.Graphics.Shader.Instructions type = SamplerType.Texture2D; flags = TextureFlags.Gather; - if (tld4sOp.Dc) - { - sourcesList.Add(Rb()); - - type |= SamplerType.Shadow; - } + int depthCompareIndex = sourcesList.Count; if (tld4sOp.Aoffi) { @@ -592,7 +587,16 @@ namespace Ryujinx.Graphics.Shader.Instructions flags |= TextureFlags.Offset; } - sourcesList.Add(Const((int)tld4sOp.TexComp)); + if (tld4sOp.Dc) + { + sourcesList.Insert(depthCompareIndex, Rb()); + + type |= SamplerType.Shadow; + } + else + { + sourcesList.Add(Const((int)tld4sOp.TexComp)); + } } else { diff --git a/src/Ryujinx.Graphics.Shader/TextureFormat.cs b/src/Ryujinx.Graphics.Shader/TextureFormat.cs index f6e57fe8f..619598c7f 100644 --- a/src/Ryujinx.Graphics.Shader/TextureFormat.cs +++ b/src/Ryujinx.Graphics.Shader/TextureFormat.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Shader.Translation; +using Ryujinx.Graphics.Shader.Translation; namespace Ryujinx.Graphics.Shader { diff --git a/src/Ryujinx.Graphics.Shader/TextureUsageFlags.cs b/src/Ryujinx.Graphics.Shader/TextureUsageFlags.cs index 3ad1685b6..306435fd6 100644 --- a/src/Ryujinx.Graphics.Shader/TextureUsageFlags.cs +++ b/src/Ryujinx.Graphics.Shader/TextureUsageFlags.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.Shader { diff --git a/src/Ryujinx.Graphics.Shader/Translation/AggregateType.cs b/src/Ryujinx.Graphics.Shader/Translation/AggregateType.cs index def8f1a9d..108fcb94f 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/AggregateType.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/AggregateType.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics.CodeAnalysis; namespace Ryujinx.Graphics.Shader.Translation diff --git a/src/Ryujinx.Graphics.Shader/Translation/FeatureFlags.cs b/src/Ryujinx.Graphics.Shader/Translation/FeatureFlags.cs index 88525462d..82a54db83 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/FeatureFlags.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/FeatureFlags.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.Shader.Translation { diff --git a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs index 6706053e5..a88903274 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Shader.Instructions; +using Ryujinx.Graphics.Shader.Instructions; using Ryujinx.Graphics.Shader.IntermediateRepresentation; using Ryujinx.Graphics.Shader.StructuredIr; using System.Collections.Generic; diff --git a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/Utils.cs b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/Utils.cs index baf8e66e7..74a6d5a1e 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/Utils.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/Utils.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; +using Ryujinx.Graphics.Shader.IntermediateRepresentation; using System.Collections.Generic; namespace Ryujinx.Graphics.Shader.Translation.Optimizations diff --git a/src/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs b/src/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs index a112991e9..a193ab3c4 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Shader.CodeGen; +using Ryujinx.Graphics.Shader.CodeGen; using Ryujinx.Graphics.Shader.CodeGen.Glsl; using Ryujinx.Graphics.Shader.CodeGen.Spirv; using Ryujinx.Graphics.Shader.Decoders; diff --git a/src/Ryujinx.Graphics.Texture/Astc/AstcDecoder.cs b/src/Ryujinx.Graphics.Texture/Astc/AstcDecoder.cs index 1f781d2f8..edf699dc3 100644 --- a/src/Ryujinx.Graphics.Texture/Astc/AstcDecoder.cs +++ b/src/Ryujinx.Graphics.Texture/Astc/AstcDecoder.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System; using System.Diagnostics; using System.Linq; diff --git a/src/Ryujinx.Graphics.Texture/Astc/AstcPixel.cs b/src/Ryujinx.Graphics.Texture/Astc/AstcPixel.cs index e6ca1035c..b16cb0026 100644 --- a/src/Ryujinx.Graphics.Texture/Astc/AstcPixel.cs +++ b/src/Ryujinx.Graphics.Texture/Astc/AstcPixel.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Graphics.Texture/Astc/BitStream128.cs b/src/Ryujinx.Graphics.Texture/Astc/BitStream128.cs index f98a714d1..4402df7e5 100644 --- a/src/Ryujinx.Graphics.Texture/Astc/BitStream128.cs +++ b/src/Ryujinx.Graphics.Texture/Astc/BitStream128.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System; using System.Diagnostics; diff --git a/src/Ryujinx.Graphics.Texture/Astc/Bits.cs b/src/Ryujinx.Graphics.Texture/Astc/Bits.cs index 91652bf14..bedc14f78 100644 --- a/src/Ryujinx.Graphics.Texture/Astc/Bits.cs +++ b/src/Ryujinx.Graphics.Texture/Astc/Bits.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Texture.Astc +namespace Ryujinx.Graphics.Texture.Astc { internal static class Bits { diff --git a/src/Ryujinx.Graphics.Texture/Astc/EndPointSet.cs b/src/Ryujinx.Graphics.Texture/Astc/EndPointSet.cs index 45e61ca2c..2cfb22018 100644 --- a/src/Ryujinx.Graphics.Texture/Astc/EndPointSet.cs +++ b/src/Ryujinx.Graphics.Texture/Astc/EndPointSet.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Graphics.Texture/Astc/IntegerEncoded.cs b/src/Ryujinx.Graphics.Texture/Astc/IntegerEncoded.cs index 361140ddd..fedd90ee2 100644 --- a/src/Ryujinx.Graphics.Texture/Astc/IntegerEncoded.cs +++ b/src/Ryujinx.Graphics.Texture/Astc/IntegerEncoded.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Numerics; namespace Ryujinx.Graphics.Texture.Astc diff --git a/src/Ryujinx.Graphics.Texture/Astc/IntegerSequence.cs b/src/Ryujinx.Graphics.Texture/Astc/IntegerSequence.cs index 367b68095..9cdffd58f 100644 --- a/src/Ryujinx.Graphics.Texture/Astc/IntegerSequence.cs +++ b/src/Ryujinx.Graphics.Texture/Astc/IntegerSequence.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Graphics.Texture/BC6Decoder.cs b/src/Ryujinx.Graphics.Texture/BC6Decoder.cs index f761a4222..ae33e9cf9 100644 --- a/src/Ryujinx.Graphics.Texture/BC6Decoder.cs +++ b/src/Ryujinx.Graphics.Texture/BC6Decoder.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Texture.Utils; +using Ryujinx.Graphics.Texture.Utils; using System; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Graphics.Texture/BC7Decoder.cs b/src/Ryujinx.Graphics.Texture/BC7Decoder.cs index c1c704291..d8c6c1edc 100644 --- a/src/Ryujinx.Graphics.Texture/BC7Decoder.cs +++ b/src/Ryujinx.Graphics.Texture/BC7Decoder.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Texture.Utils; +using Ryujinx.Graphics.Texture.Utils; using System; using System.Diagnostics; using System.Numerics; diff --git a/src/Ryujinx.Graphics.Texture/BlockLinearLayout.cs b/src/Ryujinx.Graphics.Texture/BlockLinearLayout.cs index 06d984ace..809a32cc6 100644 --- a/src/Ryujinx.Graphics.Texture/BlockLinearLayout.cs +++ b/src/Ryujinx.Graphics.Texture/BlockLinearLayout.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using System.Numerics; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Graphics.Texture/Bpp12Pixel.cs b/src/Ryujinx.Graphics.Texture/Bpp12Pixel.cs index 6e2cb8a79..bde96f0f0 100644 --- a/src/Ryujinx.Graphics.Texture/Bpp12Pixel.cs +++ b/src/Ryujinx.Graphics.Texture/Bpp12Pixel.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.Graphics.Texture { diff --git a/src/Ryujinx.Graphics.Texture/Encoders/BC7Encoder.cs b/src/Ryujinx.Graphics.Texture/Encoders/BC7Encoder.cs index 21aa225a7..5fdc9e917 100644 --- a/src/Ryujinx.Graphics.Texture/Encoders/BC7Encoder.cs +++ b/src/Ryujinx.Graphics.Texture/Encoders/BC7Encoder.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Texture.Utils; +using Ryujinx.Graphics.Texture.Utils; using System; using System.Diagnostics; using System.Numerics; diff --git a/src/Ryujinx.Graphics.Texture/Encoders/EncodeMode.cs b/src/Ryujinx.Graphics.Texture/Encoders/EncodeMode.cs index 8db3b3c0d..af2317e72 100644 --- a/src/Ryujinx.Graphics.Texture/Encoders/EncodeMode.cs +++ b/src/Ryujinx.Graphics.Texture/Encoders/EncodeMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Texture.Encoders +namespace Ryujinx.Graphics.Texture.Encoders { enum EncodeMode { diff --git a/src/Ryujinx.Graphics.Texture/Region.cs b/src/Ryujinx.Graphics.Texture/Region.cs index e59888a0e..aeb7f9184 100644 --- a/src/Ryujinx.Graphics.Texture/Region.cs +++ b/src/Ryujinx.Graphics.Texture/Region.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Texture +namespace Ryujinx.Graphics.Texture { public readonly struct Region { diff --git a/src/Ryujinx.Graphics.Texture/Utils/BC67Tables.cs b/src/Ryujinx.Graphics.Texture/Utils/BC67Tables.cs index f1745d235..522538559 100644 --- a/src/Ryujinx.Graphics.Texture/Utils/BC67Tables.cs +++ b/src/Ryujinx.Graphics.Texture/Utils/BC67Tables.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Texture.Utils +namespace Ryujinx.Graphics.Texture.Utils { static class BC67Tables { diff --git a/src/Ryujinx.Graphics.Texture/Utils/BC67Utils.cs b/src/Ryujinx.Graphics.Texture/Utils/BC67Utils.cs index 0916cc2ca..f548684a4 100644 --- a/src/Ryujinx.Graphics.Texture/Utils/BC67Utils.cs +++ b/src/Ryujinx.Graphics.Texture/Utils/BC67Utils.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/Ryujinx.Graphics.Texture/Utils/RgbaColor32.cs b/src/Ryujinx.Graphics.Texture/Utils/RgbaColor32.cs index 8ca3f89bc..7d46ad6eb 100644 --- a/src/Ryujinx.Graphics.Texture/Utils/RgbaColor32.cs +++ b/src/Ryujinx.Graphics.Texture/Utils/RgbaColor32.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/Ryujinx.Graphics.Texture/Utils/RgbaColor8.cs b/src/Ryujinx.Graphics.Texture/Utils/RgbaColor8.cs index eced3d75f..91535c1ae 100644 --- a/src/Ryujinx.Graphics.Texture/Utils/RgbaColor8.cs +++ b/src/Ryujinx.Graphics.Texture/Utils/RgbaColor8.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; diff --git a/src/Ryujinx.Graphics.Vic/Blender.cs b/src/Ryujinx.Graphics.Vic/Blender.cs index e49b59032..3218604db 100644 --- a/src/Ryujinx.Graphics.Vic/Blender.cs +++ b/src/Ryujinx.Graphics.Vic/Blender.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Vic.Image; +using Ryujinx.Graphics.Vic.Image; using Ryujinx.Graphics.Vic.Types; using System; using System.Diagnostics; diff --git a/src/Ryujinx.Graphics.Vic/Image/BufferPool.cs b/src/Ryujinx.Graphics.Vic/Image/BufferPool.cs index 1f7dc08a1..6e3963054 100644 --- a/src/Ryujinx.Graphics.Vic/Image/BufferPool.cs +++ b/src/Ryujinx.Graphics.Vic/Image/BufferPool.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.Vic.Image { diff --git a/src/Ryujinx.Graphics.Vic/Image/InputSurface.cs b/src/Ryujinx.Graphics.Vic/Image/InputSurface.cs index 04994468c..de770c943 100644 --- a/src/Ryujinx.Graphics.Vic/Image/InputSurface.cs +++ b/src/Ryujinx.Graphics.Vic/Image/InputSurface.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.Vic.Image { diff --git a/src/Ryujinx.Graphics.Vic/Image/Pixel.cs b/src/Ryujinx.Graphics.Vic/Image/Pixel.cs index 35f25d163..41308af7f 100644 --- a/src/Ryujinx.Graphics.Vic/Image/Pixel.cs +++ b/src/Ryujinx.Graphics.Vic/Image/Pixel.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Vic.Image +namespace Ryujinx.Graphics.Vic.Image { struct Pixel { diff --git a/src/Ryujinx.Graphics.Vic/Image/Surface.cs b/src/Ryujinx.Graphics.Vic/Image/Surface.cs index f393eb15c..af87d9670 100644 --- a/src/Ryujinx.Graphics.Vic/Image/Surface.cs +++ b/src/Ryujinx.Graphics.Vic/Image/Surface.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.CompilerServices; namespace Ryujinx.Graphics.Vic.Image diff --git a/src/Ryujinx.Graphics.Vic/Image/SurfaceCommon.cs b/src/Ryujinx.Graphics.Vic/Image/SurfaceCommon.cs index 10cdefe28..635f083bd 100644 --- a/src/Ryujinx.Graphics.Vic/Image/SurfaceCommon.cs +++ b/src/Ryujinx.Graphics.Vic/Image/SurfaceCommon.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Graphics.Texture; namespace Ryujinx.Graphics.Vic.Image diff --git a/src/Ryujinx.Graphics.Vic/Image/SurfaceReader.cs b/src/Ryujinx.Graphics.Vic/Image/SurfaceReader.cs index 5175d911a..83f00f345 100644 --- a/src/Ryujinx.Graphics.Vic/Image/SurfaceReader.cs +++ b/src/Ryujinx.Graphics.Vic/Image/SurfaceReader.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Common.Memory; using Ryujinx.Graphics.Texture; using Ryujinx.Graphics.Vic.Types; @@ -454,7 +454,7 @@ namespace Ryujinx.Graphics.Vic.Image int srcStride = GetPitch(width, bytesPerPixel); int inSize = srcStride * height; - ReadOnlySpan src = rm.Gmm.GetSpan(ExtendOffset(offset), inSize); + ReadOnlySpan src = rm.MemoryManager.GetSpan(ExtendOffset(offset), inSize); int outSize = dstStride * height; int bufferIndex = rm.BufferPool.RentMinimum(outSize, out byte[] buffer); @@ -481,7 +481,7 @@ namespace Ryujinx.Graphics.Vic.Image { int inSize = GetBlockLinearSize(width, height, bytesPerPixel, gobBlocksInY); - ReadOnlySpan src = rm.Gmm.GetSpan(ExtendOffset(offset), inSize); + ReadOnlySpan src = rm.MemoryManager.GetSpan(ExtendOffset(offset), inSize); int outSize = dstStride * height; int bufferIndex = rm.BufferPool.RentMinimum(outSize, out byte[] buffer); diff --git a/src/Ryujinx.Graphics.Vic/Image/SurfaceWriter.cs b/src/Ryujinx.Graphics.Vic/Image/SurfaceWriter.cs index 37d261f9e..b5008b7b5 100644 --- a/src/Ryujinx.Graphics.Vic/Image/SurfaceWriter.cs +++ b/src/Ryujinx.Graphics.Vic/Image/SurfaceWriter.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Graphics.Texture; using Ryujinx.Graphics.Vic.Types; using System; @@ -636,7 +636,7 @@ namespace Ryujinx.Graphics.Vic.Image { if (linear) { - rm.Gmm.WriteMapped(ExtendOffset(offset), src); + rm.MemoryManager.Write(ExtendOffset(offset), src); return; } @@ -659,7 +659,7 @@ namespace Ryujinx.Graphics.Vic.Image LayoutConverter.ConvertLinearToBlockLinear(dst, width, height, dstStride, bytesPerPixel, gobBlocksInY, src); - rm.Gmm.WriteMapped(ExtendOffset(offset), dst); + rm.MemoryManager.Write(ExtendOffset(offset), dst); rm.BufferPool.Return(dstIndex); } diff --git a/src/Ryujinx.Graphics.Vic/ResourceManager.cs b/src/Ryujinx.Graphics.Vic/ResourceManager.cs index 7c3f507ed..e7d7ef74a 100644 --- a/src/Ryujinx.Graphics.Vic/ResourceManager.cs +++ b/src/Ryujinx.Graphics.Vic/ResourceManager.cs @@ -1,17 +1,17 @@ -using Ryujinx.Graphics.Gpu.Memory; +using Ryujinx.Graphics.Device; using Ryujinx.Graphics.Vic.Image; namespace Ryujinx.Graphics.Vic { readonly struct ResourceManager { - public MemoryManager Gmm { get; } + public DeviceMemoryManager MemoryManager { get; } public BufferPool SurfacePool { get; } public BufferPool BufferPool { get; } - public ResourceManager(MemoryManager gmm, BufferPool surfacePool, BufferPool bufferPool) + public ResourceManager(DeviceMemoryManager mm, BufferPool surfacePool, BufferPool bufferPool) { - Gmm = gmm; + MemoryManager = mm; SurfacePool = surfacePool; BufferPool = bufferPool; } diff --git a/src/Ryujinx.Graphics.Vic/Ryujinx.Graphics.Vic.csproj b/src/Ryujinx.Graphics.Vic/Ryujinx.Graphics.Vic.csproj index cfebcfa2a..b3f39f2ef 100644 --- a/src/Ryujinx.Graphics.Vic/Ryujinx.Graphics.Vic.csproj +++ b/src/Ryujinx.Graphics.Vic/Ryujinx.Graphics.Vic.csproj @@ -8,7 +8,6 @@ - diff --git a/src/Ryujinx.Graphics.Vic/Types/BlendingSlotStruct.cs b/src/Ryujinx.Graphics.Vic/Types/BlendingSlotStruct.cs index 2cc6b1e28..0037befea 100644 --- a/src/Ryujinx.Graphics.Vic/Types/BlendingSlotStruct.cs +++ b/src/Ryujinx.Graphics.Vic/Types/BlendingSlotStruct.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; namespace Ryujinx.Graphics.Vic.Types { diff --git a/src/Ryujinx.Graphics.Vic/Types/ClearRectStruct.cs b/src/Ryujinx.Graphics.Vic/Types/ClearRectStruct.cs index da9888f78..2e78f5d4d 100644 --- a/src/Ryujinx.Graphics.Vic/Types/ClearRectStruct.cs +++ b/src/Ryujinx.Graphics.Vic/Types/ClearRectStruct.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; namespace Ryujinx.Graphics.Vic.Types { diff --git a/src/Ryujinx.Graphics.Vic/Types/ConfigStruct.cs b/src/Ryujinx.Graphics.Vic/Types/ConfigStruct.cs index bf94606c0..2496a62e9 100644 --- a/src/Ryujinx.Graphics.Vic/Types/ConfigStruct.cs +++ b/src/Ryujinx.Graphics.Vic/Types/ConfigStruct.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Vic.Types { diff --git a/src/Ryujinx.Graphics.Vic/Types/LumaKeyStruct.cs b/src/Ryujinx.Graphics.Vic/Types/LumaKeyStruct.cs index 0cb5e6d9d..87deb4e44 100644 --- a/src/Ryujinx.Graphics.Vic/Types/LumaKeyStruct.cs +++ b/src/Ryujinx.Graphics.Vic/Types/LumaKeyStruct.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; namespace Ryujinx.Graphics.Vic.Types { diff --git a/src/Ryujinx.Graphics.Vic/Types/MatrixStruct.cs b/src/Ryujinx.Graphics.Vic/Types/MatrixStruct.cs index f89a142f8..b634e3f45 100644 --- a/src/Ryujinx.Graphics.Vic/Types/MatrixStruct.cs +++ b/src/Ryujinx.Graphics.Vic/Types/MatrixStruct.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; namespace Ryujinx.Graphics.Vic.Types { diff --git a/src/Ryujinx.Graphics.Vic/Types/OutputConfig.cs b/src/Ryujinx.Graphics.Vic/Types/OutputConfig.cs index 10ceb240f..3ce6c93c5 100644 --- a/src/Ryujinx.Graphics.Vic/Types/OutputConfig.cs +++ b/src/Ryujinx.Graphics.Vic/Types/OutputConfig.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; namespace Ryujinx.Graphics.Vic.Types { diff --git a/src/Ryujinx.Graphics.Vic/Types/OutputSurfaceConfig.cs b/src/Ryujinx.Graphics.Vic/Types/OutputSurfaceConfig.cs index ad236882d..e72a6a125 100644 --- a/src/Ryujinx.Graphics.Vic/Types/OutputSurfaceConfig.cs +++ b/src/Ryujinx.Graphics.Vic/Types/OutputSurfaceConfig.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; namespace Ryujinx.Graphics.Vic.Types { diff --git a/src/Ryujinx.Graphics.Vic/Types/PipeConfig.cs b/src/Ryujinx.Graphics.Vic/Types/PipeConfig.cs index 408bd83ea..1e0a7e641 100644 --- a/src/Ryujinx.Graphics.Vic/Types/PipeConfig.cs +++ b/src/Ryujinx.Graphics.Vic/Types/PipeConfig.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; namespace Ryujinx.Graphics.Vic.Types { diff --git a/src/Ryujinx.Graphics.Vic/Types/PixelFormat.cs b/src/Ryujinx.Graphics.Vic/Types/PixelFormat.cs index 8f5eda8b6..58df3f307 100644 --- a/src/Ryujinx.Graphics.Vic/Types/PixelFormat.cs +++ b/src/Ryujinx.Graphics.Vic/Types/PixelFormat.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Vic.Types +namespace Ryujinx.Graphics.Vic.Types { enum PixelFormat { diff --git a/src/Ryujinx.Graphics.Vic/Types/SlotConfig.cs b/src/Ryujinx.Graphics.Vic/Types/SlotConfig.cs index 4031bf995..148d06815 100644 --- a/src/Ryujinx.Graphics.Vic/Types/SlotConfig.cs +++ b/src/Ryujinx.Graphics.Vic/Types/SlotConfig.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; namespace Ryujinx.Graphics.Vic.Types { diff --git a/src/Ryujinx.Graphics.Vic/Types/SlotStruct.cs b/src/Ryujinx.Graphics.Vic/Types/SlotStruct.cs index 96c6cce56..b7726683e 100644 --- a/src/Ryujinx.Graphics.Vic/Types/SlotStruct.cs +++ b/src/Ryujinx.Graphics.Vic/Types/SlotStruct.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Vic.Types +namespace Ryujinx.Graphics.Vic.Types { struct SlotStruct { diff --git a/src/Ryujinx.Graphics.Vic/Types/SlotSurfaceConfig.cs b/src/Ryujinx.Graphics.Vic/Types/SlotSurfaceConfig.cs index 0be0d4f43..3acab4de9 100644 --- a/src/Ryujinx.Graphics.Vic/Types/SlotSurfaceConfig.cs +++ b/src/Ryujinx.Graphics.Vic/Types/SlotSurfaceConfig.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; namespace Ryujinx.Graphics.Vic.Types { diff --git a/src/Ryujinx.Graphics.Vic/VicDevice.cs b/src/Ryujinx.Graphics.Vic/VicDevice.cs index 5053c0cc5..2b25a74c8 100644 --- a/src/Ryujinx.Graphics.Vic/VicDevice.cs +++ b/src/Ryujinx.Graphics.Vic/VicDevice.cs @@ -1,5 +1,4 @@ -using Ryujinx.Graphics.Device; -using Ryujinx.Graphics.Gpu.Memory; +using Ryujinx.Graphics.Device; using Ryujinx.Graphics.Vic.Image; using Ryujinx.Graphics.Vic.Types; using System; @@ -9,14 +8,14 @@ namespace Ryujinx.Graphics.Vic { public class VicDevice : IDeviceState { - private readonly MemoryManager _gmm; + private readonly DeviceMemoryManager _mm; private readonly ResourceManager _rm; private readonly DeviceState _state; - public VicDevice(MemoryManager gmm) + public VicDevice(DeviceMemoryManager mm) { - _gmm = gmm; - _rm = new ResourceManager(gmm, new BufferPool(), new BufferPool()); + _mm = mm; + _rm = new ResourceManager(mm, new BufferPool(), new BufferPool()); _state = new DeviceState(new Dictionary { { nameof(VicRegisters.Execute), new RwCallback(Execute, null) }, @@ -68,7 +67,7 @@ namespace Ryujinx.Graphics.Vic private T ReadIndirect(uint offset) where T : unmanaged { - return _gmm.Read((ulong)offset << 8); + return _mm.Read((ulong)offset << 8); } } } diff --git a/src/Ryujinx.Graphics.Vic/VicRegisters.cs b/src/Ryujinx.Graphics.Vic/VicRegisters.cs index 1e002839c..7ebc10d9a 100644 --- a/src/Ryujinx.Graphics.Vic/VicRegisters.cs +++ b/src/Ryujinx.Graphics.Vic/VicRegisters.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Vic { diff --git a/src/Ryujinx.Graphics.Video/H264PictureInfo.cs b/src/Ryujinx.Graphics.Video/H264PictureInfo.cs index 3b2c2fff7..294de0556 100644 --- a/src/Ryujinx.Graphics.Video/H264PictureInfo.cs +++ b/src/Ryujinx.Graphics.Video/H264PictureInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Video { diff --git a/src/Ryujinx.Graphics.Video/IDecoder.cs b/src/Ryujinx.Graphics.Video/IDecoder.cs index 5957af085..44c3375c0 100644 --- a/src/Ryujinx.Graphics.Video/IDecoder.cs +++ b/src/Ryujinx.Graphics.Video/IDecoder.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.Video { diff --git a/src/Ryujinx.Graphics.Video/IH264Decoder.cs b/src/Ryujinx.Graphics.Video/IH264Decoder.cs index 127b9412c..f204436d8 100644 --- a/src/Ryujinx.Graphics.Video/IH264Decoder.cs +++ b/src/Ryujinx.Graphics.Video/IH264Decoder.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.Video { diff --git a/src/Ryujinx.Graphics.Video/ISurface.cs b/src/Ryujinx.Graphics.Video/ISurface.cs index 7c1661f1f..6176b6a4e 100644 --- a/src/Ryujinx.Graphics.Video/ISurface.cs +++ b/src/Ryujinx.Graphics.Video/ISurface.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.Video { diff --git a/src/Ryujinx.Graphics.Video/IVp9Decoder.cs b/src/Ryujinx.Graphics.Video/IVp9Decoder.cs index ac79bc421..78ed90a4e 100644 --- a/src/Ryujinx.Graphics.Video/IVp9Decoder.cs +++ b/src/Ryujinx.Graphics.Video/IVp9Decoder.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.Video { diff --git a/src/Ryujinx.Graphics.Video/Plane.cs b/src/Ryujinx.Graphics.Video/Plane.cs index 1a2ad251b..b895cad90 100644 --- a/src/Ryujinx.Graphics.Video/Plane.cs +++ b/src/Ryujinx.Graphics.Video/Plane.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.Video { diff --git a/src/Ryujinx.Graphics.Video/Vp8PictureInfo.cs b/src/Ryujinx.Graphics.Video/Vp8PictureInfo.cs index df398d843..6aa7fb7fd 100644 --- a/src/Ryujinx.Graphics.Video/Vp8PictureInfo.cs +++ b/src/Ryujinx.Graphics.Video/Vp8PictureInfo.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Video +namespace Ryujinx.Graphics.Video { public ref struct Vp8PictureInfo { diff --git a/src/Ryujinx.Graphics.Video/Vp9BackwardUpdates.cs b/src/Ryujinx.Graphics.Video/Vp9BackwardUpdates.cs index a3aa4de73..0fb543669 100644 --- a/src/Ryujinx.Graphics.Video/Vp9BackwardUpdates.cs +++ b/src/Ryujinx.Graphics.Video/Vp9BackwardUpdates.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Video { diff --git a/src/Ryujinx.Graphics.Video/Vp9EntropyProbs.cs b/src/Ryujinx.Graphics.Video/Vp9EntropyProbs.cs index 10b997a5f..a5fc25a48 100644 --- a/src/Ryujinx.Graphics.Video/Vp9EntropyProbs.cs +++ b/src/Ryujinx.Graphics.Video/Vp9EntropyProbs.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Video { diff --git a/src/Ryujinx.Graphics.Video/Vp9Mv.cs b/src/Ryujinx.Graphics.Video/Vp9Mv.cs index 9de410589..ce842a1d3 100644 --- a/src/Ryujinx.Graphics.Video/Vp9Mv.cs +++ b/src/Ryujinx.Graphics.Video/Vp9Mv.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Video +namespace Ryujinx.Graphics.Video { public struct Vp9Mv { diff --git a/src/Ryujinx.Graphics.Video/Vp9MvRef.cs b/src/Ryujinx.Graphics.Video/Vp9MvRef.cs index 6f2d8e815..7962544d0 100644 --- a/src/Ryujinx.Graphics.Video/Vp9MvRef.cs +++ b/src/Ryujinx.Graphics.Video/Vp9MvRef.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Video { diff --git a/src/Ryujinx.Graphics.Video/Vp9PictureInfo.cs b/src/Ryujinx.Graphics.Video/Vp9PictureInfo.cs index a5cc2b450..bcdaf0dfc 100644 --- a/src/Ryujinx.Graphics.Video/Vp9PictureInfo.cs +++ b/src/Ryujinx.Graphics.Video/Vp9PictureInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.Graphics.Video { diff --git a/src/Ryujinx.Graphics.Vulkan/Auto.cs b/src/Ryujinx.Graphics.Vulkan/Auto.cs index 026dd2b60..606c088e9 100644 --- a/src/Ryujinx.Graphics.Vulkan/Auto.cs +++ b/src/Ryujinx.Graphics.Vulkan/Auto.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using System.Threading; diff --git a/src/Ryujinx.Graphics.Vulkan/AutoFlushCounter.cs b/src/Ryujinx.Graphics.Vulkan/AutoFlushCounter.cs index 8ac412fe5..266893a6e 100644 --- a/src/Ryujinx.Graphics.Vulkan/AutoFlushCounter.cs +++ b/src/Ryujinx.Graphics.Vulkan/AutoFlushCounter.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using System; using System.Diagnostics; using System.Linq; diff --git a/src/Ryujinx.Graphics.Vulkan/BackgroundResources.cs b/src/Ryujinx.Graphics.Vulkan/BackgroundResources.cs index e9478b438..24e600a26 100644 --- a/src/Ryujinx.Graphics.Vulkan/BackgroundResources.cs +++ b/src/Ryujinx.Graphics.Vulkan/BackgroundResources.cs @@ -1,4 +1,4 @@ -using Silk.NET.Vulkan; +using Silk.NET.Vulkan; using System; using System.Collections.Generic; using System.Threading; diff --git a/src/Ryujinx.Graphics.Vulkan/BitMap.cs b/src/Ryujinx.Graphics.Vulkan/BitMap.cs index 5619fcdf7..22abe719b 100644 --- a/src/Ryujinx.Graphics.Vulkan/BitMap.cs +++ b/src/Ryujinx.Graphics.Vulkan/BitMap.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Vulkan +namespace Ryujinx.Graphics.Vulkan { readonly struct BitMap { diff --git a/src/Ryujinx.Graphics.Vulkan/BitMapStruct.cs b/src/Ryujinx.Graphics.Vulkan/BitMapStruct.cs index 15672e9cb..43107427c 100644 --- a/src/Ryujinx.Graphics.Vulkan/BitMapStruct.cs +++ b/src/Ryujinx.Graphics.Vulkan/BitMapStruct.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System; using System.Numerics; diff --git a/src/Ryujinx.Graphics.Vulkan/BufferAllocationType.cs b/src/Ryujinx.Graphics.Vulkan/BufferAllocationType.cs index 00b65714b..345191f16 100644 --- a/src/Ryujinx.Graphics.Vulkan/BufferAllocationType.cs +++ b/src/Ryujinx.Graphics.Vulkan/BufferAllocationType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Vulkan +namespace Ryujinx.Graphics.Vulkan { internal enum BufferAllocationType { @@ -8,5 +8,6 @@ HostMapped, DeviceLocal, DeviceLocalMapped, + Sparse, } } diff --git a/src/Ryujinx.Graphics.Vulkan/BufferHolder.cs b/src/Ryujinx.Graphics.Vulkan/BufferHolder.cs index d3a3cae11..3673ee5a1 100644 --- a/src/Ryujinx.Graphics.Vulkan/BufferHolder.cs +++ b/src/Ryujinx.Graphics.Vulkan/BufferHolder.cs @@ -1,9 +1,10 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; using System; using System.Collections.Generic; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Threading; using VkBuffer = Silk.NET.Vulkan.Buffer; using VkFormat = Silk.NET.Vulkan.Format; @@ -46,7 +47,7 @@ namespace Ryujinx.Graphics.Vulkan private bool _lastAccessIsWrite; - private readonly BufferAllocationType _baseType; + private BufferAllocationType _baseType; private BufferAllocationType _currentType; private bool _swapQueued; @@ -109,6 +110,22 @@ namespace Ryujinx.Graphics.Vulkan _flushLock = new ReaderWriterLockSlim(); } + public BufferHolder(VulkanRenderer gd, Device device, VkBuffer buffer, int size, Auto[] storageAllocations) + { + _gd = gd; + _device = device; + _waitable = new MultiFenceHolder(size); + _buffer = new Auto(new DisposableBuffer(gd.Api, device, buffer), _waitable, storageAllocations); + _bufferHandle = buffer.Handle; + Size = size; + + _baseType = BufferAllocationType.Sparse; + _currentType = BufferAllocationType.Sparse; + DesiredType = BufferAllocationType.Sparse; + + _flushLock = new ReaderWriterLockSlim(); + } + public bool TryBackingSwap(ref CommandBufferScoped? cbs) { if (_swapQueued && DesiredType != _currentType) @@ -122,7 +139,7 @@ namespace Ryujinx.Graphics.Vulkan var currentBuffer = _buffer; IntPtr currentMap = _map; - (VkBuffer buffer, MemoryAllocation allocation, BufferAllocationType resultType) = _gd.BufferManager.CreateBacking(_gd, Size, DesiredType, false, _currentType); + (VkBuffer buffer, MemoryAllocation allocation, BufferAllocationType resultType) = _gd.BufferManager.CreateBacking(_gd, Size, DesiredType, false, false, _currentType); if (buffer.Handle != 0) { @@ -253,6 +270,14 @@ namespace Ryujinx.Graphics.Vulkan } } + public void Pin() + { + if (_baseType == BufferAllocationType.Auto) + { + _baseType = _currentType; + } + } + public unsafe Auto CreateView(VkFormat format, int offset, int size, Action invalidateView) { var bufferViewCreateInfo = new BufferViewCreateInfo @@ -360,7 +385,7 @@ namespace Ryujinx.Graphics.Vulkan var baseData = new Span((void*)(_map + offset), size); var modData = _pendingData.AsSpan(offset, size); - StagingBufferReserved? newMirror = _gd.BufferManager.StagingBuffer.TryReserveData(cbs, size, (int)_gd.Capabilities.MinResourceAlignment); + StagingBufferReserved? newMirror = _gd.BufferManager.StagingBuffer.TryReserveData(cbs, size); if (newMirror != null) { @@ -496,7 +521,7 @@ namespace Ryujinx.Graphics.Vulkan if (_gd.PipelineInternal.CurrentCommandBuffer.CommandBuffer.Handle == cbs.CommandBuffer.Handle) { - SetData(rangeOffset, _pendingData.AsSpan(rangeOffset, rangeSize), cbs, _gd.PipelineInternal.EndRenderPass, false); + SetData(rangeOffset, _pendingData.AsSpan(rangeOffset, rangeSize), cbs, _gd.PipelineInternal.EndRenderPassDelegate, false); } else { @@ -506,6 +531,16 @@ namespace Ryujinx.Graphics.Vulkan } } + public Auto GetAllocation() + { + return _allocationAuto; + } + + public (DeviceMemory, ulong) GetDeviceMemoryAndOffset() + { + return (_allocation.Memory, _allocation.Offset); + } + public void SignalWrite(int offset, int size) { ConsiderBackingSwap(); @@ -804,6 +839,11 @@ namespace Ryujinx.Graphics.Vulkan } } + public unsafe void SetDataUnchecked(int offset, ReadOnlySpan data) where T : unmanaged + { + SetDataUnchecked(offset, MemoryMarshal.AsBytes(data)); + } + public void SetDataInline(CommandBufferScoped cbs, Action endRenderPass, int dstOffset, ReadOnlySpan data) { if (!TryPushData(cbs, endRenderPass, dstOffset, data)) @@ -1072,7 +1112,7 @@ namespace Ryujinx.Graphics.Vulkan } else { - _allocationAuto.Dispose(); + _allocationAuto?.Dispose(); } _flushLock.EnterWriteLock(); diff --git a/src/Ryujinx.Graphics.Vulkan/BufferManager.cs b/src/Ryujinx.Graphics.Vulkan/BufferManager.cs index 380967022..33289a0e0 100644 --- a/src/Ryujinx.Graphics.Vulkan/BufferManager.cs +++ b/src/Ryujinx.Graphics.Vulkan/BufferManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; using System; @@ -9,6 +9,36 @@ using VkFormat = Silk.NET.Vulkan.Format; namespace Ryujinx.Graphics.Vulkan { + readonly struct ScopedTemporaryBuffer : IDisposable + { + private readonly BufferManager _bufferManager; + private readonly bool _isReserved; + + public readonly BufferRange Range; + public readonly BufferHolder Holder; + + public BufferHandle Handle => Range.Handle; + public int Offset => Range.Offset; + + public ScopedTemporaryBuffer(BufferManager bufferManager, BufferHolder holder, BufferHandle handle, int offset, int size, bool isReserved) + { + _bufferManager = bufferManager; + + Range = new BufferRange(handle, offset, size); + Holder = holder; + + _isReserved = isReserved; + } + + public void Dispose() + { + if (!_isReserved) + { + _bufferManager.Delete(Range.Handle); + } + } + } + class BufferManager : IDisposable { public const MemoryPropertyFlags DefaultBufferMemoryFlags = @@ -96,25 +126,131 @@ namespace Ryujinx.Graphics.Vulkan return Unsafe.As(ref handle64); } + public unsafe BufferHandle CreateSparse(VulkanRenderer gd, ReadOnlySpan storageBuffers) + { + var usage = DefaultBufferUsageFlags; + + if (gd.Capabilities.SupportsIndirectParameters) + { + usage |= BufferUsageFlags.IndirectBufferBit; + } + + ulong size = 0; + + foreach (BufferRange range in storageBuffers) + { + size += (ulong)range.Size; + } + + var bufferCreateInfo = new BufferCreateInfo() + { + SType = StructureType.BufferCreateInfo, + Size = size, + Usage = usage, + SharingMode = SharingMode.Exclusive, + Flags = BufferCreateFlags.SparseBindingBit | BufferCreateFlags.SparseAliasedBit + }; + + gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out var buffer).ThrowOnError(); + + var memoryBinds = new SparseMemoryBind[storageBuffers.Length]; + var storageAllocations = new Auto[storageBuffers.Length]; + int storageAllocationsCount = 0; + + ulong dstOffset = 0; + + for (int index = 0; index < storageBuffers.Length; index++) + { + BufferRange range = storageBuffers[index]; + + if (TryGetBuffer(range.Handle, out var existingHolder)) + { + // Since this buffer now also owns the memory from the referenced buffer, + // we pin it to ensure the memory location will not change. + existingHolder.Pin(); + + (var memory, var offset) = existingHolder.GetDeviceMemoryAndOffset(); + + memoryBinds[index] = new SparseMemoryBind() + { + ResourceOffset = dstOffset, + Size = (ulong)range.Size, + Memory = memory, + MemoryOffset = offset + (ulong)range.Offset, + Flags = SparseMemoryBindFlags.None + }; + + storageAllocations[storageAllocationsCount++] = existingHolder.GetAllocation(); + } + else + { + memoryBinds[index] = new SparseMemoryBind() + { + ResourceOffset = dstOffset, + Size = (ulong)range.Size, + Memory = default, + MemoryOffset = 0UL, + Flags = SparseMemoryBindFlags.None + }; + } + + dstOffset += (ulong)range.Size; + } + + if (storageAllocations.Length != storageAllocationsCount) + { + Array.Resize(ref storageAllocations, storageAllocationsCount); + } + + fixed (SparseMemoryBind* pMemoryBinds = memoryBinds) + { + SparseBufferMemoryBindInfo bufferBind = new SparseBufferMemoryBindInfo() + { + Buffer = buffer, + BindCount = (uint)memoryBinds.Length, + PBinds = pMemoryBinds + }; + + BindSparseInfo bindSparseInfo = new BindSparseInfo() + { + SType = StructureType.BindSparseInfo, + BufferBindCount = 1, + PBufferBinds = &bufferBind + }; + + gd.Api.QueueBindSparse(gd.Queue, 1, bindSparseInfo, default).ThrowOnError(); + } + + var holder = new BufferHolder(gd, _device, buffer, (int)size, storageAllocations); + + BufferCount++; + + ulong handle64 = (uint)_buffers.Add(holder); + + return Unsafe.As(ref handle64); + } + public BufferHandle CreateWithHandle( VulkanRenderer gd, int size, + bool sparseCompatible = false, BufferAllocationType baseType = BufferAllocationType.HostMapped, BufferHandle storageHint = default, bool forceMirrors = false) { - return CreateWithHandle(gd, size, out _, baseType, storageHint, forceMirrors); + return CreateWithHandle(gd, size, out _, sparseCompatible, baseType, storageHint, forceMirrors); } public BufferHandle CreateWithHandle( VulkanRenderer gd, int size, out BufferHolder holder, + bool sparseCompatible = false, BufferAllocationType baseType = BufferAllocationType.HostMapped, BufferHandle storageHint = default, bool forceMirrors = false) { - holder = Create(gd, size, baseType: baseType, storageHint: storageHint); + holder = Create(gd, size, forConditionalRendering: false, sparseCompatible, baseType, storageHint); if (holder == null) { return BufferHandle.Null; @@ -132,6 +268,23 @@ namespace Ryujinx.Graphics.Vulkan return Unsafe.As(ref handle64); } + public ScopedTemporaryBuffer ReserveOrCreate(VulkanRenderer gd, CommandBufferScoped cbs, int size) + { + StagingBufferReserved? result = StagingBuffer.TryReserveData(cbs, size); + + if (result.HasValue) + { + return new ScopedTemporaryBuffer(this, result.Value.Buffer, StagingBuffer.Handle, result.Value.Offset, result.Value.Size, true); + } + else + { + // Create a temporary buffer. + BufferHandle handle = CreateWithHandle(gd, size, out BufferHolder holder); + + return new ScopedTemporaryBuffer(this, holder, handle, 0, size, false); + } + } + public unsafe MemoryRequirements GetHostImportedUsageRequirements(VulkanRenderer gd) { var usage = HostImportedBufferUsageFlags; @@ -163,6 +316,7 @@ namespace Ryujinx.Graphics.Vulkan int size, BufferAllocationType type, bool forConditionalRendering = false, + bool sparseCompatible = false, BufferAllocationType fallbackType = BufferAllocationType.Auto) { var usage = DefaultBufferUsageFlags; @@ -187,6 +341,11 @@ namespace Ryujinx.Graphics.Vulkan gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out var buffer).ThrowOnError(); gd.Api.GetBufferMemoryRequirements(_device, buffer, out var requirements); + if (sparseCompatible) + { + requirements.Alignment = Math.Max(requirements.Alignment, Constants.SparseBufferAlignment); + } + MemoryAllocation allocation; do @@ -227,6 +386,7 @@ namespace Ryujinx.Graphics.Vulkan VulkanRenderer gd, int size, bool forConditionalRendering = false, + bool sparseCompatible = false, BufferAllocationType baseType = BufferAllocationType.HostMapped, BufferHandle storageHint = default) { @@ -255,7 +415,7 @@ namespace Ryujinx.Graphics.Vulkan } (VkBuffer buffer, MemoryAllocation allocation, BufferAllocationType resultType) = - CreateBacking(gd, size, type, forConditionalRendering); + CreateBacking(gd, size, type, forConditionalRendering, sparseCompatible); if (buffer.Handle != 0) { @@ -522,13 +682,14 @@ namespace Ryujinx.Graphics.Vulkan { if (disposing) { + StagingBuffer.Dispose(); + foreach (BufferHolder buffer in _buffers) { buffer.Dispose(); } _buffers.Clear(); - StagingBuffer.Dispose(); } } diff --git a/src/Ryujinx.Graphics.Vulkan/BufferMirrorRangeList.cs b/src/Ryujinx.Graphics.Vulkan/BufferMirrorRangeList.cs index 9e0b7244a..5722ca1ac 100644 --- a/src/Ryujinx.Graphics.Vulkan/BufferMirrorRangeList.cs +++ b/src/Ryujinx.Graphics.Vulkan/BufferMirrorRangeList.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.Graphics.Vulkan/BufferState.cs b/src/Ryujinx.Graphics.Vulkan/BufferState.cs index 198ee54d4..d585dd53c 100644 --- a/src/Ryujinx.Graphics.Vulkan/BufferState.cs +++ b/src/Ryujinx.Graphics.Vulkan/BufferState.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Graphics.Vulkan { diff --git a/src/Ryujinx.Graphics.Vulkan/BufferUsageBitmap.cs b/src/Ryujinx.Graphics.Vulkan/BufferUsageBitmap.cs index 19dcaccd9..8cf6a7eaa 100644 --- a/src/Ryujinx.Graphics.Vulkan/BufferUsageBitmap.cs +++ b/src/Ryujinx.Graphics.Vulkan/BufferUsageBitmap.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Vulkan +namespace Ryujinx.Graphics.Vulkan { internal class BufferUsageBitmap { diff --git a/src/Ryujinx.Graphics.Vulkan/CommandBufferPool.cs b/src/Ryujinx.Graphics.Vulkan/CommandBufferPool.cs index 4d3b8640f..61cfbb6ec 100644 --- a/src/Ryujinx.Graphics.Vulkan/CommandBufferPool.cs +++ b/src/Ryujinx.Graphics.Vulkan/CommandBufferPool.cs @@ -1,4 +1,4 @@ -using Silk.NET.Vulkan; +using Silk.NET.Vulkan; using System; using System.Collections.Generic; using System.Diagnostics; diff --git a/src/Ryujinx.Graphics.Vulkan/CommandBufferScoped.cs b/src/Ryujinx.Graphics.Vulkan/CommandBufferScoped.cs index 1d9e14bb2..270cdc6e6 100644 --- a/src/Ryujinx.Graphics.Vulkan/CommandBufferScoped.cs +++ b/src/Ryujinx.Graphics.Vulkan/CommandBufferScoped.cs @@ -1,4 +1,4 @@ -using Silk.NET.Vulkan; +using Silk.NET.Vulkan; using System; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.Graphics.Vulkan/Constants.cs b/src/Ryujinx.Graphics.Vulkan/Constants.cs index f43d815ab..cd6122112 100644 --- a/src/Ryujinx.Graphics.Vulkan/Constants.cs +++ b/src/Ryujinx.Graphics.Vulkan/Constants.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Vulkan +namespace Ryujinx.Graphics.Vulkan { static class Constants { @@ -16,5 +16,7 @@ public const int MaxStorageBufferBindings = MaxStorageBuffersPerStage * MaxShaderStages; public const int MaxTextureBindings = MaxTexturesPerStage * MaxShaderStages; public const int MaxImageBindings = MaxImagesPerStage * MaxShaderStages; + + public const ulong SparseBufferAlignment = 0x10000; } } diff --git a/src/Ryujinx.Graphics.Vulkan/DescriptorSetTemplate.cs b/src/Ryujinx.Graphics.Vulkan/DescriptorSetTemplate.cs new file mode 100644 index 000000000..0c0004b95 --- /dev/null +++ b/src/Ryujinx.Graphics.Vulkan/DescriptorSetTemplate.cs @@ -0,0 +1,145 @@ +using Ryujinx.Graphics.GAL; +using Silk.NET.Vulkan; +using System; +using System.Runtime.CompilerServices; + +namespace Ryujinx.Graphics.Vulkan +{ + class DescriptorSetTemplate : IDisposable + { + private readonly VulkanRenderer _gd; + private readonly Device _device; + + public readonly DescriptorUpdateTemplate Template; + public readonly int Size; + + public unsafe DescriptorSetTemplate(VulkanRenderer gd, Device device, ResourceBindingSegment[] segments, PipelineLayoutCacheEntry plce, PipelineBindPoint pbp, int setIndex) + { + _gd = gd; + _device = device; + + // Create a template from the set usages. Assumes the descriptor set is updated in segment order then binding order. + + DescriptorUpdateTemplateEntry* entries = stackalloc DescriptorUpdateTemplateEntry[segments.Length]; + nuint structureOffset = 0; + + for (int seg = 0; seg < segments.Length; seg++) + { + ResourceBindingSegment segment = segments[seg]; + + int binding = segment.Binding; + int count = segment.Count; + + if (setIndex == PipelineBase.UniformSetIndex) + { + entries[seg] = new DescriptorUpdateTemplateEntry() + { + DescriptorType = DescriptorType.UniformBuffer, + DstBinding = (uint)binding, + DescriptorCount = (uint)count, + Offset = structureOffset, + Stride = (nuint)Unsafe.SizeOf() + }; + + structureOffset += (nuint)(Unsafe.SizeOf() * count); + } + else if (setIndex == PipelineBase.StorageSetIndex) + { + entries[seg] = new DescriptorUpdateTemplateEntry() + { + DescriptorType = DescriptorType.StorageBuffer, + DstBinding = (uint)binding, + DescriptorCount = (uint)count, + Offset = structureOffset, + Stride = (nuint)Unsafe.SizeOf() + }; + + structureOffset += (nuint)(Unsafe.SizeOf() * count); + } + else if (setIndex == PipelineBase.TextureSetIndex) + { + if (segment.Type != ResourceType.BufferTexture) + { + entries[seg] = new DescriptorUpdateTemplateEntry() + { + DescriptorType = DescriptorType.CombinedImageSampler, + DstBinding = (uint)binding, + DescriptorCount = (uint)count, + Offset = structureOffset, + Stride = (nuint)Unsafe.SizeOf() + }; + + structureOffset += (nuint)(Unsafe.SizeOf() * count); + } + else + { + entries[seg] = new DescriptorUpdateTemplateEntry() + { + DescriptorType = DescriptorType.UniformTexelBuffer, + DstBinding = (uint)binding, + DescriptorCount = (uint)count, + Offset = structureOffset, + Stride = (nuint)Unsafe.SizeOf() + }; + + structureOffset += (nuint)(Unsafe.SizeOf() * count); + } + } + else if (setIndex == PipelineBase.ImageSetIndex) + { + if (segment.Type != ResourceType.BufferImage) + { + entries[seg] = new DescriptorUpdateTemplateEntry() + { + DescriptorType = DescriptorType.StorageImage, + DstBinding = (uint)binding, + DescriptorCount = (uint)count, + Offset = structureOffset, + Stride = (nuint)Unsafe.SizeOf() + }; + + structureOffset += (nuint)(Unsafe.SizeOf() * count); + } + else + { + entries[seg] = new DescriptorUpdateTemplateEntry() + { + DescriptorType = DescriptorType.StorageTexelBuffer, + DstBinding = (uint)binding, + DescriptorCount = (uint)count, + Offset = structureOffset, + Stride = (nuint)Unsafe.SizeOf() + }; + + structureOffset += (nuint)(Unsafe.SizeOf() * count); + } + } + } + + Size = (int)structureOffset; + + var info = new DescriptorUpdateTemplateCreateInfo() + { + SType = StructureType.DescriptorUpdateTemplateCreateInfo, + DescriptorUpdateEntryCount = (uint)segments.Length, + PDescriptorUpdateEntries = entries, + + TemplateType = DescriptorUpdateTemplateType.DescriptorSet, + DescriptorSetLayout = plce.DescriptorSetLayouts[setIndex], + PipelineBindPoint = pbp, + PipelineLayout = plce.PipelineLayout, + Set = (uint)setIndex, + }; + + DescriptorUpdateTemplate result; + gd.Api.CreateDescriptorUpdateTemplate(device, &info, null, &result).ThrowOnError(); + + Template = result; + } + + public unsafe void Dispose() + { + _gd.Api.DestroyDescriptorUpdateTemplate(_device, Template, null); + } + } +} diff --git a/src/Ryujinx.Graphics.Vulkan/DescriptorSetTemplateUpdater.cs b/src/Ryujinx.Graphics.Vulkan/DescriptorSetTemplateUpdater.cs new file mode 100644 index 000000000..1eb9dce75 --- /dev/null +++ b/src/Ryujinx.Graphics.Vulkan/DescriptorSetTemplateUpdater.cs @@ -0,0 +1,65 @@ +using Ryujinx.Common; +using Silk.NET.Vulkan; +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Ryujinx.Graphics.Vulkan +{ + ref struct DescriptorSetTemplateWriter + { + private Span _data; + + public DescriptorSetTemplateWriter(Span data) + { + _data = data; + } + + public void Push(ReadOnlySpan values) where T : unmanaged + { + Span target = MemoryMarshal.Cast(_data); + + values.CopyTo(target); + + _data = _data[(Unsafe.SizeOf() * values.Length)..]; + } + } + + unsafe class DescriptorSetTemplateUpdater : IDisposable + { + private const int SizeGranularity = 512; + + private DescriptorSetTemplate _activeTemplate; + private NativeArray _data; + + private void EnsureSize(int size) + { + if (_data == null || _data.Length < size) + { + _data?.Dispose(); + + int dataSize = BitUtils.AlignUp(size, SizeGranularity); + _data = new NativeArray(dataSize); + } + } + + public DescriptorSetTemplateWriter Begin(DescriptorSetTemplate template) + { + _activeTemplate = template; + + EnsureSize(template.Size); + + return new DescriptorSetTemplateWriter(new Span(_data.Pointer, template.Size)); + } + + public void Commit(VulkanRenderer gd, Device device, DescriptorSet set) + { + gd.Api.UpdateDescriptorSetWithTemplate(device, set, _activeTemplate.Template, _data.Pointer); + } + + public void Dispose() + { + _data?.Dispose(); + } + } +} diff --git a/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs b/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs index a9a92df1d..6615d8ce0 100644 --- a/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs +++ b/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Shader; using Silk.NET.Vulkan; @@ -35,6 +35,7 @@ namespace Ryujinx.Graphics.Vulkan } private readonly VulkanRenderer _gd; + private readonly Device _device; private readonly PipelineBase _pipeline; private ShaderCollection _program; @@ -54,6 +55,8 @@ namespace Ryujinx.Graphics.Vulkan private readonly BufferView[] _bufferTextures; private readonly BufferView[] _bufferImages; + private readonly DescriptorSetTemplateUpdater _templateUpdater; + private BitMapStruct> _uniformSet; private BitMapStruct> _storageSet; private BitMapStruct> _uniformMirrored; @@ -78,9 +81,10 @@ namespace Ryujinx.Graphics.Vulkan private readonly TextureView _dummyTexture; private readonly SamplerHolder _dummySampler; - public DescriptorSetUpdater(VulkanRenderer gd, PipelineBase pipeline) + public DescriptorSetUpdater(VulkanRenderer gd, Device device, PipelineBase pipeline) { _gd = gd; + _device = device; _pipeline = pipeline; // Some of the bindings counts needs to be multiplied by 2 because we have buffer and @@ -152,6 +156,8 @@ namespace Ryujinx.Graphics.Vulkan 0, 0, 1f)); + + _templateUpdater = new(); } public void Initialize() @@ -509,6 +515,10 @@ namespace Ryujinx.Graphics.Vulkan } } + DescriptorSetTemplate template = program.Templates[setIndex]; + + DescriptorSetTemplateWriter tu = _templateUpdater.Begin(template); + foreach (ResourceBindingSegment segment in bindingSegments) { int binding = segment.Binding; @@ -531,7 +541,8 @@ namespace Ryujinx.Graphics.Vulkan } ReadOnlySpan uniformBuffers = _uniformBuffers; - dsc.UpdateBuffers(0, binding, uniformBuffers.Slice(binding, count), DescriptorType.UniformBuffer); + + tu.Push(uniformBuffers.Slice(binding, count)); } else if (setIndex == PipelineBase.StorageSetIndex) { @@ -556,7 +567,8 @@ namespace Ryujinx.Graphics.Vulkan } ReadOnlySpan storageBuffers = _storageBuffers; - dsc.UpdateBuffers(0, binding, storageBuffers.Slice(binding, count), DescriptorType.StorageBuffer); + + tu.Push(storageBuffers.Slice(binding, count)); } else if (setIndex == PipelineBase.TextureSetIndex) { @@ -582,7 +594,7 @@ namespace Ryujinx.Graphics.Vulkan } } - dsc.UpdateImages(0, binding, textures[..count], DescriptorType.CombinedImageSampler); + tu.Push(textures[..count]); } else { @@ -593,7 +605,7 @@ namespace Ryujinx.Graphics.Vulkan bufferTextures[i] = _bufferTextureRefs[binding + i]?.GetBufferView(cbs, false) ?? default; } - dsc.UpdateBufferImages(0, binding, bufferTextures[..count], DescriptorType.UniformTexelBuffer); + tu.Push(bufferTextures[..count]); } } else if (setIndex == PipelineBase.ImageSetIndex) @@ -607,7 +619,7 @@ namespace Ryujinx.Graphics.Vulkan images[i].ImageView = _imageRefs[binding + i]?.Get(cbs).Value ?? default; } - dsc.UpdateImages(0, binding, images[..count], DescriptorType.StorageImage); + tu.Push(images[..count]); } else { @@ -618,12 +630,13 @@ namespace Ryujinx.Graphics.Vulkan bufferImages[i] = _bufferImageRefs[binding + i]?.GetBufferView(cbs, _bufferImageFormats[binding + i], true) ?? default; } - dsc.UpdateBufferImages(0, binding, bufferImages[..count], DescriptorType.StorageTexelBuffer); + tu.Push(bufferImages[..count]); } } } var sets = dsc.GetSets(); + _templateUpdater.Commit(_gd, _device, sets[0]); _gd.Api.CmdBindDescriptorSets(cbs.CommandBuffer, pbp, _program.PipelineLayout, (uint)setIndex, 1, sets, 0, ReadOnlySpan.Empty); } @@ -736,6 +749,7 @@ namespace Ryujinx.Graphics.Vulkan { _dummyTexture.Dispose(); _dummySampler.Dispose(); + _templateUpdater.Dispose(); } } diff --git a/src/Ryujinx.Graphics.Vulkan/DisposableBuffer.cs b/src/Ryujinx.Graphics.Vulkan/DisposableBuffer.cs index ba52c2575..98e0e9dd2 100644 --- a/src/Ryujinx.Graphics.Vulkan/DisposableBuffer.cs +++ b/src/Ryujinx.Graphics.Vulkan/DisposableBuffer.cs @@ -1,4 +1,4 @@ -using Silk.NET.Vulkan; +using Silk.NET.Vulkan; using System; using Buffer = Silk.NET.Vulkan.Buffer; diff --git a/src/Ryujinx.Graphics.Vulkan/DisposableBufferView.cs b/src/Ryujinx.Graphics.Vulkan/DisposableBufferView.cs index e81ca412e..dc9efc8ae 100644 --- a/src/Ryujinx.Graphics.Vulkan/DisposableBufferView.cs +++ b/src/Ryujinx.Graphics.Vulkan/DisposableBufferView.cs @@ -1,4 +1,4 @@ -using Silk.NET.Vulkan; +using Silk.NET.Vulkan; using System; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.Graphics.Vulkan/DisposableFramebuffer.cs b/src/Ryujinx.Graphics.Vulkan/DisposableFramebuffer.cs index 5b1953547..e0e536470 100644 --- a/src/Ryujinx.Graphics.Vulkan/DisposableFramebuffer.cs +++ b/src/Ryujinx.Graphics.Vulkan/DisposableFramebuffer.cs @@ -1,4 +1,4 @@ -using Silk.NET.Vulkan; +using Silk.NET.Vulkan; using System; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.Graphics.Vulkan/DisposableImage.cs b/src/Ryujinx.Graphics.Vulkan/DisposableImage.cs index c76091b73..98860cc0a 100644 --- a/src/Ryujinx.Graphics.Vulkan/DisposableImage.cs +++ b/src/Ryujinx.Graphics.Vulkan/DisposableImage.cs @@ -1,4 +1,4 @@ -using Silk.NET.Vulkan; +using Silk.NET.Vulkan; using System; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.Graphics.Vulkan/DisposableImageView.cs b/src/Ryujinx.Graphics.Vulkan/DisposableImageView.cs index 3b3bf6adf..d3b6224c1 100644 --- a/src/Ryujinx.Graphics.Vulkan/DisposableImageView.cs +++ b/src/Ryujinx.Graphics.Vulkan/DisposableImageView.cs @@ -1,4 +1,4 @@ -using Silk.NET.Vulkan; +using Silk.NET.Vulkan; using System; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.Graphics.Vulkan/DisposableMemory.cs b/src/Ryujinx.Graphics.Vulkan/DisposableMemory.cs index 638989acd..c8d135b27 100644 --- a/src/Ryujinx.Graphics.Vulkan/DisposableMemory.cs +++ b/src/Ryujinx.Graphics.Vulkan/DisposableMemory.cs @@ -1,4 +1,4 @@ -using Silk.NET.Vulkan; +using Silk.NET.Vulkan; using System; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.Graphics.Vulkan/DisposablePipeline.cs b/src/Ryujinx.Graphics.Vulkan/DisposablePipeline.cs index 6e5cf4dbc..10e88a041 100644 --- a/src/Ryujinx.Graphics.Vulkan/DisposablePipeline.cs +++ b/src/Ryujinx.Graphics.Vulkan/DisposablePipeline.cs @@ -1,4 +1,4 @@ -using Silk.NET.Vulkan; +using Silk.NET.Vulkan; using System; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.Graphics.Vulkan/DisposableRenderPass.cs b/src/Ryujinx.Graphics.Vulkan/DisposableRenderPass.cs index 65652f413..f42dbeff5 100644 --- a/src/Ryujinx.Graphics.Vulkan/DisposableRenderPass.cs +++ b/src/Ryujinx.Graphics.Vulkan/DisposableRenderPass.cs @@ -1,4 +1,4 @@ -using Silk.NET.Vulkan; +using Silk.NET.Vulkan; using System; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.Graphics.Vulkan/DisposableSampler.cs b/src/Ryujinx.Graphics.Vulkan/DisposableSampler.cs index 4788b192a..7e04c47aa 100644 --- a/src/Ryujinx.Graphics.Vulkan/DisposableSampler.cs +++ b/src/Ryujinx.Graphics.Vulkan/DisposableSampler.cs @@ -1,4 +1,4 @@ -using Silk.NET.Vulkan; +using Silk.NET.Vulkan; using System; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.Graphics.Vulkan/Effects/FsrScalingFilter.cs b/src/Ryujinx.Graphics.Vulkan/Effects/FsrScalingFilter.cs index 23acdcf8f..5c0fc468b 100644 --- a/src/Ryujinx.Graphics.Vulkan/Effects/FsrScalingFilter.cs +++ b/src/Ryujinx.Graphics.Vulkan/Effects/FsrScalingFilter.cs @@ -142,19 +142,18 @@ namespace Ryujinx.Graphics.Vulkan.Effects }; int rangeSize = dimensionsBuffer.Length * sizeof(float); - var bufferHandle = _renderer.BufferManager.CreateWithHandle(_renderer, rangeSize); - _renderer.BufferManager.SetData(bufferHandle, 0, dimensionsBuffer); + using var buffer = _renderer.BufferManager.ReserveOrCreate(_renderer, cbs, rangeSize); + buffer.Holder.SetDataUnchecked(buffer.Offset, dimensionsBuffer); - ReadOnlySpan sharpeningBuffer = stackalloc float[] { 1.5f - (Level * 0.01f * 1.5f) }; - var sharpeningBufferHandle = _renderer.BufferManager.CreateWithHandle(_renderer, sizeof(float)); - _renderer.BufferManager.SetData(sharpeningBufferHandle, 0, sharpeningBuffer); + ReadOnlySpan sharpeningBufferData = stackalloc float[] { 1.5f - (Level * 0.01f * 1.5f) }; + using var sharpeningBuffer = _renderer.BufferManager.ReserveOrCreate(_renderer, cbs, sizeof(float)); + sharpeningBuffer.Holder.SetDataUnchecked(sharpeningBuffer.Offset, sharpeningBufferData); int threadGroupWorkRegionDim = 16; int dispatchX = (width + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim; int dispatchY = (height + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim; - var bufferRanges = new BufferRange(bufferHandle, 0, rangeSize); - _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(2, bufferRanges) }); + _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(2, buffer.Range) }); _pipeline.SetImage(0, _intermediaryTexture, FormatTable.ConvertRgba8SrgbToUnorm(view.Info.Format)); _pipeline.DispatchCompute(dispatchX, dispatchY, 1); _pipeline.ComputeBarrier(); @@ -162,16 +161,12 @@ namespace Ryujinx.Graphics.Vulkan.Effects // Sharpening pass _pipeline.SetProgram(_sharpeningProgram); _pipeline.SetTextureAndSampler(ShaderStage.Compute, 1, _intermediaryTexture, _sampler); - var sharpeningRange = new BufferRange(sharpeningBufferHandle, 0, sizeof(float)); - _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(4, sharpeningRange) }); + _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(4, sharpeningBuffer.Range) }); _pipeline.SetImage(0, destinationTexture); _pipeline.DispatchCompute(dispatchX, dispatchY, 1); _pipeline.ComputeBarrier(); _pipeline.Finish(); - - _renderer.BufferManager.Delete(bufferHandle); - _renderer.BufferManager.Delete(sharpeningBufferHandle); } } } diff --git a/src/Ryujinx.Graphics.Vulkan/Effects/FxaaPostProcessingEffect.cs b/src/Ryujinx.Graphics.Vulkan/Effects/FxaaPostProcessingEffect.cs index 7729934f2..a7dd8eee8 100644 --- a/src/Ryujinx.Graphics.Vulkan/Effects/FxaaPostProcessingEffect.cs +++ b/src/Ryujinx.Graphics.Vulkan/Effects/FxaaPostProcessingEffect.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Shader; using Ryujinx.Graphics.Shader.Translation; @@ -66,12 +66,11 @@ namespace Ryujinx.Graphics.Vulkan.Effects ReadOnlySpan resolutionBuffer = stackalloc float[] { view.Width, view.Height }; int rangeSize = resolutionBuffer.Length * sizeof(float); - var bufferHandle = _renderer.BufferManager.CreateWithHandle(_renderer, rangeSize); + using var buffer = _renderer.BufferManager.ReserveOrCreate(_renderer, cbs, rangeSize); - _renderer.BufferManager.SetData(bufferHandle, 0, resolutionBuffer); + buffer.Holder.SetDataUnchecked(buffer.Offset, resolutionBuffer); - var bufferRanges = new BufferRange(bufferHandle, 0, rangeSize); - _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(2, bufferRanges) }); + _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(2, buffer.Range) }); var dispatchX = BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize); var dispatchY = BitUtils.DivRoundUp(view.Height, IPostProcessingEffect.LocalGroupSize); @@ -79,7 +78,6 @@ namespace Ryujinx.Graphics.Vulkan.Effects _pipeline.SetImage(0, _texture, FormatTable.ConvertRgba8SrgbToUnorm(view.Info.Format)); _pipeline.DispatchCompute(dispatchX, dispatchY, 1); - _renderer.BufferManager.Delete(bufferHandle); _pipeline.ComputeBarrier(); _pipeline.Finish(); diff --git a/src/Ryujinx.Graphics.Vulkan/Effects/SmaaPostProcessingEffect.cs b/src/Ryujinx.Graphics.Vulkan/Effects/SmaaPostProcessingEffect.cs index c521f2273..be392fe0e 100644 --- a/src/Ryujinx.Graphics.Vulkan/Effects/SmaaPostProcessingEffect.cs +++ b/src/Ryujinx.Graphics.Vulkan/Effects/SmaaPostProcessingEffect.cs @@ -215,11 +215,10 @@ namespace Ryujinx.Graphics.Vulkan.Effects ReadOnlySpan resolutionBuffer = stackalloc float[] { view.Width, view.Height }; int rangeSize = resolutionBuffer.Length * sizeof(float); - var bufferHandle = _renderer.BufferManager.CreateWithHandle(_renderer, rangeSize); + using var buffer = _renderer.BufferManager.ReserveOrCreate(_renderer, cbs, rangeSize); - _renderer.BufferManager.SetData(bufferHandle, 0, resolutionBuffer); - var bufferRanges = new BufferRange(bufferHandle, 0, rangeSize); - _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(2, bufferRanges) }); + buffer.Holder.SetDataUnchecked(buffer.Offset, resolutionBuffer); + _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(2, buffer.Range) }); _pipeline.SetImage(0, _edgeOutputTexture, FormatTable.ConvertRgba8SrgbToUnorm(view.Info.Format)); _pipeline.DispatchCompute(dispatchX, dispatchY, 1); _pipeline.ComputeBarrier(); @@ -245,8 +244,6 @@ namespace Ryujinx.Graphics.Vulkan.Effects _pipeline.Finish(); - _renderer.BufferManager.Delete(bufferHandle); - return _outputTexture; } @@ -260,7 +257,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects scissors[0] = new Rectangle(0, 0, texture.Width, texture.Height); - _pipeline.SetRenderTarget(texture.GetImageViewForAttachment(), (uint)texture.Width, (uint)texture.Height, false, texture.VkFormat); + _pipeline.SetRenderTarget(texture, (uint)texture.Width, (uint)texture.Height); _pipeline.SetRenderTargetColorMasks(colorMasks); _pipeline.SetScissors(scissors); _pipeline.ClearRenderTargetColor(0, 0, 1, new ColorF(0f, 0f, 0f, 1f)); diff --git a/src/Ryujinx.Graphics.Vulkan/EnumConversion.cs b/src/Ryujinx.Graphics.Vulkan/EnumConversion.cs index f478c58e2..e10027057 100644 --- a/src/Ryujinx.Graphics.Vulkan/EnumConversion.cs +++ b/src/Ryujinx.Graphics.Vulkan/EnumConversion.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Shader; using Silk.NET.Vulkan; @@ -424,12 +424,12 @@ namespace Ryujinx.Graphics.Vulkan public static BufferAllocationType Convert(this BufferAccess access) { - return access switch + if (access.HasFlag(BufferAccess.FlushPersistent) || access.HasFlag(BufferAccess.Stream)) { - BufferAccess.FlushPersistent => BufferAllocationType.HostMapped, - BufferAccess.Stream => BufferAllocationType.HostMapped, - _ => BufferAllocationType.Auto, - }; + return BufferAllocationType.HostMapped; + } + + return BufferAllocationType.Auto; } private static T2 LogInvalidAndReturn(T1 value, string name, T2 defaultValue = default) diff --git a/src/Ryujinx.Graphics.Vulkan/FenceHelper.cs b/src/Ryujinx.Graphics.Vulkan/FenceHelper.cs index d6731c0eb..6649af7f5 100644 --- a/src/Ryujinx.Graphics.Vulkan/FenceHelper.cs +++ b/src/Ryujinx.Graphics.Vulkan/FenceHelper.cs @@ -1,4 +1,4 @@ -using Silk.NET.Vulkan; +using Silk.NET.Vulkan; using System; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.Graphics.Vulkan/FenceHolder.cs b/src/Ryujinx.Graphics.Vulkan/FenceHolder.cs index d57d95ec1..4f0a87160 100644 --- a/src/Ryujinx.Graphics.Vulkan/FenceHolder.cs +++ b/src/Ryujinx.Graphics.Vulkan/FenceHolder.cs @@ -1,4 +1,4 @@ -using Silk.NET.Vulkan; +using Silk.NET.Vulkan; using System; using System.Threading; diff --git a/src/Ryujinx.Graphics.Vulkan/FormatTable.cs b/src/Ryujinx.Graphics.Vulkan/FormatTable.cs index eacfa0dbf..a12e3efd0 100644 --- a/src/Ryujinx.Graphics.Vulkan/FormatTable.cs +++ b/src/Ryujinx.Graphics.Vulkan/FormatTable.cs @@ -1,5 +1,6 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using System; +using System.Collections.Generic; using VkFormat = Silk.NET.Vulkan.Format; namespace Ryujinx.Graphics.Vulkan @@ -7,10 +8,12 @@ namespace Ryujinx.Graphics.Vulkan static class FormatTable { private static readonly VkFormat[] _table; + private static readonly Dictionary _reverseMap; static FormatTable() { _table = new VkFormat[Enum.GetNames(typeof(Format)).Length]; + _reverseMap = new Dictionary(); #pragma warning disable IDE0055 // Disable formatting Add(Format.R8Unorm, VkFormat.R8Unorm); @@ -164,6 +167,7 @@ namespace Ryujinx.Graphics.Vulkan private static void Add(Format format, VkFormat vkFormat) { _table[(int)format] = vkFormat; + _reverseMap[vkFormat] = format; } public static VkFormat GetFormat(Format format) @@ -171,6 +175,16 @@ namespace Ryujinx.Graphics.Vulkan return _table[(int)format]; } + public static Format GetFormat(VkFormat format) + { + if (!_reverseMap.TryGetValue(format, out Format result)) + { + return Format.B8G8R8A8Unorm; + } + + return result; + } + public static Format ConvertRgba8SrgbToUnorm(Format format) { return format switch diff --git a/src/Ryujinx.Graphics.Vulkan/FramebufferParams.cs b/src/Ryujinx.Graphics.Vulkan/FramebufferParams.cs index 662bb80f8..af22f2656 100644 --- a/src/Ryujinx.Graphics.Vulkan/FramebufferParams.cs +++ b/src/Ryujinx.Graphics.Vulkan/FramebufferParams.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; using System; using System.Linq; @@ -12,6 +12,8 @@ namespace Ryujinx.Graphics.Vulkan private readonly Auto[] _attachments; private readonly TextureView[] _colors; private readonly TextureView _depthStencil; + private readonly TextureView[] _colorsCanonical; + private readonly TextureView _baseAttachment; private readonly uint _validColorAttachments; public uint Width { get; } @@ -28,25 +30,31 @@ namespace Ryujinx.Graphics.Vulkan public bool HasDepthStencil { get; } public int ColorAttachmentsCount => AttachmentsCount - (HasDepthStencil ? 1 : 0); - public FramebufferParams( - Device device, - Auto view, - uint width, - uint height, - uint samples, - bool isDepthStencil, - VkFormat format) + public FramebufferParams(Device device, TextureView view, uint width, uint height) { + bool isDepthStencil = view.Info.Format.IsDepthOrStencil(); + _device = device; - _attachments = new[] { view }; + _attachments = new[] { view.GetImageViewForAttachment() }; _validColorAttachments = isDepthStencil ? 0u : 1u; + _baseAttachment = view; + + if (isDepthStencil) + { + _depthStencil = view; + } + else + { + _colors = new TextureView[] { view }; + _colorsCanonical = _colors; + } Width = width; Height = height; Layers = 1; - AttachmentSamples = new[] { samples }; - AttachmentFormats = new[] { format }; + AttachmentSamples = new[] { (uint)view.Info.Samples }; + AttachmentFormats = new[] { view.VkFormat }; AttachmentIndices = isDepthStencil ? Array.Empty() : new[] { 0 }; AttachmentsCount = 1; @@ -64,6 +72,7 @@ namespace Ryujinx.Graphics.Vulkan _attachments = new Auto[count]; _colors = new TextureView[colorsCount]; + _colorsCanonical = colors.Select(color => color is TextureView view && view.Valid ? view : null).ToArray(); AttachmentSamples = new uint[count]; AttachmentFormats = new VkFormat[count]; @@ -86,6 +95,7 @@ namespace Ryujinx.Graphics.Vulkan _attachments[index] = texture.GetImageViewForAttachment(); _colors[index] = texture; _validColorAttachments |= 1u << bindIndex; + _baseAttachment = texture; AttachmentSamples[index] = (uint)texture.Info.Samples; AttachmentFormats[index] = texture.VkFormat; @@ -115,6 +125,7 @@ namespace Ryujinx.Graphics.Vulkan { _attachments[count - 1] = dsTexture.GetImageViewForAttachment(); _depthStencil = dsTexture; + _baseAttachment ??= dsTexture; AttachmentSamples[count - 1] = (uint)dsTexture.Info.Samples; AttachmentFormats[count - 1] = dsTexture.VkFormat; @@ -251,19 +262,11 @@ namespace Ryujinx.Graphics.Vulkan public void InsertClearBarrier(CommandBufferScoped cbs, int index) { - if (_colors != null) - { - int realIndex = Array.IndexOf(AttachmentIndices, index); - - if (realIndex != -1) - { - _colors[realIndex].Storage?.InsertReadToWriteBarrier( - cbs, - AccessFlags.ColorAttachmentWriteBit, - PipelineStageFlags.ColorAttachmentOutputBit, - insideRenderPass: true); - } - } + _colorsCanonical?[index]?.Storage?.InsertReadToWriteBarrier( + cbs, + AccessFlags.ColorAttachmentWriteBit, + PipelineStageFlags.ColorAttachmentOutputBit, + insideRenderPass: true); } public void InsertClearBarrierDS(CommandBufferScoped cbs) @@ -274,5 +277,61 @@ namespace Ryujinx.Graphics.Vulkan PipelineStageFlags.LateFragmentTestsBit, insideRenderPass: true); } + + public TextureView[] GetAttachmentViews() + { + var result = new TextureView[_attachments.Length]; + + _colors?.CopyTo(result, 0); + + if (_depthStencil != null) + { + result[^1] = _depthStencil; + } + + return result; + } + + public RenderPassCacheKey GetRenderPassCacheKey() + { + return new RenderPassCacheKey(_depthStencil, _colorsCanonical); + } + + public void InsertLoadOpBarriers(CommandBufferScoped cbs) + { + if (_colors != null) + { + foreach (var color in _colors) + { + // If Clear or DontCare were used, this would need to be write bit. + color.Storage?.InsertWriteToReadBarrier(cbs, AccessFlags.ColorAttachmentReadBit, PipelineStageFlags.ColorAttachmentOutputBit); + color.Storage?.SetModification(AccessFlags.ColorAttachmentWriteBit, PipelineStageFlags.ColorAttachmentOutputBit); + } + } + + if (_depthStencil != null) + { + _depthStencil.Storage?.InsertWriteToReadBarrier(cbs, AccessFlags.DepthStencilAttachmentReadBit, PipelineStageFlags.EarlyFragmentTestsBit); + _depthStencil.Storage?.SetModification(AccessFlags.DepthStencilAttachmentWriteBit, PipelineStageFlags.LateFragmentTestsBit); + } + } + + public (Auto renderPass, Auto framebuffer) GetPassAndFramebuffer( + VulkanRenderer gd, + Device device, + CommandBufferScoped cbs) + { + return _baseAttachment.GetPassAndFramebuffer(gd, device, cbs, this); + } + + public TextureView GetColorView(int index) + { + return _colorsCanonical[index]; + } + + public TextureView GetDepthStencilView() + { + return _depthStencil; + } } } diff --git a/src/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs b/src/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs index 32e941dba..98c777eed 100644 --- a/src/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs +++ b/src/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs @@ -1,4 +1,4 @@ -using Silk.NET.Vulkan; +using Silk.NET.Vulkan; using System; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.Graphics.Vulkan/HashTableSlim.cs b/src/Ryujinx.Graphics.Vulkan/HashTableSlim.cs index 2efe81a60..3796e3c52 100644 --- a/src/Ryujinx.Graphics.Vulkan/HashTableSlim.cs +++ b/src/Ryujinx.Graphics.Vulkan/HashTableSlim.cs @@ -1,5 +1,6 @@ -using System; +using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; namespace Ryujinx.Graphics.Vulkan { @@ -20,20 +21,29 @@ namespace Ryujinx.Graphics.Vulkan public TValue Value; } - private readonly Entry[][] _hashTable = new Entry[TotalBuckets][]; + private struct Bucket + { + public int Length; + public Entry[] Entries; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly Span AsSpan() + { + return Entries == null ? Span.Empty : Entries.AsSpan(0, Length); + } + } + + private readonly Bucket[] _hashTable = new Bucket[TotalBuckets]; public IEnumerable Keys { get { - foreach (Entry[] bucket in _hashTable) + foreach (Bucket bucket in _hashTable) { - if (bucket != null) + for (int i = 0; i < bucket.Length; i++) { - foreach (Entry entry in bucket) - { - yield return entry.Key; - } + yield return bucket.Entries[i].Key; } } } @@ -43,14 +53,11 @@ namespace Ryujinx.Graphics.Vulkan { get { - foreach (Entry[] bucket in _hashTable) + foreach (Bucket bucket in _hashTable) { - if (bucket != null) + for (int i = 0; i < bucket.Length; i++) { - foreach (Entry entry in bucket) - { - yield return entry.Value; - } + yield return bucket.Entries[i].Value; } } } @@ -68,40 +75,64 @@ namespace Ryujinx.Graphics.Vulkan int hashCode = key.GetHashCode(); int bucketIndex = hashCode & TotalBucketsMask; - var bucket = _hashTable[bucketIndex]; - if (bucket != null) + ref var bucket = ref _hashTable[bucketIndex]; + if (bucket.Entries != null) { int index = bucket.Length; - Array.Resize(ref _hashTable[bucketIndex], index + 1); + if (index >= bucket.Entries.Length) + { + Array.Resize(ref bucket.Entries, index + 1); + } - _hashTable[bucketIndex][index] = entry; + bucket.Entries[index] = entry; } else { - _hashTable[bucketIndex] = new[] + bucket.Entries = new[] { entry, }; } + + bucket.Length++; + } + + public bool Remove(ref TKey key) + { + int hashCode = key.GetHashCode(); + + ref var bucket = ref _hashTable[hashCode & TotalBucketsMask]; + var entries = bucket.AsSpan(); + for (int i = 0; i < entries.Length; i++) + { + ref var entry = ref entries[i]; + + if (entry.Hash == hashCode && entry.Key.Equals(ref key)) + { + entries[(i + 1)..].CopyTo(entries[i..]); + bucket.Length--; + + return true; + } + } + + return false; } public bool TryGetValue(ref TKey key, out TValue value) { int hashCode = key.GetHashCode(); - var bucket = _hashTable[hashCode & TotalBucketsMask]; - if (bucket != null) + var entries = _hashTable[hashCode & TotalBucketsMask].AsSpan(); + for (int i = 0; i < entries.Length; i++) { - for (int i = 0; i < bucket.Length; i++) - { - ref var entry = ref bucket[i]; + ref var entry = ref entries[i]; - if (entry.Hash == hashCode && entry.Key.Equals(ref key)) - { - value = entry.Value; - return true; - } + if (entry.Hash == hashCode && entry.Key.Equals(ref key)) + { + value = entry.Value; + return true; } } diff --git a/src/Ryujinx.Graphics.Vulkan/HelperShader.cs b/src/Ryujinx.Graphics.Vulkan/HelperShader.cs index 5be4a9329..c0ded5b3b 100644 --- a/src/Ryujinx.Graphics.Vulkan/HelperShader.cs +++ b/src/Ryujinx.Graphics.Vulkan/HelperShader.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Shader; using Ryujinx.Graphics.Shader.Translation; @@ -256,17 +256,8 @@ namespace Ryujinx.Graphics.Vulkan using var cbs = gd.CommandBufferPool.Rent(); - var dstFormat = dst.VkFormat; - var dstSamples = dst.Info.Samples; - for (int l = 0; l < levels; l++) { - int srcWidth = Math.Max(1, src.Width >> l); - int srcHeight = Math.Max(1, src.Height >> l); - - int dstWidth = Math.Max(1, dst.Width >> l); - int dstHeight = Math.Max(1, dst.Height >> l); - var mipSrcRegion = new Extents2D( srcRegion.X1 >> l, srcRegion.Y1 >> l, @@ -290,11 +281,7 @@ namespace Ryujinx.Graphics.Vulkan gd, cbs, srcView, - dst.GetImageViewForAttachment(), - dstWidth, - dstHeight, - dstSamples, - dstFormat, + dstView, mipSrcRegion, mipDstRegion); } @@ -304,12 +291,7 @@ namespace Ryujinx.Graphics.Vulkan gd, cbs, srcView, - dst.GetImageViewForAttachment(), - dstWidth, - dstHeight, - dstSamples, - dstFormat, - false, + dstView, mipSrcRegion, mipDstRegion, linearFilter, @@ -367,12 +349,7 @@ namespace Ryujinx.Graphics.Vulkan gd, cbs, srcView, - dstView.GetImageViewForAttachment(), - dstView.Width, - dstView.Height, - dstView.Info.Samples, - dstView.VkFormat, - dstView.Info.Format.IsDepthOrStencil(), + dstView, extents, extents, false); @@ -394,12 +371,7 @@ namespace Ryujinx.Graphics.Vulkan VulkanRenderer gd, CommandBufferScoped cbs, TextureView src, - Auto dst, - int dstWidth, - int dstHeight, - int dstSamples, - VkFormat dstFormat, - bool dstIsDepthOrStencil, + TextureView dst, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter, @@ -430,11 +402,11 @@ namespace Ryujinx.Graphics.Vulkan (region[2], region[3]) = (region[3], region[2]); } - var bufferHandle = gd.BufferManager.CreateWithHandle(gd, RegionBufferSize); + using var buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, RegionBufferSize); - gd.BufferManager.SetData(bufferHandle, 0, region); + buffer.Holder.SetDataUnchecked(buffer.Offset, region); - _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, RegionBufferSize)) }); + _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, buffer.Range) }); Span viewports = stackalloc Viewport[1]; @@ -453,6 +425,8 @@ namespace Ryujinx.Graphics.Vulkan 0f, 1f); + bool dstIsDepthOrStencil = dst.Info.Format.IsDepthOrStencil(); + if (dstIsDepthOrStencil) { _pipeline.SetProgram(src.Info.Target.IsMultisample() ? _programDepthBlitMs : _programDepthBlit); @@ -471,7 +445,10 @@ namespace Ryujinx.Graphics.Vulkan _pipeline.SetProgram(_programColorBlit); } - _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, (uint)dstSamples, dstIsDepthOrStencil, dstFormat); + int dstWidth = dst.Width; + int dstHeight = dst.Height; + + _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight); _pipeline.SetRenderTargetColorMasks(new uint[] { 0xf }); _pipeline.SetScissors(stackalloc Rectangle[] { new Rectangle(0, 0, dstWidth, dstHeight) }); @@ -490,19 +467,13 @@ namespace Ryujinx.Graphics.Vulkan } _pipeline.Finish(gd, cbs); - - gd.BufferManager.Delete(bufferHandle); } private void BlitDepthStencil( VulkanRenderer gd, CommandBufferScoped cbs, TextureView src, - Auto dst, - int dstWidth, - int dstHeight, - int dstSamples, - VkFormat dstFormat, + TextureView dst, Extents2D srcRegion, Extents2D dstRegion) { @@ -527,11 +498,11 @@ namespace Ryujinx.Graphics.Vulkan (region[2], region[3]) = (region[3], region[2]); } - var bufferHandle = gd.BufferManager.CreateWithHandle(gd, RegionBufferSize); + using var buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, RegionBufferSize); - gd.BufferManager.SetData(bufferHandle, 0, region); + buffer.Holder.SetDataUnchecked(buffer.Offset, region); - _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, RegionBufferSize)) }); + _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, buffer.Range) }); Span viewports = stackalloc Viewport[1]; @@ -550,7 +521,10 @@ namespace Ryujinx.Graphics.Vulkan 0f, 1f); - _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, (uint)dstSamples, true, dstFormat); + int dstWidth = dst.Width; + int dstHeight = dst.Height; + + _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight); _pipeline.SetScissors(stackalloc Rectangle[] { new Rectangle(0, 0, dstWidth, dstHeight) }); _pipeline.SetViewports(viewports); _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); @@ -582,8 +556,6 @@ namespace Ryujinx.Graphics.Vulkan } _pipeline.Finish(gd, cbs); - - gd.BufferManager.Delete(bufferHandle); } private static TextureView CreateDepthOrStencilView(TextureView depthStencilTexture, DepthStencilMode depthStencilMode) @@ -664,12 +636,11 @@ namespace Ryujinx.Graphics.Vulkan public void Clear( VulkanRenderer gd, - Auto dst, + TextureView dst, ReadOnlySpan clearColor, uint componentMask, int dstWidth, int dstHeight, - VkFormat dstFormat, ComponentType type, Rectangle scissor) { @@ -681,11 +652,11 @@ namespace Ryujinx.Graphics.Vulkan _pipeline.SetCommandBuffer(cbs); - var bufferHandle = gd.BufferManager.CreateWithHandle(gd, ClearColorBufferSize); + using var buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, ClearColorBufferSize); - gd.BufferManager.SetData(bufferHandle, 0, clearColor); + buffer.Holder.SetDataUnchecked(buffer.Offset, clearColor); - _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, ClearColorBufferSize)) }); + _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, buffer.Range) }); Span viewports = stackalloc Viewport[1]; @@ -714,20 +685,18 @@ namespace Ryujinx.Graphics.Vulkan } _pipeline.SetProgram(program); - _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, false, dstFormat); + _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight); _pipeline.SetRenderTargetColorMasks(new[] { componentMask }); _pipeline.SetViewports(viewports); _pipeline.SetScissors(stackalloc Rectangle[] { scissor }); _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); _pipeline.Draw(4, 1, 0, 0); _pipeline.Finish(); - - gd.BufferManager.Delete(bufferHandle); } public void Clear( VulkanRenderer gd, - Auto dst, + TextureView dst, float depthValue, bool depthMask, int stencilValue, @@ -745,11 +714,11 @@ namespace Ryujinx.Graphics.Vulkan _pipeline.SetCommandBuffer(cbs); - var bufferHandle = gd.BufferManager.CreateWithHandle(gd, ClearColorBufferSize); + using var buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, ClearColorBufferSize); - gd.BufferManager.SetData(bufferHandle, 0, stackalloc float[] { depthValue }); + buffer.Holder.SetDataUnchecked(buffer.Offset, stackalloc float[] { depthValue }); - _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, ClearColorBufferSize)) }); + _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, buffer.Range) }); Span viewports = stackalloc Viewport[1]; @@ -763,7 +732,7 @@ namespace Ryujinx.Graphics.Vulkan 1f); _pipeline.SetProgram(_programDepthStencilClear); - _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, true, dstFormat); + _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight); _pipeline.SetViewports(viewports); _pipeline.SetScissors(stackalloc Rectangle[] { scissor }); _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); @@ -771,8 +740,6 @@ namespace Ryujinx.Graphics.Vulkan _pipeline.SetStencilTest(CreateStencilTestDescriptor(stencilMask != 0, stencilValue, 0xff, stencilMask)); _pipeline.Draw(4, 1, 0, 0); _pipeline.Finish(); - - gd.BufferManager.Delete(bufferHandle); } public void DrawTexture( @@ -878,13 +845,13 @@ namespace Ryujinx.Graphics.Vulkan shaderParams[2] = size; shaderParams[3] = srcOffset; - var bufferHandle = gd.BufferManager.CreateWithHandle(gd, ParamsBufferSize); + using var buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, ParamsBufferSize); - gd.BufferManager.SetData(bufferHandle, 0, shaderParams); + buffer.Holder.SetDataUnchecked(buffer.Offset, shaderParams); _pipeline.SetCommandBuffer(cbs); - _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, new BufferRange(bufferHandle, 0, ParamsBufferSize)) }); + _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, buffer.Range) }); Span> sbRanges = new Auto[2]; @@ -896,8 +863,6 @@ namespace Ryujinx.Graphics.Vulkan _pipeline.SetProgram(_programStrideChange); _pipeline.DispatchCompute(1 + elems / ConvertElementsPerWorkgroup, 1, 1); - gd.BufferManager.Delete(bufferHandle); - _pipeline.Finish(gd, cbs); } else @@ -1025,7 +990,7 @@ namespace Ryujinx.Graphics.Vulkan { const int ParamsBufferSize = 4; - Span shaderParams = stackalloc int[sizeof(int)]; + Span shaderParams = stackalloc int[ParamsBufferSize / sizeof(int)]; int srcBpp = src.Info.BytesPerPixel; int dstBpp = dst.Info.BytesPerPixel; @@ -1034,9 +999,9 @@ namespace Ryujinx.Graphics.Vulkan shaderParams[0] = BitOperations.Log2((uint)ratio); - var bufferHandle = gd.BufferManager.CreateWithHandle(gd, ParamsBufferSize); + using var buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, ParamsBufferSize); - gd.BufferManager.SetData(bufferHandle, 0, shaderParams); + buffer.Holder.SetDataUnchecked(buffer.Offset, shaderParams); TextureView.InsertImageBarrier( gd.Api, @@ -1064,7 +1029,7 @@ namespace Ryujinx.Graphics.Vulkan var srcFormat = GetFormat(componentSize, srcBpp / componentSize); var dstFormat = GetFormat(componentSize, dstBpp / componentSize); - _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, new BufferRange(bufferHandle, 0, ParamsBufferSize)) }); + _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, buffer.Range) }); for (int l = 0; l < levels; l++) { @@ -1093,8 +1058,6 @@ namespace Ryujinx.Graphics.Vulkan } } - gd.BufferManager.Delete(bufferHandle); - _pipeline.Finish(gd, cbs); TextureView.InsertImageBarrier( @@ -1128,9 +1091,9 @@ namespace Ryujinx.Graphics.Vulkan (shaderParams[0], shaderParams[1]) = GetSampleCountXYLog2(samples); (shaderParams[2], shaderParams[3]) = GetSampleCountXYLog2((int)TextureStorage.ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)samples)); - var bufferHandle = gd.BufferManager.CreateWithHandle(gd, ParamsBufferSize); + using var buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, ParamsBufferSize); - gd.BufferManager.SetData(bufferHandle, 0, shaderParams); + buffer.Holder.SetDataUnchecked(buffer.Offset, shaderParams); TextureView.InsertImageBarrier( gd.Api, @@ -1147,7 +1110,7 @@ namespace Ryujinx.Graphics.Vulkan 1); _pipeline.SetCommandBuffer(cbs); - _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, new BufferRange(bufferHandle, 0, ParamsBufferSize)) }); + _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, buffer.Range) }); if (isDepthOrStencil) { @@ -1175,12 +1138,7 @@ namespace Ryujinx.Graphics.Vulkan var srcView = Create2DLayerView(src, srcLayer + z, 0); var dstView = Create2DLayerView(dst, dstLayer + z, 0); - _pipeline.SetRenderTarget( - dstView.GetImageViewForAttachment(), - (uint)dst.Width, - (uint)dst.Height, - true, - dst.VkFormat); + _pipeline.SetRenderTarget(dstView, (uint)dst.Width, (uint)dst.Height); CopyMSDraw(srcView, aspectFlags, fromMS: true); @@ -1226,8 +1184,6 @@ namespace Ryujinx.Graphics.Vulkan } } - gd.BufferManager.Delete(bufferHandle); - _pipeline.Finish(gd, cbs); TextureView.InsertImageBarrier( @@ -1261,9 +1217,9 @@ namespace Ryujinx.Graphics.Vulkan (shaderParams[0], shaderParams[1]) = GetSampleCountXYLog2(samples); (shaderParams[2], shaderParams[3]) = GetSampleCountXYLog2((int)TextureStorage.ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)samples)); - var bufferHandle = gd.BufferManager.CreateWithHandle(gd, ParamsBufferSize); + using var buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, ParamsBufferSize); - gd.BufferManager.SetData(bufferHandle, 0, shaderParams); + buffer.Holder.SetDataUnchecked(buffer.Offset, shaderParams); TextureView.InsertImageBarrier( gd.Api, @@ -1299,7 +1255,7 @@ namespace Ryujinx.Graphics.Vulkan _pipeline.SetViewports(viewports); _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); - _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, new BufferRange(bufferHandle, 0, ParamsBufferSize)) }); + _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, buffer.Range) }); if (isDepthOrStencil) { @@ -1308,13 +1264,7 @@ namespace Ryujinx.Graphics.Vulkan var srcView = Create2DLayerView(src, srcLayer + z, 0); var dstView = Create2DLayerView(dst, dstLayer + z, 0); - _pipeline.SetRenderTarget( - dstView.GetImageViewForAttachment(), - (uint)dst.Width, - (uint)dst.Height, - (uint)samples, - true, - dst.VkFormat); + _pipeline.SetRenderTarget(dstView, (uint)dst.Width, (uint)dst.Height); CopyMSDraw(srcView, aspectFlags, fromMS: false); @@ -1342,13 +1292,7 @@ namespace Ryujinx.Graphics.Vulkan var dstView = Create2DLayerView(dst, dstLayer + z, 0); _pipeline.SetTextureAndSamplerIdentitySwizzle(ShaderStage.Fragment, 0, srcView, null); - _pipeline.SetRenderTarget( - dstView.GetView(format).GetImageViewForAttachment(), - (uint)dst.Width, - (uint)dst.Height, - (uint)samples, - false, - vkFormat); + _pipeline.SetRenderTarget(dstView.GetView(format), (uint)dst.Width, (uint)dst.Height); _pipeline.Draw(4, 1, 0, 0); @@ -1364,8 +1308,6 @@ namespace Ryujinx.Graphics.Vulkan } } - gd.BufferManager.Delete(bufferHandle); - _pipeline.Finish(gd, cbs); TextureView.InsertImageBarrier( @@ -1487,9 +1429,9 @@ namespace Ryujinx.Graphics.Vulkan }; var info = new TextureCreateInfo( - from.Info.Width, - from.Info.Height, - from.Info.Depth, + Math.Max(1, from.Info.Width >> level), + Math.Max(1, from.Info.Height >> level), + 1, 1, from.Info.Samples, from.Info.BlockWidth, @@ -1616,10 +1558,11 @@ namespace Ryujinx.Graphics.Vulkan pattern.OffsetIndex.CopyTo(shaderParams[..pattern.OffsetIndex.Length]); - var patternBufferHandle = gd.BufferManager.CreateWithHandle(gd, ParamsBufferSize, out var patternBuffer); + using var patternScoped = gd.BufferManager.ReserveOrCreate(gd, cbs, ParamsBufferSize); + var patternBuffer = patternScoped.Holder; var patternBufferAuto = patternBuffer.GetBuffer(); - gd.BufferManager.SetData(patternBufferHandle, 0, shaderParams); + patternBuffer.SetDataUnchecked(patternScoped.Offset, shaderParams); _pipeline.SetCommandBuffer(cbs); @@ -1635,7 +1578,8 @@ namespace Ryujinx.Graphics.Vulkan indirectDataSize); _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, drawCountBufferAligned) }); - _pipeline.SetStorageBuffers(1, new[] { srcIndirectBuffer.GetBuffer(), dstIndirectBuffer.GetBuffer(), patternBuffer.GetBuffer() }); + _pipeline.SetStorageBuffers(1, new[] { srcIndirectBuffer.GetBuffer(), dstIndirectBuffer.GetBuffer() }); + _pipeline.SetStorageBuffers(stackalloc[] { new BufferAssignment(3, patternScoped.Range) }); _pipeline.SetProgram(_programConvertIndirectData); _pipeline.DispatchCompute(1, 1, 1); @@ -1643,12 +1587,12 @@ namespace Ryujinx.Graphics.Vulkan BufferHolder.InsertBufferBarrier( gd, cbs.CommandBuffer, - patternBufferAuto.Get(cbs, ParamsIndirectDispatchOffset, ParamsIndirectDispatchSize).Value, + patternBufferAuto.Get(cbs, patternScoped.Offset + ParamsIndirectDispatchOffset, ParamsIndirectDispatchSize).Value, AccessFlags.ShaderWriteBit, AccessFlags.IndirectCommandReadBit, PipelineStageFlags.ComputeShaderBit, PipelineStageFlags.DrawIndirectBit, - ParamsIndirectDispatchOffset, + patternScoped.Offset + ParamsIndirectDispatchOffset, ParamsIndirectDispatchSize); BufferHolder.InsertBufferBarrier( @@ -1662,11 +1606,11 @@ namespace Ryujinx.Graphics.Vulkan 0, convertedCount * outputIndexSize); - _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, new BufferRange(patternBufferHandle, 0, ParamsBufferSize)) }); + _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, new BufferRange(patternScoped.Handle, patternScoped.Offset, ParamsBufferSize)) }); _pipeline.SetStorageBuffers(1, new[] { srcIndexBuffer.GetBuffer(), dstIndexBuffer.GetBuffer() }); _pipeline.SetProgram(_programConvertIndexBuffer); - _pipeline.DispatchComputeIndirect(patternBufferAuto, ParamsIndirectDispatchOffset); + _pipeline.DispatchComputeIndirect(patternBufferAuto, patternScoped.Offset + ParamsIndirectDispatchOffset); BufferHolder.InsertBufferBarrier( gd, @@ -1679,8 +1623,6 @@ namespace Ryujinx.Graphics.Vulkan 0, convertedCount * outputIndexSize); - gd.BufferManager.Delete(patternBufferHandle); - _pipeline.Finish(gd, cbs); } @@ -1726,13 +1668,13 @@ namespace Ryujinx.Graphics.Vulkan shaderParams[0] = pixelCount; shaderParams[1] = dstOffset; - var bufferHandle = gd.BufferManager.CreateWithHandle(gd, ParamsBufferSize); + using var buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, ParamsBufferSize); - gd.BufferManager.SetData(bufferHandle, 0, shaderParams); + buffer.Holder.SetDataUnchecked(buffer.Offset, shaderParams); _pipeline.SetCommandBuffer(cbs); - _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, new BufferRange(bufferHandle, 0, ParamsBufferSize)) }); + _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, buffer.Range) }); Span> sbRanges = new Auto[2]; @@ -1744,8 +1686,6 @@ namespace Ryujinx.Graphics.Vulkan _pipeline.SetProgram(_programConvertD32S8ToD24S8); _pipeline.DispatchCompute(1 + inSize / ConvertElementsPerWorkgroup, 1, 1); - gd.BufferManager.Delete(bufferHandle); - _pipeline.Finish(gd, cbs); BufferHolder.InsertBufferBarrier( diff --git a/src/Ryujinx.Graphics.Vulkan/HostMemoryAllocator.cs b/src/Ryujinx.Graphics.Vulkan/HostMemoryAllocator.cs index 726cafc51..baccc698f 100644 --- a/src/Ryujinx.Graphics.Vulkan/HostMemoryAllocator.cs +++ b/src/Ryujinx.Graphics.Vulkan/HostMemoryAllocator.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Common.Collections; using Ryujinx.Common.Logging; using Silk.NET.Vulkan; diff --git a/src/Ryujinx.Graphics.Vulkan/IndexBufferPattern.cs b/src/Ryujinx.Graphics.Vulkan/IndexBufferPattern.cs index 9d34c8116..7b01dd4ca 100644 --- a/src/Ryujinx.Graphics.Vulkan/IndexBufferPattern.cs +++ b/src/Ryujinx.Graphics.Vulkan/IndexBufferPattern.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using System; using System.Collections.Generic; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Graphics.Vulkan/IndexBufferState.cs b/src/Ryujinx.Graphics.Vulkan/IndexBufferState.cs index b85f0c7f0..d26fea307 100644 --- a/src/Ryujinx.Graphics.Vulkan/IndexBufferState.cs +++ b/src/Ryujinx.Graphics.Vulkan/IndexBufferState.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using IndexType = Silk.NET.Vulkan.IndexType; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.Graphics.Vulkan/MemoryAllocation.cs b/src/Ryujinx.Graphics.Vulkan/MemoryAllocation.cs index e2b6028ab..3f134e289 100644 --- a/src/Ryujinx.Graphics.Vulkan/MemoryAllocation.cs +++ b/src/Ryujinx.Graphics.Vulkan/MemoryAllocation.cs @@ -1,4 +1,4 @@ -using Silk.NET.Vulkan; +using Silk.NET.Vulkan; using System; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.Graphics.Vulkan/MemoryAllocator.cs b/src/Ryujinx.Graphics.Vulkan/MemoryAllocator.cs index aa0b410c4..339754db1 100644 --- a/src/Ryujinx.Graphics.Vulkan/MemoryAllocator.cs +++ b/src/Ryujinx.Graphics.Vulkan/MemoryAllocator.cs @@ -1,4 +1,4 @@ -using Silk.NET.Vulkan; +using Silk.NET.Vulkan; using System; using System.Collections.Generic; using System.Threading; diff --git a/src/Ryujinx.Graphics.Vulkan/MemoryAllocatorBlockList.cs b/src/Ryujinx.Graphics.Vulkan/MemoryAllocatorBlockList.cs index 6a40b16e3..a1acc90f9 100644 --- a/src/Ryujinx.Graphics.Vulkan/MemoryAllocatorBlockList.cs +++ b/src/Ryujinx.Graphics.Vulkan/MemoryAllocatorBlockList.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Silk.NET.Vulkan; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.Graphics.Vulkan/MultiFenceHolder.cs b/src/Ryujinx.Graphics.Vulkan/MultiFenceHolder.cs index 4d2d312fe..0bce3b72d 100644 --- a/src/Ryujinx.Graphics.Vulkan/MultiFenceHolder.cs +++ b/src/Ryujinx.Graphics.Vulkan/MultiFenceHolder.cs @@ -1,4 +1,4 @@ -using Silk.NET.Vulkan; +using Silk.NET.Vulkan; using System; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.Graphics.Vulkan/NativeArray.cs b/src/Ryujinx.Graphics.Vulkan/NativeArray.cs index 3a8512874..7678b63c8 100644 --- a/src/Ryujinx.Graphics.Vulkan/NativeArray.cs +++ b/src/Ryujinx.Graphics.Vulkan/NativeArray.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Graphics.Vulkan/PersistentFlushBuffer.cs b/src/Ryujinx.Graphics.Vulkan/PersistentFlushBuffer.cs index 80a24682b..5e0ed077b 100644 --- a/src/Ryujinx.Graphics.Vulkan/PersistentFlushBuffer.cs +++ b/src/Ryujinx.Graphics.Vulkan/PersistentFlushBuffer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using System; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs index 7346d7891..3aef1317a 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Shader; using Silk.NET.Vulkan; using System; @@ -30,10 +30,12 @@ namespace Ryujinx.Graphics.Vulkan public readonly PipelineCache PipelineCache; public readonly AutoFlushCounter AutoFlush; + public readonly Action EndRenderPassDelegate; protected PipelineDynamicState DynamicState; private PipelineState _newState; - private bool _stateDirty; + private bool _graphicsStateDirty; + private bool _computeStateDirty; private PrimitiveTopology _topology; private ulong _currentPipelineHandle; @@ -53,6 +55,7 @@ namespace Ryujinx.Graphics.Vulkan protected FramebufferParams FramebufferParams; private Auto _framebuffer; private Auto _renderPass; + private RenderPassHolder _nullRenderPass; private int _writtenAttachmentCount; private bool _framebufferUsingColorWriteMask; @@ -92,6 +95,7 @@ namespace Ryujinx.Graphics.Vulkan Device = device; AutoFlush = new AutoFlushCounter(gd); + EndRenderPassDelegate = EndRenderPass; var pipelineCacheCreateInfo = new PipelineCacheCreateInfo { @@ -100,7 +104,7 @@ namespace Ryujinx.Graphics.Vulkan gd.Api.CreatePipelineCache(device, pipelineCacheCreateInfo, null, out PipelineCache).ThrowOnError(); - _descriptorSetUpdater = new DescriptorSetUpdater(gd, this); + _descriptorSetUpdater = new DescriptorSetUpdater(gd, device, this); _vertexBufferUpdater = new VertexBufferUpdater(gd); _transformFeedbackBuffers = new BufferState[Constants.MaxTransformFeedbackBuffers]; @@ -351,7 +355,7 @@ namespace Ryujinx.Graphics.Vulkan } EndRenderPass(); - RecreatePipelineIfNeeded(PipelineBindPoint.Compute); + RecreateComputePipelineIfNeeded(); Gd.Api.CmdDispatch(CommandBuffer, (uint)groupsX, (uint)groupsY, (uint)groupsZ); } @@ -364,19 +368,23 @@ namespace Ryujinx.Graphics.Vulkan } EndRenderPass(); - RecreatePipelineIfNeeded(PipelineBindPoint.Compute); + RecreateComputePipelineIfNeeded(); Gd.Api.CmdDispatchIndirect(CommandBuffer, indirectBuffer.Get(Cbs, indirectBufferOffset, 12).Value, (ulong)indirectBufferOffset); } public void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance) { - if (!_program.IsLinked || vertexCount == 0) + if (vertexCount == 0) + { + return; + } + + if (!RecreateGraphicsPipelineIfNeeded()) { return; } - RecreatePipelineIfNeeded(PipelineBindPoint.Graphics); BeginRenderPass(); DrawCount++; @@ -435,13 +443,18 @@ namespace Ryujinx.Graphics.Vulkan public void DrawIndexed(int indexCount, int instanceCount, int firstIndex, int firstVertex, int firstInstance) { - if (!_program.IsLinked || indexCount == 0) + if (indexCount == 0) { return; } UpdateIndexBufferPattern(); - RecreatePipelineIfNeeded(PipelineBindPoint.Graphics); + + if (!RecreateGraphicsPipelineIfNeeded()) + { + return; + } + BeginRenderPass(); DrawCount++; @@ -474,17 +487,17 @@ namespace Ryujinx.Graphics.Vulkan public void DrawIndexedIndirect(BufferRange indirectBuffer) { - if (!_program.IsLinked) - { - return; - } - var buffer = Gd.BufferManager .GetBuffer(CommandBuffer, indirectBuffer.Handle, indirectBuffer.Offset, indirectBuffer.Size, false) .Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size).Value; UpdateIndexBufferPattern(); - RecreatePipelineIfNeeded(PipelineBindPoint.Graphics); + + if (!RecreateGraphicsPipelineIfNeeded()) + { + return; + } + BeginRenderPass(); DrawCount++; @@ -520,11 +533,6 @@ namespace Ryujinx.Graphics.Vulkan public void DrawIndexedIndirectCount(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride) { - if (!_program.IsLinked) - { - return; - } - var countBuffer = Gd.BufferManager .GetBuffer(CommandBuffer, parameterBuffer.Handle, parameterBuffer.Offset, parameterBuffer.Size, false) .Get(Cbs, parameterBuffer.Offset, parameterBuffer.Size).Value; @@ -534,7 +542,12 @@ namespace Ryujinx.Graphics.Vulkan .Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size).Value; UpdateIndexBufferPattern(); - RecreatePipelineIfNeeded(PipelineBindPoint.Graphics); + + if (!RecreateGraphicsPipelineIfNeeded()) + { + return; + } + BeginRenderPass(); DrawCount++; @@ -612,18 +625,17 @@ namespace Ryujinx.Graphics.Vulkan public void DrawIndirect(BufferRange indirectBuffer) { - if (!_program.IsLinked) - { - return; - } - // TODO: Support quads and other unsupported topologies. var buffer = Gd.BufferManager .GetBuffer(CommandBuffer, indirectBuffer.Handle, indirectBuffer.Offset, indirectBuffer.Size, false) .Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size, false).Value; - RecreatePipelineIfNeeded(PipelineBindPoint.Graphics); + if (!RecreateGraphicsPipelineIfNeeded()) + { + return; + } + BeginRenderPass(); ResumeTransformFeedbackInternal(); DrawCount++; @@ -639,11 +651,6 @@ namespace Ryujinx.Graphics.Vulkan throw new NotSupportedException(); } - if (!_program.IsLinked) - { - return; - } - var buffer = Gd.BufferManager .GetBuffer(CommandBuffer, indirectBuffer.Handle, indirectBuffer.Offset, indirectBuffer.Size, false) .Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size, false).Value; @@ -654,7 +661,11 @@ namespace Ryujinx.Graphics.Vulkan // TODO: Support quads and other unsupported topologies. - RecreatePipelineIfNeeded(PipelineBindPoint.Graphics); + if (!RecreateGraphicsPipelineIfNeeded()) + { + return; + } + BeginRenderPass(); ResumeTransformFeedbackInternal(); DrawCount++; @@ -1478,106 +1489,43 @@ namespace Ryujinx.Graphics.Vulkan protected unsafe void CreateRenderPass() { - const int MaxAttachments = Constants.MaxRenderTargets + 1; - - AttachmentDescription[] attachmentDescs = null; - - var subpass = new SubpassDescription - { - PipelineBindPoint = PipelineBindPoint.Graphics, - }; - - AttachmentReference* attachmentReferences = stackalloc AttachmentReference[MaxAttachments]; - var hasFramebuffer = FramebufferParams != null; - if (hasFramebuffer && FramebufferParams.AttachmentsCount != 0) - { - attachmentDescs = new AttachmentDescription[FramebufferParams.AttachmentsCount]; - - for (int i = 0; i < FramebufferParams.AttachmentsCount; i++) - { - attachmentDescs[i] = new AttachmentDescription( - 0, - FramebufferParams.AttachmentFormats[i], - TextureStorage.ConvertToSampleCountFlags(Gd.Capabilities.SupportedSampleCounts, FramebufferParams.AttachmentSamples[i]), - AttachmentLoadOp.Load, - AttachmentStoreOp.Store, - AttachmentLoadOp.Load, - AttachmentStoreOp.Store, - ImageLayout.General, - ImageLayout.General); - } - - int colorAttachmentsCount = FramebufferParams.ColorAttachmentsCount; - - if (colorAttachmentsCount > MaxAttachments - 1) - { - colorAttachmentsCount = MaxAttachments - 1; - } - - if (colorAttachmentsCount != 0) - { - int maxAttachmentIndex = FramebufferParams.MaxColorAttachmentIndex; - subpass.ColorAttachmentCount = (uint)maxAttachmentIndex + 1; - subpass.PColorAttachments = &attachmentReferences[0]; - - // Fill with VK_ATTACHMENT_UNUSED to cover any gaps. - for (int i = 0; i <= maxAttachmentIndex; i++) - { - subpass.PColorAttachments[i] = new AttachmentReference(Vk.AttachmentUnused, ImageLayout.Undefined); - } - - for (int i = 0; i < colorAttachmentsCount; i++) - { - int bindIndex = FramebufferParams.AttachmentIndices[i]; - - subpass.PColorAttachments[bindIndex] = new AttachmentReference((uint)i, ImageLayout.General); - } - } - - if (FramebufferParams.HasDepthStencil) - { - uint dsIndex = (uint)FramebufferParams.AttachmentsCount - 1; - - subpass.PDepthStencilAttachment = &attachmentReferences[MaxAttachments - 1]; - *subpass.PDepthStencilAttachment = new AttachmentReference(dsIndex, ImageLayout.General); - } - } - - var subpassDependency = PipelineConverter.CreateSubpassDependency(); - - fixed (AttachmentDescription* pAttachmentDescs = attachmentDescs) - { - var renderPassCreateInfo = new RenderPassCreateInfo - { - SType = StructureType.RenderPassCreateInfo, - PAttachments = pAttachmentDescs, - AttachmentCount = attachmentDescs != null ? (uint)attachmentDescs.Length : 0, - PSubpasses = &subpass, - SubpassCount = 1, - PDependencies = &subpassDependency, - DependencyCount = 1, - }; - - Gd.Api.CreateRenderPass(Device, renderPassCreateInfo, null, out var renderPass).ThrowOnError(); - - _renderPass?.Dispose(); - _renderPass = new Auto(new DisposableRenderPass(Gd.Api, Device, renderPass)); - } - EndRenderPass(); - _framebuffer?.Dispose(); - _framebuffer = hasFramebuffer ? FramebufferParams.Create(Gd.Api, Cbs, _renderPass) : null; + if (!hasFramebuffer || FramebufferParams.AttachmentsCount == 0) + { + // Use the null framebuffer. + _nullRenderPass ??= new RenderPassHolder(Gd, Device, new RenderPassCacheKey(), FramebufferParams); + + _renderPass = _nullRenderPass.GetRenderPass(); + _framebuffer = _nullRenderPass.GetFramebuffer(Gd, Cbs, FramebufferParams); + } + else + { + (_renderPass, _framebuffer) = FramebufferParams.GetPassAndFramebuffer(Gd, Device, Cbs); + } } protected void SignalStateChange() { - _stateDirty = true; + _graphicsStateDirty = true; + _computeStateDirty = true; } - private void RecreatePipelineIfNeeded(PipelineBindPoint pbp) + private void RecreateComputePipelineIfNeeded() + { + if (_computeStateDirty || Pbp != PipelineBindPoint.Compute) + { + CreatePipeline(PipelineBindPoint.Compute); + _computeStateDirty = false; + Pbp = PipelineBindPoint.Compute; + } + + _descriptorSetUpdater.UpdateAndBindDescriptorSets(Cbs, PipelineBindPoint.Compute); + } + + private bool RecreateGraphicsPipelineIfNeeded() { if (AutoFlush.ShouldFlushDraw(DrawCount)) { @@ -1618,17 +1566,23 @@ namespace Ryujinx.Graphics.Vulkan _vertexBufferUpdater.Commit(Cbs); } - if (_stateDirty || Pbp != pbp) + if (_graphicsStateDirty || Pbp != PipelineBindPoint.Graphics) { - CreatePipeline(pbp); - _stateDirty = false; - Pbp = pbp; + if (!CreatePipeline(PipelineBindPoint.Graphics)) + { + return false; + } + + _graphicsStateDirty = false; + Pbp = PipelineBindPoint.Graphics; } - _descriptorSetUpdater.UpdateAndBindDescriptorSets(Cbs, pbp); + _descriptorSetUpdater.UpdateAndBindDescriptorSets(Cbs, PipelineBindPoint.Graphics); + + return true; } - private void CreatePipeline(PipelineBindPoint pbp) + private bool CreatePipeline(PipelineBindPoint pbp) { // We can only create a pipeline if the have the shader stages set. if (_newState.Stages != null) @@ -1638,10 +1592,25 @@ namespace Ryujinx.Graphics.Vulkan CreateRenderPass(); } + if (!_program.IsLinked) + { + // Background compile failed, we likely can't create the pipeline because the shader is broken + // or the driver failed to compile it. + + return false; + } + var pipeline = pbp == PipelineBindPoint.Compute ? _newState.CreateComputePipeline(Gd, Device, _program, PipelineCache) : _newState.CreateGraphicsPipeline(Gd, Device, _program, PipelineCache, _renderPass.Get(Cbs).Value); + if (pipeline == null) + { + // Host failed to create the pipeline, likely due to driver bugs. + + return false; + } + ulong pipelineHandle = pipeline.GetUnsafe().Value.Handle; if (_currentPipelineHandle != pipelineHandle) @@ -1653,6 +1622,8 @@ namespace Ryujinx.Graphics.Vulkan Gd.Api.CmdBindPipeline(CommandBuffer, pbp, Pipeline.Get(Cbs).Value); } } + + return true; } private unsafe void BeginRenderPass() @@ -1724,8 +1695,7 @@ namespace Ryujinx.Graphics.Vulkan { if (disposing) { - _renderPass?.Dispose(); - _framebuffer?.Dispose(); + _nullRenderPass?.Dispose(); _newState.Dispose(); _descriptorSetUpdater.Dispose(); _vertexBufferUpdater.Dispose(); diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineConverter.cs b/src/Ryujinx.Graphics.Vulkan/PipelineConverter.cs index b2da61031..95b480a5e 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineConverter.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineConverter.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; using System; diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs b/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs index a5c218ac2..1cc33f728 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Silk.NET.Vulkan; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineFull.cs b/src/Ryujinx.Graphics.Vulkan/PipelineFull.cs index c3e6f37c3..6c4419cd2 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineFull.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineFull.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Vulkan.Queries; using Silk.NET.Vulkan; using System; @@ -51,7 +51,7 @@ namespace Ryujinx.Graphics.Vulkan { // We can't use CmdClearAttachments if not writing all components, // because on Vulkan, the pipeline state does not affect clears. - var dstTexture = FramebufferParams.GetAttachment(index); + var dstTexture = FramebufferParams.GetColorView(index); if (dstTexture == null) { return; @@ -71,7 +71,6 @@ namespace Ryujinx.Graphics.Vulkan componentMask, (int)FramebufferParams.Width, (int)FramebufferParams.Height, - FramebufferParams.AttachmentFormats[index], FramebufferParams.GetAttachmentComponentType(index), ClearScissor); } @@ -92,7 +91,7 @@ namespace Ryujinx.Graphics.Vulkan { // We can't use CmdClearAttachments if not clearing all (mask is all ones, 0xFF) or none (mask is 0) of the stencil bits, // because on Vulkan, the pipeline state does not affect clears. - var dstTexture = FramebufferParams.GetDepthStencilAttachment(); + var dstTexture = FramebufferParams.GetDepthStencilView(); if (dstTexture == null) { return; @@ -246,7 +245,10 @@ namespace Ryujinx.Graphics.Vulkan SignalCommandBufferChange(); - DynamicState.ReplayIfDirty(Gd.Api, CommandBuffer); + if (Pipeline != null && Pbp == PipelineBindPoint.Graphics) + { + DynamicState.ReplayIfDirty(Gd.Api, CommandBuffer); + } } public void FlushCommandsImpl() diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineHelperShader.cs b/src/Ryujinx.Graphics.Vulkan/PipelineHelperShader.cs index b31b72a1a..dfbf19013 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineHelperShader.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineHelperShader.cs @@ -1,4 +1,4 @@ -using Silk.NET.Vulkan; +using Silk.NET.Vulkan; using VkFormat = Silk.NET.Vulkan.Format; namespace Ryujinx.Graphics.Vulkan @@ -9,21 +9,16 @@ namespace Ryujinx.Graphics.Vulkan { } - public void SetRenderTarget(Auto view, uint width, uint height, bool isDepthStencil, VkFormat format) + public void SetRenderTarget(TextureView view, uint width, uint height) { - SetRenderTarget(view, width, height, 1u, isDepthStencil, format); - } - - public void SetRenderTarget(Auto view, uint width, uint height, uint samples, bool isDepthStencil, VkFormat format) - { - CreateFramebuffer(view, width, height, samples, isDepthStencil, format); + CreateFramebuffer(view, width, height); CreateRenderPass(); SignalStateChange(); } - private void CreateFramebuffer(Auto view, uint width, uint height, uint samples, bool isDepthStencil, VkFormat format) + private void CreateFramebuffer(TextureView view, uint width, uint height) { - FramebufferParams = new FramebufferParams(Device, view, width, height, samples, isDepthStencil, format); + FramebufferParams = new FramebufferParams(Device, view, width, height); UpdatePipelineAttachmentFormats(); } diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineLayoutFactory.cs b/src/Ryujinx.Graphics.Vulkan/PipelineLayoutFactory.cs index ba93dfadb..8bf286c65 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineLayoutFactory.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineLayoutFactory.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; using System.Collections.ObjectModel; diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineState.cs b/src/Ryujinx.Graphics.Vulkan/PipelineState.cs index 5a30cff8e..25fd7168f 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineState.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineState.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Silk.NET.Vulkan; using System; using System.Numerics; @@ -312,7 +312,6 @@ namespace Ryujinx.Graphics.Vulkan } public NativeArray Stages; - public NativeArray StageRequiredSubgroupSizes; public PipelineLayout PipelineLayout; public SpecData SpecializationData; @@ -321,16 +320,6 @@ namespace Ryujinx.Graphics.Vulkan public void Initialize() { Stages = new NativeArray(Constants.MaxShaderStages); - StageRequiredSubgroupSizes = new NativeArray(Constants.MaxShaderStages); - - for (int index = 0; index < Constants.MaxShaderStages; index++) - { - StageRequiredSubgroupSizes[index] = new PipelineShaderStageRequiredSubgroupSizeCreateInfoEXT - { - SType = StructureType.PipelineShaderStageRequiredSubgroupSizeCreateInfoExt, - RequiredSubgroupSize = RequiredSubgroupSize, - }; - } AdvancedBlendSrcPreMultiplied = true; AdvancedBlendDstPreMultiplied = true; @@ -397,7 +386,8 @@ namespace Ryujinx.Graphics.Vulkan Device device, ShaderCollection program, PipelineCache cache, - RenderPass renderPass) + RenderPass renderPass, + bool throwOnError = false) { if (program.TryGetGraphicsPipeline(ref Internal, out var pipeline)) { @@ -630,7 +620,18 @@ namespace Ryujinx.Graphics.Vulkan BasePipelineIndex = -1, }; - gd.Api.CreateGraphicsPipelines(device, cache, 1, &pipelineCreateInfo, null, &pipelineHandle).ThrowOnError(); + Result result = gd.Api.CreateGraphicsPipelines(device, cache, 1, &pipelineCreateInfo, null, &pipelineHandle); + + if (throwOnError) + { + result.ThrowOnError(); + } + else if (result.IsError()) + { + program.AddGraphicsPipeline(ref Internal, null); + + return null; + } // Restore previous blend enable values if we changed it. while (blendEnables != 0) @@ -708,7 +709,6 @@ namespace Ryujinx.Graphics.Vulkan public readonly void Dispose() { Stages.Dispose(); - StageRequiredSubgroupSizes.Dispose(); } } } diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineUid.cs b/src/Ryujinx.Graphics.Vulkan/PipelineUid.cs index 460c27d8b..3448d9743 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineUid.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineUid.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Silk.NET.Vulkan; using System; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs b/src/Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs index 2a85429fb..3fdc5afa5 100644 --- a/src/Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs +++ b/src/Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; using System; diff --git a/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs b/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs index 9c450cb78..0d133e50e 100644 --- a/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs +++ b/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; using System; using System.Collections.Generic; @@ -67,9 +67,18 @@ namespace Ryujinx.Graphics.Vulkan.Queries lock (_queryPool) { count = Math.Min(count, _queryPool.Count); - for (int i = 0; i < count; i++) + + if (count > 0) { - _queryPool.ElementAt(i).PoolReset(cmd, ResetSequence); + foreach (BufferedQuery query in _queryPool) + { + query.PoolReset(cmd, ResetSequence); + + if (--count == 0) + { + break; + } + } } } } diff --git a/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs b/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs index 77d9a3557..14d3050bf 100644 --- a/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs +++ b/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using System; using System.Threading; diff --git a/src/Ryujinx.Graphics.Vulkan/RenderPassCacheKey.cs b/src/Ryujinx.Graphics.Vulkan/RenderPassCacheKey.cs new file mode 100644 index 000000000..7c57b8feb --- /dev/null +++ b/src/Ryujinx.Graphics.Vulkan/RenderPassCacheKey.cs @@ -0,0 +1,43 @@ +using System; +using System.Linq; + +namespace Ryujinx.Graphics.Vulkan +{ + internal readonly struct RenderPassCacheKey : IRefEquatable + { + private readonly TextureView _depthStencil; + private readonly TextureView[] _colors; + + public RenderPassCacheKey(TextureView depthStencil, TextureView[] colors) + { + _depthStencil = depthStencil; + _colors = colors; + } + + public override int GetHashCode() + { + HashCode hc = new(); + + hc.Add(_depthStencil); + + if (_colors != null) + { + foreach (var color in _colors) + { + hc.Add(color); + } + } + + return hc.ToHashCode(); + } + + public bool Equals(ref RenderPassCacheKey other) + { + bool colorsNull = _colors == null; + bool otherNull = other._colors == null; + return other._depthStencil == _depthStencil && + colorsNull == otherNull && + (colorsNull || other._colors.SequenceEqual(_colors)); + } + } +} diff --git a/src/Ryujinx.Graphics.Vulkan/RenderPassHolder.cs b/src/Ryujinx.Graphics.Vulkan/RenderPassHolder.cs new file mode 100644 index 000000000..3d883b2d5 --- /dev/null +++ b/src/Ryujinx.Graphics.Vulkan/RenderPassHolder.cs @@ -0,0 +1,180 @@ +using Silk.NET.Vulkan; +using System; + +namespace Ryujinx.Graphics.Vulkan +{ + internal class RenderPassHolder + { + private readonly struct FramebufferCacheKey : IRefEquatable + { + private readonly uint _width; + private readonly uint _height; + private readonly uint _layers; + + public FramebufferCacheKey(uint width, uint height, uint layers) + { + _width = width; + _height = height; + _layers = layers; + } + + public override int GetHashCode() + { + return HashCode.Combine(_width, _height, _layers); + } + + public bool Equals(ref FramebufferCacheKey other) + { + return other._width == _width && other._height == _height && other._layers == _layers; + } + } + + private readonly TextureView[] _textures; + private readonly Auto _renderPass; + private readonly HashTableSlim> _framebuffers; + private readonly RenderPassCacheKey _key; + + public unsafe RenderPassHolder(VulkanRenderer gd, Device device, RenderPassCacheKey key, FramebufferParams fb) + { + // Create render pass using framebuffer params. + + const int MaxAttachments = Constants.MaxRenderTargets + 1; + + AttachmentDescription[] attachmentDescs = null; + + var subpass = new SubpassDescription + { + PipelineBindPoint = PipelineBindPoint.Graphics, + }; + + AttachmentReference* attachmentReferences = stackalloc AttachmentReference[MaxAttachments]; + + var hasFramebuffer = fb != null; + + if (hasFramebuffer && fb.AttachmentsCount != 0) + { + attachmentDescs = new AttachmentDescription[fb.AttachmentsCount]; + + for (int i = 0; i < fb.AttachmentsCount; i++) + { + attachmentDescs[i] = new AttachmentDescription( + 0, + fb.AttachmentFormats[i], + TextureStorage.ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, fb.AttachmentSamples[i]), + AttachmentLoadOp.Load, + AttachmentStoreOp.Store, + AttachmentLoadOp.Load, + AttachmentStoreOp.Store, + ImageLayout.General, + ImageLayout.General); + } + + int colorAttachmentsCount = fb.ColorAttachmentsCount; + + if (colorAttachmentsCount > MaxAttachments - 1) + { + colorAttachmentsCount = MaxAttachments - 1; + } + + if (colorAttachmentsCount != 0) + { + int maxAttachmentIndex = fb.MaxColorAttachmentIndex; + subpass.ColorAttachmentCount = (uint)maxAttachmentIndex + 1; + subpass.PColorAttachments = &attachmentReferences[0]; + + // Fill with VK_ATTACHMENT_UNUSED to cover any gaps. + for (int i = 0; i <= maxAttachmentIndex; i++) + { + subpass.PColorAttachments[i] = new AttachmentReference(Vk.AttachmentUnused, ImageLayout.Undefined); + } + + for (int i = 0; i < colorAttachmentsCount; i++) + { + int bindIndex = fb.AttachmentIndices[i]; + + subpass.PColorAttachments[bindIndex] = new AttachmentReference((uint)i, ImageLayout.General); + } + } + + if (fb.HasDepthStencil) + { + uint dsIndex = (uint)fb.AttachmentsCount - 1; + + subpass.PDepthStencilAttachment = &attachmentReferences[MaxAttachments - 1]; + *subpass.PDepthStencilAttachment = new AttachmentReference(dsIndex, ImageLayout.General); + } + } + + var subpassDependency = PipelineConverter.CreateSubpassDependency(); + + fixed (AttachmentDescription* pAttachmentDescs = attachmentDescs) + { + var renderPassCreateInfo = new RenderPassCreateInfo + { + SType = StructureType.RenderPassCreateInfo, + PAttachments = pAttachmentDescs, + AttachmentCount = attachmentDescs != null ? (uint)attachmentDescs.Length : 0, + PSubpasses = &subpass, + SubpassCount = 1, + PDependencies = &subpassDependency, + DependencyCount = 1, + }; + + gd.Api.CreateRenderPass(device, renderPassCreateInfo, null, out var renderPass).ThrowOnError(); + + _renderPass?.Dispose(); + _renderPass = new Auto(new DisposableRenderPass(gd.Api, device, renderPass)); + } + + _framebuffers = new HashTableSlim>(); + + // Register this render pass with all render target views. + + var textures = fb.GetAttachmentViews(); + + foreach (var texture in textures) + { + texture.AddRenderPass(key, this); + } + + _textures = textures; + _key = key; + } + + public Auto GetFramebuffer(VulkanRenderer gd, CommandBufferScoped cbs, FramebufferParams fb) + { + var key = new FramebufferCacheKey(fb.Width, fb.Height, fb.Layers); + + if (!_framebuffers.TryGetValue(ref key, out Auto result)) + { + result = fb.Create(gd.Api, cbs, _renderPass); + + _framebuffers.Add(ref key, result); + } + + return result; + } + + public Auto GetRenderPass() + { + return _renderPass; + } + + public void Dispose() + { + // Dispose all framebuffers + + foreach (var fb in _framebuffers.Values) + { + fb.Dispose(); + } + + // Notify all texture views that this render pass has been disposed. + + foreach (var texture in _textures) + { + texture.RemoveRenderPass(_key); + } + } + } +} diff --git a/src/Ryujinx.Graphics.Vulkan/SamplerHolder.cs b/src/Ryujinx.Graphics.Vulkan/SamplerHolder.cs index 6e9f408f3..f67daeecc 100644 --- a/src/Ryujinx.Graphics.Vulkan/SamplerHolder.cs +++ b/src/Ryujinx.Graphics.Vulkan/SamplerHolder.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo; diff --git a/src/Ryujinx.Graphics.Vulkan/SemaphoreHolder.cs b/src/Ryujinx.Graphics.Vulkan/SemaphoreHolder.cs index 2dd17c51c..618a7d488 100644 --- a/src/Ryujinx.Graphics.Vulkan/SemaphoreHolder.cs +++ b/src/Ryujinx.Graphics.Vulkan/SemaphoreHolder.cs @@ -1,4 +1,4 @@ -using Silk.NET.Vulkan; +using Silk.NET.Vulkan; using System; using System.Threading; using VkSemaphore = Silk.NET.Vulkan.Semaphore; diff --git a/src/Ryujinx.Graphics.Vulkan/Shader.cs b/src/Ryujinx.Graphics.Vulkan/Shader.cs index 2229785d8..06f3499db 100644 --- a/src/Ryujinx.Graphics.Vulkan/Shader.cs +++ b/src/Ryujinx.Graphics.Vulkan/Shader.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Shader; using shaderc; diff --git a/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs b/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs index 0cb80ac71..7c25c6d14 100644 --- a/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs +++ b/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; using System; @@ -26,6 +26,7 @@ namespace Ryujinx.Graphics.Vulkan public ResourceBindingSegment[][] ClearSegments { get; } public ResourceBindingSegment[][] BindingSegments { get; } + public DescriptorSetTemplate[] Templates { get; } public ProgramLinkStatus LinkStatus { get; private set; } @@ -118,6 +119,7 @@ namespace Ryujinx.Graphics.Vulkan ClearSegments = BuildClearSegments(resourceLayout.Sets); BindingSegments = BuildBindingSegments(resourceLayout.SetUsages); + Templates = BuildTemplates(); _compileTask = Task.CompletedTask; _firstBackgroundUse = false; @@ -241,6 +243,23 @@ namespace Ryujinx.Graphics.Vulkan return segments; } + private DescriptorSetTemplate[] BuildTemplates() + { + var templates = new DescriptorSetTemplate[BindingSegments.Length]; + + for (int setIndex = 0; setIndex < BindingSegments.Length; setIndex++) + { + ResourceBindingSegment[] segments = BindingSegments[setIndex]; + + if (segments != null && segments.Length > 0) + { + templates[setIndex] = new DescriptorSetTemplate(_gd, _device, segments, _plce, IsCompute ? PipelineBindPoint.Compute : PipelineBindPoint.Graphics, setIndex); + } + } + + return templates; + } + private async Task BackgroundCompilation() { await Task.WhenAll(_shaders.Select(shader => shader.CompileTask)); @@ -355,7 +374,7 @@ namespace Ryujinx.Graphics.Vulkan pipeline.StagesCount = (uint)_shaders.Length; pipeline.PipelineLayout = PipelineLayout; - pipeline.CreateGraphicsPipeline(_gd, _device, this, (_gd.Pipeline as PipelineBase).PipelineCache, renderPass.Value); + pipeline.CreateGraphicsPipeline(_gd, _device, this, (_gd.Pipeline as PipelineBase).PipelineCache, renderPass.Value, throwOnError: true); pipeline.Dispose(); } @@ -492,7 +511,7 @@ namespace Ryujinx.Graphics.Vulkan { foreach (Auto pipeline in _graphicsPipelineCache.Values) { - pipeline.Dispose(); + pipeline?.Dispose(); } } @@ -504,6 +523,11 @@ namespace Ryujinx.Graphics.Vulkan } } + for (int i = 0; i < Templates.Length; i++) + { + Templates[i]?.Dispose(); + } + if (_dummyRenderPass.Value.Handle != 0) { _dummyRenderPass.Dispose(); diff --git a/src/Ryujinx.Graphics.Vulkan/StagingBuffer.cs b/src/Ryujinx.Graphics.Vulkan/StagingBuffer.cs index 3a02a28dc..90a47bb67 100644 --- a/src/Ryujinx.Graphics.Vulkan/StagingBuffer.cs +++ b/src/Ryujinx.Graphics.Vulkan/StagingBuffer.cs @@ -1,5 +1,6 @@ using Ryujinx.Common; using Ryujinx.Common.Logging; +using Ryujinx.Graphics.GAL; using System; using System.Collections.Generic; using System.Diagnostics; @@ -29,6 +30,9 @@ namespace Ryujinx.Graphics.Vulkan private readonly VulkanRenderer _gd; private readonly BufferHolder _buffer; + private readonly int _resourceAlignment; + + public readonly BufferHandle Handle; private readonly struct PendingCopy { @@ -48,9 +52,10 @@ namespace Ryujinx.Graphics.Vulkan public StagingBuffer(VulkanRenderer gd, BufferManager bufferManager) { _gd = gd; - _buffer = bufferManager.Create(gd, BufferSize); + Handle = bufferManager.CreateWithHandle(gd, BufferSize, out _buffer); _pendingCopies = new Queue(); _freeSize = BufferSize; + _resourceAlignment = (int)gd.Capabilities.MinResourceAlignment; } public void PushData(CommandBufferPool cbp, CommandBufferScoped? cbs, Action endRenderPass, BufferHolder dst, int dstOffset, ReadOnlySpan data) @@ -197,7 +202,7 @@ namespace Ryujinx.Graphics.Vulkan /// Reserve a range on the staging buffer for the current command buffer and upload data to it. /// /// Command buffer to reserve the data on - /// The data to upload + /// The minimum size the reserved data requires /// The required alignment for the buffer offset /// The reserved range of the staging buffer public unsafe StagingBufferReserved? TryReserveData(CommandBufferScoped cbs, int size, int alignment) @@ -223,6 +228,18 @@ namespace Ryujinx.Graphics.Vulkan return ReserveDataImpl(cbs, size, alignment); } + /// + /// Reserve a range on the staging buffer for the current command buffer and upload data to it. + /// Uses the most permissive byte alignment. + /// + /// Command buffer to reserve the data on + /// The minimum size the reserved data requires + /// The reserved range of the staging buffer + public unsafe StagingBufferReserved? TryReserveData(CommandBufferScoped cbs, int size) + { + return TryReserveData(cbs, size, _resourceAlignment); + } + private bool WaitFreeCompleted(CommandBufferPool cbp) { if (_pendingCopies.TryPeek(out var pc)) @@ -263,7 +280,7 @@ namespace Ryujinx.Graphics.Vulkan { if (disposing) { - _buffer.Dispose(); + _gd.BufferManager.Delete(Handle); while (_pendingCopies.TryDequeue(out var pc)) { diff --git a/src/Ryujinx.Graphics.Vulkan/TextureBuffer.cs b/src/Ryujinx.Graphics.Vulkan/TextureBuffer.cs index 285a56498..81e478814 100644 --- a/src/Ryujinx.Graphics.Vulkan/TextureBuffer.cs +++ b/src/Ryujinx.Graphics.Vulkan/TextureBuffer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; using System; diff --git a/src/Ryujinx.Graphics.Vulkan/TextureCopy.cs b/src/Ryujinx.Graphics.Vulkan/TextureCopy.cs index 717935fb4..7c06a5df6 100644 --- a/src/Ryujinx.Graphics.Vulkan/TextureCopy.cs +++ b/src/Ryujinx.Graphics.Vulkan/TextureCopy.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; using System; diff --git a/src/Ryujinx.Graphics.Vulkan/TextureStorage.cs b/src/Ryujinx.Graphics.Vulkan/TextureStorage.cs index 5a6216c22..b763fa987 100644 --- a/src/Ryujinx.Graphics.Vulkan/TextureStorage.cs +++ b/src/Ryujinx.Graphics.Vulkan/TextureStorage.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; using System; diff --git a/src/Ryujinx.Graphics.Vulkan/TextureView.cs b/src/Ryujinx.Graphics.Vulkan/TextureView.cs index 05dbd15ce..393db2611 100644 --- a/src/Ryujinx.Graphics.Vulkan/TextureView.cs +++ b/src/Ryujinx.Graphics.Vulkan/TextureView.cs @@ -1,8 +1,9 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; using System; using System.Collections.Generic; +using System.Linq; using Format = Ryujinx.Graphics.GAL.Format; using VkBuffer = Silk.NET.Vulkan.Buffer; using VkFormat = Silk.NET.Vulkan.Format; @@ -23,6 +24,8 @@ namespace Ryujinx.Graphics.Vulkan private readonly TextureCreateInfo _info; + private HashTableSlim _renderPasses; + public TextureCreateInfo Info => _info; public TextureStorage Storage { get; } @@ -158,6 +161,26 @@ namespace Ryujinx.Graphics.Vulkan Valid = true; } + /// + /// Create a texture view for an existing swapchain image view. + /// Does not set storage, so only appropriate for swapchain use. + /// + /// Do not use this for normal textures, and make sure uses do not try to read storage. + public TextureView(VulkanRenderer gd, Device device, DisposableImageView view, TextureCreateInfo info, VkFormat format) + { + _gd = gd; + _device = device; + + _imageView = new Auto(view); + _imageViewDraw = _imageView; + _imageViewIdentity = _imageView; + _info = info; + + VkFormat = format; + + Valid = true; + } + public Auto GetImage() { return Storage.GetImage(); @@ -939,6 +962,34 @@ namespace Ryujinx.Graphics.Vulkan throw new NotImplementedException(); } + public (Auto renderPass, Auto framebuffer) GetPassAndFramebuffer( + VulkanRenderer gd, + Device device, + CommandBufferScoped cbs, + FramebufferParams fb) + { + var key = fb.GetRenderPassCacheKey(); + + if (_renderPasses == null || !_renderPasses.TryGetValue(ref key, out RenderPassHolder rpHolder)) + { + rpHolder = new RenderPassHolder(gd, device, key, fb); + } + + return (rpHolder.GetRenderPass(), rpHolder.GetFramebuffer(gd, cbs, fb)); + } + + public void AddRenderPass(RenderPassCacheKey key, RenderPassHolder renderPass) + { + _renderPasses ??= new HashTableSlim(); + + _renderPasses.Add(ref key, renderPass); + } + + public void RemoveRenderPass(RenderPassCacheKey key) + { + _renderPasses.Remove(ref key); + } + protected virtual void Dispose(bool disposing) { if (disposing) @@ -948,15 +999,29 @@ namespace Ryujinx.Graphics.Vulkan if (_gd.Textures.Remove(this)) { _imageView.Dispose(); - _imageViewIdentity.Dispose(); _imageView2dArray?.Dispose(); + if (_imageViewIdentity != _imageView) + { + _imageViewIdentity.Dispose(); + } + if (_imageViewDraw != _imageViewIdentity) { _imageViewDraw.Dispose(); } Storage.DecrementViewsCount(); + + if (_renderPasses != null) + { + var renderPasses = _renderPasses.Values.ToArray(); + + foreach (var pass in renderPasses) + { + pass.Dispose(); + } + } } } } diff --git a/src/Ryujinx.Graphics.Vulkan/VertexBufferState.cs b/src/Ryujinx.Graphics.Vulkan/VertexBufferState.cs index 9a943bf98..6f27bb68b 100644 --- a/src/Ryujinx.Graphics.Vulkan/VertexBufferState.cs +++ b/src/Ryujinx.Graphics.Vulkan/VertexBufferState.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; namespace Ryujinx.Graphics.Vulkan { diff --git a/src/Ryujinx.Graphics.Vulkan/VertexBufferUpdater.cs b/src/Ryujinx.Graphics.Vulkan/VertexBufferUpdater.cs index 8d6b0a055..94269dd76 100644 --- a/src/Ryujinx.Graphics.Vulkan/VertexBufferUpdater.cs +++ b/src/Ryujinx.Graphics.Vulkan/VertexBufferUpdater.cs @@ -1,4 +1,4 @@ -using System; +using System; using VkBuffer = Silk.NET.Vulkan.Buffer; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.Graphics.Vulkan/VulkanConfiguration.cs b/src/Ryujinx.Graphics.Vulkan/VulkanConfiguration.cs index 5080ebf68..a1fdc4aed 100644 --- a/src/Ryujinx.Graphics.Vulkan/VulkanConfiguration.cs +++ b/src/Ryujinx.Graphics.Vulkan/VulkanConfiguration.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Graphics.Vulkan +namespace Ryujinx.Graphics.Vulkan { static class VulkanConfiguration { diff --git a/src/Ryujinx.Graphics.Vulkan/VulkanException.cs b/src/Ryujinx.Graphics.Vulkan/VulkanException.cs index 2d9dbc348..e203a3a21 100644 --- a/src/Ryujinx.Graphics.Vulkan/VulkanException.cs +++ b/src/Ryujinx.Graphics.Vulkan/VulkanException.cs @@ -1,4 +1,4 @@ -using Silk.NET.Vulkan; +using Silk.NET.Vulkan; using System; using System.Runtime.Serialization; @@ -6,10 +6,16 @@ namespace Ryujinx.Graphics.Vulkan { static class ResultExtensions { + public static bool IsError(this Result result) + { + // Only negative result codes are errors. + return result < Result.Success; + } + public static void ThrowOnError(this Result result) { // Only negative result codes are errors. - if ((int)result < (int)Result.Success) + if (result.IsError()) { throw new VulkanException(result); } diff --git a/src/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs b/src/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs index 973c6d396..dd7bcf10f 100644 --- a/src/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs +++ b/src/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Configuration; +using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; diff --git a/src/Ryujinx.Graphics.Vulkan/VulkanPhysicalDevice.cs b/src/Ryujinx.Graphics.Vulkan/VulkanPhysicalDevice.cs index 547f36543..3bee1e9d8 100644 --- a/src/Ryujinx.Graphics.Vulkan/VulkanPhysicalDevice.cs +++ b/src/Ryujinx.Graphics.Vulkan/VulkanPhysicalDevice.cs @@ -58,6 +58,33 @@ namespace Ryujinx.Graphics.Vulkan public bool IsDeviceExtensionPresent(string extension) => DeviceExtensions.Contains(extension); + public unsafe bool TryGetPhysicalDeviceDriverPropertiesKHR(Vk api, out PhysicalDeviceDriverPropertiesKHR res) + { + if (!IsDeviceExtensionPresent("VK_KHR_driver_properties")) + { + res = default; + + return false; + } + + PhysicalDeviceDriverPropertiesKHR physicalDeviceDriverProperties = new() + { + SType = StructureType.PhysicalDeviceDriverPropertiesKhr + }; + + PhysicalDeviceProperties2 physicalDeviceProperties2 = new() + { + SType = StructureType.PhysicalDeviceProperties2, + PNext = &physicalDeviceDriverProperties + }; + + api.GetPhysicalDeviceProperties2(PhysicalDevice, &physicalDeviceProperties2); + + res = physicalDeviceDriverProperties; + + return true; + } + public DeviceInfo ToDeviceInfo() { return new DeviceInfo( diff --git a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs index ed7c1faaa..89ff768dc 100644 --- a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs +++ b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Configuration; +using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Shader; @@ -84,6 +84,7 @@ namespace Ryujinx.Graphics.Vulkan internal bool IsTBDR { get; private set; } internal bool IsSharedMemory { get; private set; } public string GpuVendor { get; private set; } + public string GpuDriver { get; private set; } public string GpuRenderer { get; private set; } public string GpuVersion { get; private set; } @@ -392,6 +393,8 @@ namespace Ryujinx.Graphics.Vulkan LoadFeatures(maxQueueCount, queueFamilyIndex); + QueueFamilyIndex = queueFamilyIndex; + _window = new Window(this, _surface, _physicalDevice.PhysicalDevice, _device); _initialized = true; @@ -399,12 +402,12 @@ namespace Ryujinx.Graphics.Vulkan public BufferHandle CreateBuffer(int size, BufferAccess access) { - return BufferManager.CreateWithHandle(this, size, access.Convert(), default, access == BufferAccess.Stream); + return BufferManager.CreateWithHandle(this, size, access.HasFlag(BufferAccess.SparseCompatible), access.Convert(), default, access == BufferAccess.Stream); } - public BufferHandle CreateBuffer(int size, BufferHandle storageHint) + public BufferHandle CreateBuffer(int size, BufferAccess access, BufferHandle storageHint) { - return BufferManager.CreateWithHandle(this, size, BufferAllocationType.Auto, storageHint); + return BufferManager.CreateWithHandle(this, size, access.HasFlag(BufferAccess.SparseCompatible), access.Convert(), storageHint); } public BufferHandle CreateBuffer(nint pointer, int size) @@ -412,6 +415,11 @@ namespace Ryujinx.Graphics.Vulkan return BufferManager.CreateHostImported(this, pointer, size); } + public BufferHandle CreateBufferSparse(ReadOnlySpan storageBuffers) + { + return BufferManager.CreateSparse(this, storageBuffers); + } + public IProgram CreateProgram(ShaderSource[] sources, ShaderInfo info) { bool isCompute = sources.Length == 1 && sources[0].Stage == ShaderStage.Compute; @@ -571,6 +579,7 @@ namespace Ryujinx.Graphics.Vulkan Api.GetPhysicalDeviceFeatures2(_physicalDevice.PhysicalDevice, &features2); var limits = _physicalDevice.PhysicalDeviceProperties.Limits; + var mainQueueProperties = _physicalDevice.QueueFamilyProperties[QueueFamilyIndex]; return new Capabilities( api: TargetApi.Vulkan, @@ -590,6 +599,7 @@ namespace Ryujinx.Graphics.Vulkan supportsR4G4B4A4Format: supportsR4G4B4A4Format, supportsSnormBufferTextureFormat: true, supports5BitComponentFormat: supports5BitComponentFormat, + supportsSparseBuffer: features2.Features.SparseBinding && mainQueueProperties.QueueFlags.HasFlag(QueueFlags.SparseBindingBit), supportsBlendEquationAdvanced: Capabilities.SupportsBlendEquationAdvanced, supportsFragmentShaderInterlock: Capabilities.SupportsFragmentShaderInterlock, supportsFragmentShaderOrderingIntel: false, @@ -628,7 +638,7 @@ namespace Ryujinx.Graphics.Vulkan public HardwareInfo GetHardwareInfo() { - return new HardwareInfo(GpuVendor, GpuRenderer); + return new HardwareInfo(GpuVendor, GpuRenderer, GpuDriver); } /// @@ -685,6 +695,8 @@ namespace Ryujinx.Graphics.Vulkan { var properties = _physicalDevice.PhysicalDeviceProperties; + var hasDriverProperties = _physicalDevice.TryGetPhysicalDeviceDriverPropertiesKHR(Api, out var driverProperties); + string vendorName = VendorUtils.GetNameFromId(properties.VendorID); Vendor = VendorUtils.FromId(properties.VendorID); @@ -699,6 +711,7 @@ namespace Ryujinx.Graphics.Vulkan Vendor == Vendor.ImgTec; GpuVendor = vendorName; + GpuDriver = hasDriverProperties ? Marshal.PtrToStringAnsi((IntPtr)driverProperties.DriverName) : vendorName; // Fall back to vendor name if driver name isn't available. GpuRenderer = Marshal.PtrToStringAnsi((IntPtr)properties.DeviceName); GpuVersion = $"Vulkan v{ParseStandardVulkanVersion(properties.ApiVersion)}, Driver v{ParseDriverVersion(ref properties)}"; @@ -776,7 +789,7 @@ namespace Ryujinx.Graphics.Vulkan public void SetBufferData(BufferHandle buffer, int offset, ReadOnlySpan data) { - BufferManager.SetData(buffer, offset, data, _pipeline.CurrentCommandBuffer, _pipeline.EndRenderPass); + BufferManager.SetData(buffer, offset, data, _pipeline.CurrentCommandBuffer, _pipeline.EndRenderPassDelegate); } public void UpdateCounters() diff --git a/src/Ryujinx.Graphics.Vulkan/Window.cs b/src/Ryujinx.Graphics.Vulkan/Window.cs index afaa7defe..5ddb6eeda 100644 --- a/src/Ryujinx.Graphics.Vulkan/Window.cs +++ b/src/Ryujinx.Graphics.Vulkan/Window.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Vulkan.Effects; using Silk.NET.Vulkan; using Silk.NET.Vulkan.Extensions.KHR; @@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Vulkan private SwapchainKHR _swapchain; private Image[] _swapchainImages; - private Auto[] _swapchainImageViews; + private TextureView[] _swapchainImageViews; private Semaphore[] _imageAvailableSemaphores; private Semaphore[] _renderFinishedSemaphores; @@ -143,6 +143,23 @@ namespace Ryujinx.Graphics.Vulkan Clipped = true, }; + var textureCreateInfo = new TextureCreateInfo( + _width, + _height, + 1, + 1, + 1, + 1, + 1, + 1, + FormatTable.GetFormat(surfaceFormat.Format), + DepthStencilMode.Depth, + Target.Texture2D, + SwizzleComponent.Red, + SwizzleComponent.Green, + SwizzleComponent.Blue, + SwizzleComponent.Alpha); + _gd.SwapchainApi.CreateSwapchain(_device, swapchainCreateInfo, null, out _swapchain).ThrowOnError(); _gd.SwapchainApi.GetSwapchainImages(_device, _swapchain, &imageCount, null); @@ -154,11 +171,11 @@ namespace Ryujinx.Graphics.Vulkan _gd.SwapchainApi.GetSwapchainImages(_device, _swapchain, &imageCount, pSwapchainImages); } - _swapchainImageViews = new Auto[imageCount]; + _swapchainImageViews = new TextureView[imageCount]; for (int i = 0; i < _swapchainImageViews.Length; i++) { - _swapchainImageViews[i] = CreateSwapchainImageView(_swapchainImages[i], surfaceFormat.Format); + _swapchainImageViews[i] = CreateSwapchainImageView(_swapchainImages[i], surfaceFormat.Format, textureCreateInfo); } var semaphoreCreateInfo = new SemaphoreCreateInfo @@ -181,7 +198,7 @@ namespace Ryujinx.Graphics.Vulkan } } - private unsafe Auto CreateSwapchainImageView(Image swapchainImage, VkFormat format) + private unsafe TextureView CreateSwapchainImageView(Image swapchainImage, VkFormat format, TextureCreateInfo info) { var componentMapping = new ComponentMapping( ComponentSwizzle.R, @@ -204,7 +221,8 @@ namespace Ryujinx.Graphics.Vulkan }; _gd.Api.CreateImageView(_device, imageCreateInfo, null, out var imageView).ThrowOnError(); - return new Auto(new DisposableImageView(_gd.Api, _device, imageView)); + + return new TextureView(_gd, _device, new DisposableImageView(_gd.Api, _device, imageView), info, format); } private static SurfaceFormatKHR ChooseSwapSurfaceFormat(SurfaceFormatKHR[] availableFormats, bool colorSpacePassthroughEnabled) @@ -406,7 +424,7 @@ namespace Ryujinx.Graphics.Vulkan _scalingFilter.Run( view, cbs, - _swapchainImageViews[nextImage], + _swapchainImageViews[nextImage].GetImageViewForAttachment(), _format, _width, _height, @@ -421,11 +439,6 @@ namespace Ryujinx.Graphics.Vulkan cbs, view, _swapchainImageViews[nextImage], - _width, - _height, - 1, - _format, - false, new Extents2D(srcX0, srcY0, srcX1, srcY1), new Extents2D(dstX0, dstY1, dstX1, dstY0), _isLinear, diff --git a/src/Ryujinx.Graphics.Vulkan/WindowBase.cs b/src/Ryujinx.Graphics.Vulkan/WindowBase.cs index da1613f41..edb9c688c 100644 --- a/src/Ryujinx.Graphics.Vulkan/WindowBase.cs +++ b/src/Ryujinx.Graphics.Vulkan/WindowBase.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.GAL; using System; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.HLE/AssemblyInfo.cs b/src/Ryujinx.HLE/AssemblyInfo.cs index 82519d542..a3b3e594b 100644 --- a/src/Ryujinx.HLE/AssemblyInfo.cs +++ b/src/Ryujinx.HLE/AssemblyInfo.cs @@ -1,3 +1,3 @@ -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("Ryujinx.Tests")] diff --git a/src/Ryujinx.HLE/Exceptions/InternalServiceException.cs b/src/Ryujinx.HLE/Exceptions/InternalServiceException.cs index e0ee5eb91..ad764889e 100644 --- a/src/Ryujinx.HLE/Exceptions/InternalServiceException.cs +++ b/src/Ryujinx.HLE/Exceptions/InternalServiceException.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.Exceptions { diff --git a/src/Ryujinx.HLE/Exceptions/InvalidFirmwarePackageException.cs b/src/Ryujinx.HLE/Exceptions/InvalidFirmwarePackageException.cs index bddd827a0..fd9110327 100644 --- a/src/Ryujinx.HLE/Exceptions/InvalidFirmwarePackageException.cs +++ b/src/Ryujinx.HLE/Exceptions/InvalidFirmwarePackageException.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.Exceptions { diff --git a/src/Ryujinx.HLE/Exceptions/InvalidNpdmException.cs b/src/Ryujinx.HLE/Exceptions/InvalidNpdmException.cs index c4036ea0d..78d75680a 100644 --- a/src/Ryujinx.HLE/Exceptions/InvalidNpdmException.cs +++ b/src/Ryujinx.HLE/Exceptions/InvalidNpdmException.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.Exceptions { diff --git a/src/Ryujinx.HLE/Exceptions/InvalidSystemResourceException.cs b/src/Ryujinx.HLE/Exceptions/InvalidSystemResourceException.cs index d9afff111..9e95c0cf0 100644 --- a/src/Ryujinx.HLE/Exceptions/InvalidSystemResourceException.cs +++ b/src/Ryujinx.HLE/Exceptions/InvalidSystemResourceException.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.Exceptions { diff --git a/src/Ryujinx.HLE/Exceptions/ServiceNotImplementedException.cs b/src/Ryujinx.HLE/Exceptions/ServiceNotImplementedException.cs index 9cb1cf2c7..408b5baa4 100644 --- a/src/Ryujinx.HLE/Exceptions/ServiceNotImplementedException.cs +++ b/src/Ryujinx.HLE/Exceptions/ServiceNotImplementedException.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.HLE.HOS; using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Services; diff --git a/src/Ryujinx.HLE/FileSystem/ContentPath.cs b/src/Ryujinx.HLE/FileSystem/ContentPath.cs index 6d2f3f6ab..02539c5c6 100644 --- a/src/Ryujinx.HLE/FileSystem/ContentPath.cs +++ b/src/Ryujinx.HLE/FileSystem/ContentPath.cs @@ -1,4 +1,4 @@ -using LibHac.Fs; +using LibHac.Fs; using LibHac.Ncm; using Ryujinx.Common.Configuration; using System; diff --git a/src/Ryujinx.HLE/FileSystem/EncryptedFileSystemCreator.cs b/src/Ryujinx.HLE/FileSystem/EncryptedFileSystemCreator.cs index d50b80ffb..64b02a282 100644 --- a/src/Ryujinx.HLE/FileSystem/EncryptedFileSystemCreator.cs +++ b/src/Ryujinx.HLE/FileSystem/EncryptedFileSystemCreator.cs @@ -1,4 +1,4 @@ -using LibHac; +using LibHac; using LibHac.Common; using LibHac.Fs; using LibHac.Fs.Fsa; diff --git a/src/Ryujinx.HLE/FileSystem/LocationEntry.cs b/src/Ryujinx.HLE/FileSystem/LocationEntry.cs index dd4068aab..fb717665a 100644 --- a/src/Ryujinx.HLE/FileSystem/LocationEntry.cs +++ b/src/Ryujinx.HLE/FileSystem/LocationEntry.cs @@ -1,4 +1,4 @@ -using LibHac.Tools.FsSystem.NcaUtils; +using LibHac.Tools.FsSystem.NcaUtils; namespace Ryujinx.HLE.FileSystem { diff --git a/src/Ryujinx.HLE/FileSystem/VirtualFileSystem.cs b/src/Ryujinx.HLE/FileSystem/VirtualFileSystem.cs index 43bd27761..0827266a1 100644 --- a/src/Ryujinx.HLE/FileSystem/VirtualFileSystem.cs +++ b/src/Ryujinx.HLE/FileSystem/VirtualFileSystem.cs @@ -186,7 +186,12 @@ namespace Ryujinx.HLE.FileSystem public void InitializeFsServer(LibHac.Horizon horizon, out HorizonClient fsServerClient) { - LocalFileSystem serverBaseFs = new(AppDataManager.BaseDirPath); + LocalFileSystem serverBaseFs = new(useUnixTimeStamps: true); + Result result = serverBaseFs.Initialize(AppDataManager.BaseDirPath, LocalFileSystem.PathMode.DefaultCaseSensitivity, ensurePathExists: true); + if (result.IsFailure()) + { + throw new HorizonResultException(result, "Error creating LocalFileSystem."); + } fsServerClient = horizon.CreatePrivilegedHorizonClient(); var fsServer = new FileSystemServer(fsServerClient); diff --git a/src/Ryujinx.HLE/HLEConfiguration.cs b/src/Ryujinx.HLE/HLEConfiguration.cs index d52f1815a..f589bfdda 100644 --- a/src/Ryujinx.HLE/HLEConfiguration.cs +++ b/src/Ryujinx.HLE/HLEConfiguration.cs @@ -1,4 +1,4 @@ -using LibHac.Tools.FsSystem; +using LibHac.Tools.FsSystem; using Ryujinx.Audio.Integration; using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration.Multiplayer; diff --git a/src/Ryujinx.HLE/HOS/Applets/AppletManager.cs b/src/Ryujinx.HLE/HOS/Applets/AppletManager.cs index 93d49cd24..30300f1b6 100644 --- a/src/Ryujinx.HLE/HOS/Applets/AppletManager.cs +++ b/src/Ryujinx.HLE/HOS/Applets/AppletManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Applets.Browser; +using Ryujinx.HLE.HOS.Applets.Browser; using Ryujinx.HLE.HOS.Applets.Error; using Ryujinx.HLE.HOS.Services.Am.AppletAE; using System; diff --git a/src/Ryujinx.HLE/HOS/Applets/Browser/BootDisplayKind.cs b/src/Ryujinx.HLE/HOS/Applets/Browser/BootDisplayKind.cs index 11c1cb912..3c5b1f1c4 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Browser/BootDisplayKind.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Browser/BootDisplayKind.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.Browser +namespace Ryujinx.HLE.HOS.Applets.Browser { enum BootDisplayKind { diff --git a/src/Ryujinx.HLE/HOS/Applets/Browser/BrowserApplet.cs b/src/Ryujinx.HLE/HOS/Applets/Browser/BrowserApplet.cs index f50e6448f..6afbe4a72 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Browser/BrowserApplet.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Browser/BrowserApplet.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.Common.Memory; using Ryujinx.HLE.HOS.Services.Am.AppletAE; diff --git a/src/Ryujinx.HLE/HOS/Applets/Browser/BrowserArgument.cs b/src/Ryujinx.HLE/HOS/Applets/Browser/BrowserArgument.cs index 708781bf3..d2e1d55ca 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Browser/BrowserArgument.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Browser/BrowserArgument.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Account.Acc; +using Ryujinx.HLE.HOS.Services.Account.Acc; using System; using System.Collections.Generic; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.HLE/HOS/Applets/Browser/BrowserOutput.cs b/src/Ryujinx.HLE/HOS/Applets/Browser/BrowserOutput.cs index 443886fde..b0e2d0e1c 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Browser/BrowserOutput.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Browser/BrowserOutput.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using System; using System.IO; diff --git a/src/Ryujinx.HLE/HOS/Applets/Browser/BrowserOutputType.cs b/src/Ryujinx.HLE/HOS/Applets/Browser/BrowserOutputType.cs index 7f85bc81c..b6908c474 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Browser/BrowserOutputType.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Browser/BrowserOutputType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.Browser +namespace Ryujinx.HLE.HOS.Applets.Browser { enum BrowserOutputType : ushort { diff --git a/src/Ryujinx.HLE/HOS/Applets/Browser/DocumentKind.cs b/src/Ryujinx.HLE/HOS/Applets/Browser/DocumentKind.cs index 9d355cd75..9e089a205 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Browser/DocumentKind.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Browser/DocumentKind.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.Browser +namespace Ryujinx.HLE.HOS.Applets.Browser { enum DocumentKind { diff --git a/src/Ryujinx.HLE/HOS/Applets/Browser/LeftStickMode.cs b/src/Ryujinx.HLE/HOS/Applets/Browser/LeftStickMode.cs index 50ad7b8bb..7c2f31a25 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Browser/LeftStickMode.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Browser/LeftStickMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.Browser +namespace Ryujinx.HLE.HOS.Applets.Browser { enum LeftStickMode { diff --git a/src/Ryujinx.HLE/HOS/Applets/Browser/ShimKind.cs b/src/Ryujinx.HLE/HOS/Applets/Browser/ShimKind.cs index f097d1f4a..60de546d3 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Browser/ShimKind.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Browser/ShimKind.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.Browser +namespace Ryujinx.HLE.HOS.Applets.Browser { public enum ShimKind : uint { diff --git a/src/Ryujinx.HLE/HOS/Applets/Browser/WebArgHeader.cs b/src/Ryujinx.HLE/HOS/Applets/Browser/WebArgHeader.cs index c3cc711e4..e67d70917 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Browser/WebArgHeader.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Browser/WebArgHeader.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.Browser +namespace Ryujinx.HLE.HOS.Applets.Browser { public struct WebArgHeader { diff --git a/src/Ryujinx.HLE/HOS/Applets/Browser/WebArgTLV.cs b/src/Ryujinx.HLE/HOS/Applets/Browser/WebArgTLV.cs index 1b5510a5d..a331e82fe 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Browser/WebArgTLV.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Browser/WebArgTLV.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.Browser +namespace Ryujinx.HLE.HOS.Applets.Browser { public struct WebArgTLV { diff --git a/src/Ryujinx.HLE/HOS/Applets/Browser/WebArgTLVType.cs b/src/Ryujinx.HLE/HOS/Applets/Browser/WebArgTLVType.cs index 575138330..2f2450dcb 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Browser/WebArgTLVType.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Browser/WebArgTLVType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.Browser +namespace Ryujinx.HLE.HOS.Applets.Browser { enum WebArgTLVType : ushort { diff --git a/src/Ryujinx.HLE/HOS/Applets/Browser/WebCommonReturnValue.cs b/src/Ryujinx.HLE/HOS/Applets/Browser/WebCommonReturnValue.cs index a1bdf0c76..cc1f3706c 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Browser/WebCommonReturnValue.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Browser/WebCommonReturnValue.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.HLE.HOS.Applets.Browser { diff --git a/src/Ryujinx.HLE/HOS/Applets/Browser/WebExitReason.cs b/src/Ryujinx.HLE/HOS/Applets/Browser/WebExitReason.cs index 1959fc0b4..ebb705acb 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Browser/WebExitReason.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Browser/WebExitReason.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.Browser +namespace Ryujinx.HLE.HOS.Applets.Browser { public enum WebExitReason : uint { diff --git a/src/Ryujinx.HLE/HOS/Applets/CommonArguments.cs b/src/Ryujinx.HLE/HOS/Applets/CommonArguments.cs index 857798987..0360aff80 100644 --- a/src/Ryujinx.HLE/HOS/Applets/CommonArguments.cs +++ b/src/Ryujinx.HLE/HOS/Applets/CommonArguments.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Applets { diff --git a/src/Ryujinx.HLE/HOS/Applets/Error/ApplicationErrorArg.cs b/src/Ryujinx.HLE/HOS/Applets/Error/ApplicationErrorArg.cs index 4263c84b8..0a20bee46 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Error/ApplicationErrorArg.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Error/ApplicationErrorArg.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Applets.Error diff --git a/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs b/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs index fa415b396..5c474f229 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs @@ -1,4 +1,4 @@ -using LibHac.Common; +using LibHac.Common; using LibHac.Fs; using LibHac.Fs.Fsa; using LibHac.FsSystem; diff --git a/src/Ryujinx.HLE/HOS/Applets/Error/ErrorCommonArg.cs b/src/Ryujinx.HLE/HOS/Applets/Error/ErrorCommonArg.cs index a042739cb..73e03a1b2 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Error/ErrorCommonArg.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Error/ErrorCommonArg.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Applets.Error { diff --git a/src/Ryujinx.HLE/HOS/Applets/Error/ErrorCommonHeader.cs b/src/Ryujinx.HLE/HOS/Applets/Error/ErrorCommonHeader.cs index ca8e9220f..d4f77d6ef 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Error/ErrorCommonHeader.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Error/ErrorCommonHeader.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Applets.Error { diff --git a/src/Ryujinx.HLE/HOS/Applets/Error/ErrorType.cs b/src/Ryujinx.HLE/HOS/Applets/Error/ErrorType.cs index c5f7e4eb0..548176980 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Error/ErrorType.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Error/ErrorType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.Error +namespace Ryujinx.HLE.HOS.Applets.Error { enum ErrorType : byte { diff --git a/src/Ryujinx.HLE/HOS/Applets/IApplet.cs b/src/Ryujinx.HLE/HOS/Applets/IApplet.cs index 224d67874..5ccf3994f 100644 --- a/src/Ryujinx.HLE/HOS/Applets/IApplet.cs +++ b/src/Ryujinx.HLE/HOS/Applets/IApplet.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Am.AppletAE; +using Ryujinx.HLE.HOS.Services.Am.AppletAE; using Ryujinx.HLE.Ui; using Ryujinx.Memory; using System; diff --git a/src/Ryujinx.HLE/HOS/Applets/PlayerSelect/PlayerSelectApplet.cs b/src/Ryujinx.HLE/HOS/Applets/PlayerSelect/PlayerSelectApplet.cs index 8db23d30b..ccc761ba1 100644 --- a/src/Ryujinx.HLE/HOS/Applets/PlayerSelect/PlayerSelectApplet.cs +++ b/src/Ryujinx.HLE/HOS/Applets/PlayerSelect/PlayerSelectApplet.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.HLE.HOS.Services.Account.Acc; using Ryujinx.HLE.HOS.Services.Am.AppletAE; using System; diff --git a/src/Ryujinx.HLE/HOS/Applets/PlayerSelect/PlayerSelectResult.cs b/src/Ryujinx.HLE/HOS/Applets/PlayerSelect/PlayerSelectResult.cs index d07aadf4b..c0475b75a 100644 --- a/src/Ryujinx.HLE/HOS/Applets/PlayerSelect/PlayerSelectResult.cs +++ b/src/Ryujinx.HLE/HOS/Applets/PlayerSelect/PlayerSelectResult.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets +namespace Ryujinx.HLE.HOS.Applets { enum PlayerSelectResult : ulong { diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/CJKCharacterValidation.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/CJKCharacterValidation.cs index 722fe60af..6134a3cdd 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/CJKCharacterValidation.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/CJKCharacterValidation.cs @@ -1,4 +1,4 @@ -using System.Text.RegularExpressions; +using System.Text.RegularExpressions; namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InitialCursorPosition.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InitialCursorPosition.cs index be94ee482..a95af67a8 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InitialCursorPosition.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InitialCursorPosition.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard +namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { /// /// Identifies the initial position of the cursor displayed in the area. diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardRequest.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardRequest.cs index cc2938e04..f95a3627d 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardRequest.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardRequest.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard +namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { /// /// Possible requests to the software keyboard when running in inline mode. diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardResponse.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardResponse.cs index 2179752e1..ed4b78c8e 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardResponse.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardResponse.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard +namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { /// /// Possible responses from the software keyboard when running in inline mode. diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardState.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardState.cs index da802fbc1..91d0164e3 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardState.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardState.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard +namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { /// /// Possible states for the software keyboard when running in inline mode. diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineResponses.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineResponses.cs index e8e57a48d..46e541a9e 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineResponses.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineResponses.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; using System.Text; namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InputFormMode.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InputFormMode.cs index 9b7ef9c61..780c82b53 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InputFormMode.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InputFormMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard +namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { /// /// Identifies the text entry mode. diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InvalidButtonFlags.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InvalidButtonFlags.cs index 4928c1943..8d81d4a11 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InvalidButtonFlags.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InvalidButtonFlags.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InvalidCharFlags.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InvalidCharFlags.cs index f2dcc5823..aa703f5d6 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InvalidCharFlags.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InvalidCharFlags.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardCalcFlags.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardCalcFlags.cs index e1402b1b2..6f7f6d2a9 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardCalcFlags.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardCalcFlags.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardInputMode.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardInputMode.cs index 925d52f6f..a75ef8cc6 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardInputMode.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardInputMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard +namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { /// /// Active input options set by the keyboard applet. These options allow keyboard diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMiniaturizationMode.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMiniaturizationMode.cs index b5ebabebb..3c96a61ab 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMiniaturizationMode.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMiniaturizationMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard +namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { /// /// The miniaturization mode used by the keyboard in inline mode. diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMode.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMode.cs index c2dfc31a3..aa79dd426 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMode.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard +namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { /// /// Identifies the variant of keyboard displayed on screen. diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardResult.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardResult.cs index dc39feb87..7c6d5c70b 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardResult.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardResult.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard +namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { /// /// The intention of the user when they finish the interaction with the keyboard. diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/PasswordMode.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/PasswordMode.cs index b5ea7faa2..040eee3e4 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/PasswordMode.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/PasswordMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard +namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { /// /// Identifies the display mode of text in a password field. diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardAppear.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardAppear.cs index fb6aad649..49c8160d1 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardAppear.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardAppear.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardAppearEx.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardAppearEx.cs index 29cd0a73c..31cb27e22 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardAppearEx.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardAppearEx.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs index e0f6e3f0c..432bf6a8a 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Applets.SoftwareKeyboard; diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCalc.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCalc.cs index 2941e15d1..cb02f8b46 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCalc.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCalc.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCalcEx.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCalcEx.cs index 2d3d5dbe9..abc3950cc 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCalcEx.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCalcEx.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardConfig.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardConfig.cs index 58c389e1a..5261bc8f4 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardConfig.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardConfig.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCustomizeDic.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCustomizeDic.cs index 53c8c8950..4d08dda17 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCustomizeDic.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCustomizeDic.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardDictSet.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardDictSet.cs index 385548816..0d757c442 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardDictSet.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardDictSet.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardInitialize.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardInitialize.cs index 764d0e38f..743d40a2e 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardInitialize.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardInitialize.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRenderer.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRenderer.cs index 2331e36ab..f76cce295 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRenderer.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRenderer.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.Ui; +using Ryujinx.HLE.Ui; using Ryujinx.Memory; using System; using System.Threading; diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs index 2f4fd2a89..3971a33be 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.Ui; +using Ryujinx.HLE.Ui; using Ryujinx.Memory; using SixLabors.Fonts; using SixLabors.ImageSharp; diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardState.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardState.cs index 92a943f27..86302e492 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardState.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardState.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard +namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { /// /// Identifies the software keyboard state. diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUiState.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUiState.cs index aed53d40d..608d51f32 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUiState.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUiState.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.Ui; +using Ryujinx.HLE.Ui; namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUserWord.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUserWord.cs index f1bfec2b3..84836884d 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUserWord.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUserWord.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TRef.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TRef.cs index 53746e745..32d9e68da 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TRef.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TRef.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard +namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { /// /// Wraps a type in a class so it gets stored in the GC managed heap. This is used as communication mechanism diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TimedAction.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TimedAction.cs index f44dc5da0..3eaf64596 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TimedAction.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TimedAction.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading; namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard diff --git a/src/Ryujinx.HLE/HOS/ArmProcessContext.cs b/src/Ryujinx.HLE/HOS/ArmProcessContext.cs index 99b355286..fde489ab7 100644 --- a/src/Ryujinx.HLE/HOS/ArmProcessContext.cs +++ b/src/Ryujinx.HLE/HOS/ArmProcessContext.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Memory; +using ARMeilleure.Memory; using Ryujinx.Cpu; using Ryujinx.Graphics.Gpu; using Ryujinx.HLE.HOS.Kernel.Process; @@ -57,6 +57,8 @@ namespace Ryujinx.HLE.HOS public void Execute(IExecutionContext context, ulong codeAddress) { + // We must wait until shader cache is loaded, among other things, before executing CPU code. + _gpuContext.WaitUntilGpuReady(); _cpuContext.Execute(context, codeAddress); } @@ -85,6 +87,8 @@ namespace Ryujinx.HLE.HOS _memoryManager = null; _gpuContext.UnregisterProcess(_pid); } + + _cpuContext.Dispose(); } } } diff --git a/src/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs b/src/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs index 7ff055a69..06b8fd345 100644 --- a/src/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs +++ b/src/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs @@ -1,8 +1,9 @@ -using Ryujinx.Common.Configuration; +using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Cpu; using Ryujinx.Cpu.AppleHv; using Ryujinx.Cpu.Jit; +using Ryujinx.Cpu.LightningJit; using Ryujinx.Graphics.Gpu; using Ryujinx.HLE.HOS.Kernel; using Ryujinx.HLE.HOS.Kernel.Process; @@ -46,7 +47,9 @@ namespace Ryujinx.HLE.HOS { IArmProcessContext processContext; - if (OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64 && for64Bit && context.Device.Configuration.UseHypervisor) + bool isArm64Host = RuntimeInformation.ProcessArchitecture == Architecture.Arm64; + + if (OperatingSystem.IsMacOS() && isArm64Host && for64Bit && context.Device.Configuration.UseHypervisor) { var cpuEngine = new HvEngine(_tickSource); var memoryManager = new HvMemoryManager(context.Memory, addressSpaceSize, invalidAccessHandler); @@ -63,7 +66,9 @@ namespace Ryujinx.HLE.HOS mode = MemoryManagerMode.SoftwarePageTable; } - var cpuEngine = new JitEngine(_tickSource); + ICpuEngine cpuEngine = isArm64Host && (mode == MemoryManagerMode.HostMapped || mode == MemoryManagerMode.HostMappedUnsafe) + ? new LightningJitEngine(_tickSource) + : new JitEngine(_tickSource); AddressSpace addressSpace = null; diff --git a/src/Ryujinx.HLE/HOS/Diagnostics/Demangler/Demangler.cs b/src/Ryujinx.HLE/HOS/Diagnostics/Demangler/Demangler.cs index 311488bcb..171a083f3 100644 --- a/src/Ryujinx.HLE/HOS/Diagnostics/Demangler/Demangler.cs +++ b/src/Ryujinx.HLE/HOS/Diagnostics/Demangler/Demangler.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast; +using Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast; using System; using System.Collections.Generic; using System.IO; diff --git a/src/Ryujinx.HLE/HOS/HomebrewRomFsStream.cs b/src/Ryujinx.HLE/HOS/HomebrewRomFsStream.cs index 2cba640b8..02b39da37 100644 --- a/src/Ryujinx.HLE/HOS/HomebrewRomFsStream.cs +++ b/src/Ryujinx.HLE/HOS/HomebrewRomFsStream.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; namespace Ryujinx.HLE.HOS diff --git a/src/Ryujinx.HLE/HOS/Horizon.cs b/src/Ryujinx.HLE/HOS/Horizon.cs index 1a402240f..cd1719580 100644 --- a/src/Ryujinx.HLE/HOS/Horizon.cs +++ b/src/Ryujinx.HLE/HOS/Horizon.cs @@ -330,7 +330,7 @@ namespace Ryujinx.HLE.HOS HorizonFsClient fsClient = new(this); ServiceTable = new ServiceTable(); - var services = ServiceTable.GetServices(new HorizonOptions(Device.Configuration.IgnoreMissingServices, LibHacHorizonManager.BcatClient, fsClient)); + var services = ServiceTable.GetServices(new HorizonOptions(Device.Configuration.IgnoreMissingServices, LibHacHorizonManager.BcatClient, fsClient, AccountManager)); foreach (var service in services) { diff --git a/src/Ryujinx.HLE/HOS/Kernel/KernelConstants.cs b/src/Ryujinx.HLE/HOS/Kernel/KernelConstants.cs index 3dbaec187..2c01efecc 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/KernelConstants.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/KernelConstants.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Kernel.Memory; +using Ryujinx.HLE.HOS.Kernel.Memory; namespace Ryujinx.HLE.HOS.Kernel { diff --git a/src/Ryujinx.HLE/HOS/Kernel/KernelContext.cs b/src/Ryujinx.HLE/HOS/Kernel/KernelContext.cs index ccc5c0f0b..89d788c54 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/KernelContext.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/KernelContext.cs @@ -1,4 +1,4 @@ -using Ryujinx.Cpu; +using Ryujinx.Cpu; using Ryujinx.HLE.HOS.Kernel.Common; using Ryujinx.HLE.HOS.Kernel.Memory; using Ryujinx.HLE.HOS.Kernel.Process; diff --git a/src/Ryujinx.HLE/HOS/Kernel/KernelStatic.cs b/src/Ryujinx.HLE/HOS/Kernel/KernelStatic.cs index 2234a8c42..f5ecba752 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/KernelStatic.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/KernelStatic.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Kernel.Memory; +using Ryujinx.HLE.HOS.Kernel.Memory; using Ryujinx.HLE.HOS.Kernel.Process; using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.Horizon.Common; diff --git a/src/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryBlockManager.cs b/src/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryBlockManager.cs index e9146aeb8..f13a3554a 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryBlockManager.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryBlockManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Collections; +using Ryujinx.Common.Collections; using Ryujinx.Horizon.Common; using System.Diagnostics; diff --git a/src/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs b/src/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs index 6d0a16581..e56304d9d 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Kernel.Common; +using Ryujinx.HLE.HOS.Kernel.Common; using System; namespace Ryujinx.HLE.HOS.Kernel.Memory diff --git a/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageBitmap.cs b/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageBitmap.cs index e0f9df484..947983d61 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageBitmap.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageBitmap.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using System; using System.Numerics; diff --git a/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageHeap.cs b/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageHeap.cs index 635dcced8..ee5d6e2b6 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageHeap.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageHeap.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using System; namespace Ryujinx.HLE.HOS.Kernel.Memory diff --git a/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTable.cs b/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTable.cs index 4cd3e6fdd..543acb7a0 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTable.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTable.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Memory; using Ryujinx.Memory.Range; using System; diff --git a/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs b/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs index 2b6d4e4e9..b065e9c58 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs @@ -675,7 +675,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory KMemoryPermission.None, MemoryAttribute.Mask, MemoryAttribute.None, - MemoryAttribute.IpcAndDeviceMapped, + MemoryAttribute.IpcAndDeviceMapped | MemoryAttribute.PermissionLocked, out MemoryState state, out _, out _); @@ -687,7 +687,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory state, KMemoryPermission.None, KMemoryPermission.None, - MemoryAttribute.Mask, + MemoryAttribute.Mask & ~MemoryAttribute.PermissionLocked, MemoryAttribute.None); if (success) @@ -913,19 +913,27 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory return Result.Success; } - public Result SetMemoryAttribute( - ulong address, - ulong size, - MemoryAttribute attributeMask, - MemoryAttribute attributeValue) + public Result SetMemoryAttribute(ulong address, ulong size, MemoryAttribute attributeMask, MemoryAttribute attributeValue) { lock (_blockManager) { + MemoryState stateCheckMask = 0; + + if (attributeMask.HasFlag(MemoryAttribute.Uncached)) + { + stateCheckMask = MemoryState.AttributeChangeAllowed; + } + + if (attributeMask.HasFlag(MemoryAttribute.PermissionLocked)) + { + stateCheckMask |= MemoryState.PermissionLockAllowed; + } + if (CheckRange( address, size, - MemoryState.AttributeChangeAllowed, - MemoryState.AttributeChangeAllowed, + stateCheckMask, + stateCheckMask, KMemoryPermission.None, KMemoryPermission.None, MemoryAttribute.BorrowedAndIpcMapped, diff --git a/src/Ryujinx.HLE/HOS/Kernel/Memory/KScopedPageList.cs b/src/Ryujinx.HLE/HOS/Kernel/Memory/KScopedPageList.cs index 498e6f8c8..d9370165b 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Memory/KScopedPageList.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Memory/KScopedPageList.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Kernel.Memory { diff --git a/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryAttribute.cs b/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryAttribute.cs index 36b1ec8c3..e0fa60fab 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryAttribute.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryAttribute.cs @@ -12,11 +12,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory IpcMapped = 1 << 1, DeviceMapped = 1 << 2, Uncached = 1 << 3, + PermissionLocked = 1 << 4, IpcAndDeviceMapped = IpcMapped | DeviceMapped, - BorrowedAndIpcMapped = Borrowed | IpcMapped, - DeviceMappedAndUncached = DeviceMapped | Uncached, } } diff --git a/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryFillValue.cs b/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryFillValue.cs index cdc892fc5..74a88b48f 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryFillValue.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryFillValue.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Kernel.Memory +namespace Ryujinx.HLE.HOS.Kernel.Memory { enum MemoryFillValue : byte { diff --git a/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryState.cs b/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryState.cs index 273b58e5e..da6fac639 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryState.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryState.cs @@ -5,35 +5,155 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory [Flags] enum MemoryState : uint { - Unmapped = 0x00000000, - Io = 0x00002001, - Normal = 0x00042002, - CodeStatic = 0x00DC7E03, - CodeMutable = 0x03FEBD04, - Heap = 0x037EBD05, - SharedMemory = 0x00402006, - ModCodeStatic = 0x00DD7E08, - ModCodeMutable = 0x03FFBD09, - IpcBuffer0 = 0x005C3C0A, - Stack = 0x005C3C0B, - ThreadLocal = 0x0040200C, - TransferMemoryIsolated = 0x015C3C0D, - TransferMemory = 0x005C380E, - ProcessMemory = 0x0040380F, - Reserved = 0x00000010, - IpcBuffer1 = 0x005C3811, - IpcBuffer3 = 0x004C2812, - KernelStack = 0x00002013, - CodeReadOnly = 0x00402214, - CodeWritable = 0x00402015, - UserMask = 0xff, - Mask = 0xffffffff, + Unmapped = 0x0, + Io = Mapped | 0x1, + Normal = Mapped | QueryPhysicalAddressAllowed | 0x2, + CodeStatic = ForceReadWritableByDebugSyscalls | + IpcSendAllowedType0 | + IpcSendAllowedType3 | + IpcSendAllowedType1 | + Mapped | + ProcessPermissionChangeAllowed | + QueryPhysicalAddressAllowed | + MapDeviceAllowed | + MapDeviceAlignedAllowed | + IsPoolAllocated | + MapProcessAllowed | + LinearMapped | + 0x3, + CodeMutable = PermissionChangeAllowed | + IpcSendAllowedType0 | + IpcSendAllowedType3 | + IpcSendAllowedType1 | + Mapped | + MapAllowed | + TransferMemoryAllowed | + QueryPhysicalAddressAllowed | + MapDeviceAllowed | + MapDeviceAlignedAllowed | + IpcBufferAllowed | + IsPoolAllocated | + MapProcessAllowed | + AttributeChangeAllowed | + CodeMemoryAllowed | + LinearMapped | + PermissionLockAllowed | + 0x4, + Heap = PermissionChangeAllowed | + IpcSendAllowedType0 | + IpcSendAllowedType3 | + IpcSendAllowedType1 | + Mapped | + MapAllowed | + TransferMemoryAllowed | + QueryPhysicalAddressAllowed | + MapDeviceAllowed | + MapDeviceAlignedAllowed | + IpcBufferAllowed | + IsPoolAllocated | + AttributeChangeAllowed | + CodeMemoryAllowed | + LinearMapped | + 0x5, + SharedMemory = Mapped | IsPoolAllocated | LinearMapped | 0x6, + ModCodeStatic = ForceReadWritableByDebugSyscalls | + IpcSendAllowedType0 | + IpcSendAllowedType3 | + IpcSendAllowedType1 | + Mapped | + ProcessPermissionChangeAllowed | + UnmapProcessCodeMemoryAllowed | + QueryPhysicalAddressAllowed | + MapDeviceAllowed | + MapDeviceAlignedAllowed | + IsPoolAllocated | + MapProcessAllowed | + LinearMapped | + 0x8, + ModCodeMutable = PermissionChangeAllowed | + IpcSendAllowedType0 | + IpcSendAllowedType3 | + IpcSendAllowedType1 | + Mapped | + MapAllowed | + UnmapProcessCodeMemoryAllowed | + TransferMemoryAllowed | + QueryPhysicalAddressAllowed | + MapDeviceAllowed | + MapDeviceAlignedAllowed | + IpcBufferAllowed | + IsPoolAllocated | + MapProcessAllowed | + AttributeChangeAllowed | + CodeMemoryAllowed | + LinearMapped | + PermissionLockAllowed | + 0x9, + IpcBuffer0 = IpcSendAllowedType0 | + IpcSendAllowedType3 | + IpcSendAllowedType1 | + Mapped | + QueryPhysicalAddressAllowed | + MapDeviceAllowed | + MapDeviceAlignedAllowed | + IsPoolAllocated | + LinearMapped | + 0xA, + Stack = IpcSendAllowedType0 | + IpcSendAllowedType3 | + IpcSendAllowedType1 | + Mapped | + QueryPhysicalAddressAllowed | + MapDeviceAllowed | + MapDeviceAlignedAllowed | + IsPoolAllocated | + LinearMapped | + 0xB, + ThreadLocal = Mapped | IsPoolAllocated | LinearMapped | 0xC, + TransferMemoryIsolated = IpcSendAllowedType0 | + IpcSendAllowedType3 | + IpcSendAllowedType1 | + Mapped | + QueryPhysicalAddressAllowed | + MapDeviceAllowed | + MapDeviceAlignedAllowed | + IsPoolAllocated | + AttributeChangeAllowed | + LinearMapped | + 0xD, + TransferMemory = IpcSendAllowedType3 | + IpcSendAllowedType1 | + Mapped | + QueryPhysicalAddressAllowed | + MapDeviceAllowed | + MapDeviceAlignedAllowed | + IsPoolAllocated | + LinearMapped | + 0xE, + ProcessMemory = IpcSendAllowedType3 | IpcSendAllowedType1 | Mapped | IsPoolAllocated | LinearMapped | 0xF, + Reserved = 0x10, + IpcBuffer1 = IpcSendAllowedType3 | + IpcSendAllowedType1 | + Mapped | + QueryPhysicalAddressAllowed | + MapDeviceAllowed | + MapDeviceAlignedAllowed | + IsPoolAllocated | + LinearMapped | + 0x11, + IpcBuffer3 = IpcSendAllowedType3 | Mapped | QueryPhysicalAddressAllowed | MapDeviceAllowed | IsPoolAllocated | LinearMapped | 0x12, + KernelStack = Mapped | 0x13, + CodeReadOnly = ForceReadWritableByDebugSyscalls | Mapped | IsPoolAllocated | LinearMapped | 0x14, + CodeWritable = Mapped | IsPoolAllocated | LinearMapped | 0x15, + UserMask = 0xFF, + Mask = 0xFFFFFFFF, PermissionChangeAllowed = 1 << 8, ForceReadWritableByDebugSyscalls = 1 << 9, IpcSendAllowedType0 = 1 << 10, IpcSendAllowedType3 = 1 << 11, IpcSendAllowedType1 = 1 << 12, + Mapped = 1 << 13, ProcessPermissionChangeAllowed = 1 << 14, MapAllowed = 1 << 15, UnmapProcessCodeMemoryAllowed = 1 << 16, @@ -46,5 +166,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory MapProcessAllowed = 1 << 23, AttributeChangeAllowed = 1 << 24, CodeMemoryAllowed = 1 << 25, + LinearMapped = 1 << 26, + PermissionLockAllowed = 1 << 27, } } diff --git a/src/Ryujinx.HLE/HOS/Kernel/Memory/SharedMemoryStorage.cs b/src/Ryujinx.HLE/HOS/Kernel/Memory/SharedMemoryStorage.cs index c68b73695..54ccad0ab 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Memory/SharedMemoryStorage.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Memory/SharedMemoryStorage.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Kernel.Memory { diff --git a/src/Ryujinx.HLE/HOS/Kernel/Process/IProcessContext.cs b/src/Ryujinx.HLE/HOS/Kernel/Process/IProcessContext.cs index bdfef9d7a..ac36b781b 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Process/IProcessContext.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Process/IProcessContext.cs @@ -1,4 +1,4 @@ -using Ryujinx.Cpu; +using Ryujinx.Cpu; using Ryujinx.Memory; using System; diff --git a/src/Ryujinx.HLE/HOS/Kernel/Process/IProcessContextFactory.cs b/src/Ryujinx.HLE/HOS/Kernel/Process/IProcessContextFactory.cs index 0a24a5240..93af78c1a 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Process/IProcessContextFactory.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Process/IProcessContextFactory.cs @@ -1,4 +1,4 @@ -using Ryujinx.Memory; +using Ryujinx.Memory; namespace Ryujinx.HLE.HOS.Kernel.Process { diff --git a/src/Ryujinx.HLE/HOS/Kernel/Process/ProcessContext.cs b/src/Ryujinx.HLE/HOS/Kernel/Process/ProcessContext.cs index cab5c6082..b4ae6ec4e 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Process/ProcessContext.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Process/ProcessContext.cs @@ -1,4 +1,4 @@ -using Ryujinx.Cpu; +using Ryujinx.Cpu; using Ryujinx.Memory; using System; diff --git a/src/Ryujinx.HLE/HOS/Kernel/Process/ProcessContextFactory.cs b/src/Ryujinx.HLE/HOS/Kernel/Process/ProcessContextFactory.cs index 60dd5abf1..d2722b730 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Process/ProcessContextFactory.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Process/ProcessContextFactory.cs @@ -1,4 +1,4 @@ -using Ryujinx.Memory; +using Ryujinx.Memory; namespace Ryujinx.HLE.HOS.Kernel.Process { diff --git a/src/Ryujinx.HLE/HOS/Kernel/Process/ProcessCreationFlags.cs b/src/Ryujinx.HLE/HOS/Kernel/Process/ProcessCreationFlags.cs index c68190d69..f0e43e023 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Process/ProcessCreationFlags.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Process/ProcessCreationFlags.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics.CodeAnalysis; namespace Ryujinx.HLE.HOS.Kernel.Process diff --git a/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/InfoType.cs b/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/InfoType.cs index 2ca0d03a4..c0db82105 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/InfoType.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/InfoType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall +namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall { enum InfoType : uint { diff --git a/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/MemoryInfo.cs b/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/MemoryInfo.cs index c900781e9..beec621bf 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/MemoryInfo.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/MemoryInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Kernel.Memory; +using Ryujinx.HLE.HOS.Kernel.Memory; namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall { diff --git a/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/PointerSizedAttribute.cs b/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/PointerSizedAttribute.cs index 154164fb5..3d50e8962 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/PointerSizedAttribute.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/PointerSizedAttribute.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall { diff --git a/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcAttribute.cs b/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcAttribute.cs index b8839d1d3..24b51fb79 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcAttribute.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcAttribute.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall { diff --git a/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcImplAttribute.cs b/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcImplAttribute.cs index a32d851f6..8fe74e6b3 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcImplAttribute.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcImplAttribute.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall { diff --git a/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs b/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs index 82632f44c..b07f5194e 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.Cpu; using Ryujinx.HLE.Exceptions; @@ -949,8 +949,16 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall MemoryAttribute attributes = attributeMask | attributeValue; + const MemoryAttribute SupportedAttributes = MemoryAttribute.Uncached | MemoryAttribute.PermissionLocked; + if (attributes != attributeMask || - (attributes | MemoryAttribute.Uncached) != MemoryAttribute.Uncached) + (attributes | SupportedAttributes) != SupportedAttributes) + { + return KernelResult.InvalidCombination; + } + + // The permission locked attribute can't be unset. + if ((attributeMask & MemoryAttribute.PermissionLocked) != (attributeValue & MemoryAttribute.PermissionLocked)) { return KernelResult.InvalidCombination; } diff --git a/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/ThreadContext.cs b/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/ThreadContext.cs index fd1b41e32..cca6dda0f 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/ThreadContext.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/ThreadContext.cs @@ -1,4 +1,4 @@ -using ARMeilleure.State; +using ARMeilleure.State; using Ryujinx.Common.Memory; namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall diff --git a/src/Ryujinx.HLE/HOS/Kernel/Threading/KThreadContext.cs b/src/Ryujinx.HLE/HOS/Kernel/Threading/KThreadContext.cs index e8ad53c28..9a616a135 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Threading/KThreadContext.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Threading/KThreadContext.cs @@ -1,4 +1,4 @@ -using Ryujinx.Cpu; +using Ryujinx.Cpu; using Ryujinx.Horizon.Common; using System.Threading; diff --git a/src/Ryujinx.HLE/HOS/LibHacHorizonManager.cs b/src/Ryujinx.HLE/HOS/LibHacHorizonManager.cs index 01d4b2450..e8ef15dce 100644 --- a/src/Ryujinx.HLE/HOS/LibHacHorizonManager.cs +++ b/src/Ryujinx.HLE/HOS/LibHacHorizonManager.cs @@ -1,4 +1,4 @@ -using LibHac; +using LibHac; using LibHac.Bcat; using LibHac.Common; using LibHac.FsSrv.Impl; diff --git a/src/Ryujinx.HLE/HOS/ModLoader.cs b/src/Ryujinx.HLE/HOS/ModLoader.cs index 834bc0595..8ae529655 100644 --- a/src/Ryujinx.HLE/HOS/ModLoader.cs +++ b/src/Ryujinx.HLE/HOS/ModLoader.cs @@ -7,6 +7,7 @@ using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem.RomFs; using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; +using Ryujinx.Common.Utilities; using Ryujinx.HLE.HOS.Kernel.Process; using Ryujinx.HLE.Loaders.Executables; using Ryujinx.HLE.Loaders.Mods; @@ -17,6 +18,7 @@ using System.Collections.Specialized; using System.Globalization; using System.IO; using System.Linq; +using LazyFile = Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy.LazyFile; using Path = System.IO.Path; namespace Ryujinx.HLE.HOS @@ -37,15 +39,19 @@ namespace Ryujinx.HLE.HOS private const string AmsNroPatchDir = "nro_patches"; private const string AmsKipPatchDir = "kip_patches"; + private static readonly ModMetadataJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions()); + public readonly struct Mod where T : FileSystemInfo { public readonly string Name; public readonly T Path; + public readonly bool Enabled; - public Mod(string name, T path) + public Mod(string name, T path, bool enabled) { Name = name; Path = path; + Enabled = enabled; } } @@ -67,7 +73,7 @@ namespace Ryujinx.HLE.HOS } } - // Title dependent mods + // Application dependent mods public class ModCache { public List> RomfsContainers { get; } @@ -88,7 +94,7 @@ namespace Ryujinx.HLE.HOS } } - // Title independent mods + // Application independent mods private class PatchCache { public List> NsoPatches { get; } @@ -107,7 +113,7 @@ namespace Ryujinx.HLE.HOS } } - private readonly Dictionary _appMods; // key is TitleId + private readonly Dictionary _appMods; // key is ApplicationId private PatchCache _patches; private static readonly EnumerationOptions _dirEnumOptions; @@ -153,26 +159,52 @@ namespace Ryujinx.HLE.HOS return modsDir.FullName; } - private static DirectoryInfo FindTitleDir(DirectoryInfo contentsDir, string titleId) - => contentsDir.EnumerateDirectories(titleId, _dirEnumOptions).FirstOrDefault(); + private static DirectoryInfo FindApplicationDir(DirectoryInfo contentsDir, string applicationId) + => contentsDir.EnumerateDirectories(applicationId, _dirEnumOptions).FirstOrDefault(); - private static void AddModsFromDirectory(ModCache mods, DirectoryInfo dir, string titleId) + private static void AddModsFromDirectory(ModCache mods, DirectoryInfo dir, ModMetadata modMetadata) { System.Text.StringBuilder types = new(); foreach (var modDir in dir.EnumerateDirectories()) { types.Clear(); - Mod mod = new("", null); + Mod mod = new("", null, true); if (StrEquals(RomfsDir, modDir.Name)) { - mods.RomfsDirs.Add(mod = new Mod(dir.Name, modDir)); + bool enabled; + + try + { + var modData = modMetadata.Mods.Find(x => modDir.FullName.Contains(x.Path)); + enabled = modData.Enabled; + } + catch + { + // Mod is not in the list yet. New mods should be enabled by default. + enabled = true; + } + + mods.RomfsDirs.Add(mod = new Mod(dir.Name, modDir, enabled)); types.Append('R'); } else if (StrEquals(ExefsDir, modDir.Name)) { - mods.ExefsDirs.Add(mod = new Mod(dir.Name, modDir)); + bool enabled; + + try + { + var modData = modMetadata.Mods.Find(x => modDir.FullName.Contains(x.Path)); + enabled = modData.Enabled; + } + catch + { + // Mod is not in the list yet. New mods should be enabled by default. + enabled = true; + } + + mods.ExefsDirs.Add(mod = new Mod(dir.Name, modDir, enabled)); types.Append('E'); } else if (StrEquals(CheatDir, modDir.Name)) @@ -181,7 +213,7 @@ namespace Ryujinx.HLE.HOS } else { - AddModsFromDirectory(mods, modDir, titleId); + AddModsFromDirectory(mods, modDir, modMetadata); } if (types.Length > 0) @@ -191,18 +223,18 @@ namespace Ryujinx.HLE.HOS } } - public static string GetTitleDir(string modsBasePath, string titleId) + public static string GetApplicationDir(string modsBasePath, string applicationId) { var contentsDir = new DirectoryInfo(Path.Combine(modsBasePath, AmsContentsDir)); - var titleModsPath = FindTitleDir(contentsDir, titleId); + var applicationModsPath = FindApplicationDir(contentsDir, applicationId); - if (titleModsPath == null) + if (applicationModsPath == null) { - Logger.Info?.Print(LogClass.ModLoader, $"Creating mods directory for Title {titleId.ToUpper()}"); - titleModsPath = contentsDir.CreateSubdirectory(titleId); + Logger.Info?.Print(LogClass.ModLoader, $"Creating mods directory for Application {applicationId.ToUpper()}"); + applicationModsPath = contentsDir.CreateSubdirectory(applicationId); } - return titleModsPath.FullName; + return applicationModsPath.FullName; } // Static Query Methods @@ -238,47 +270,68 @@ namespace Ryujinx.HLE.HOS foreach (var modDir in patchDir.EnumerateDirectories()) { - patches.Add(new Mod(modDir.Name, modDir)); + patches.Add(new Mod(modDir.Name, modDir, true)); Logger.Info?.Print(LogClass.ModLoader, $"Found {type} patch '{modDir.Name}'"); } } - private static void QueryTitleDir(ModCache mods, DirectoryInfo titleDir) + private static void QueryApplicationDir(ModCache mods, DirectoryInfo applicationDir, ulong applicationId) { - if (!titleDir.Exists) + if (!applicationDir.Exists) { return; } - var fsFile = new FileInfo(Path.Combine(titleDir.FullName, RomfsContainer)); - if (fsFile.Exists) + string modJsonPath = Path.Combine(AppDataManager.GamesDirPath, applicationId.ToString("x16"), "mods.json"); + ModMetadata modMetadata = new(); + + if (File.Exists(modJsonPath)) { - mods.RomfsContainers.Add(new Mod($"<{titleDir.Name} RomFs>", fsFile)); + try + { + modMetadata = JsonHelper.DeserializeFromFile(modJsonPath, _serializerContext.ModMetadata); + } + catch + { + Logger.Warning?.Print(LogClass.ModLoader, $"Failed to deserialize mod data for {applicationId:X16} at {modJsonPath}"); + } } - fsFile = new FileInfo(Path.Combine(titleDir.FullName, ExefsContainer)); + var fsFile = new FileInfo(Path.Combine(applicationDir.FullName, RomfsContainer)); if (fsFile.Exists) { - mods.ExefsContainers.Add(new Mod($"<{titleDir.Name} ExeFs>", fsFile)); + var modData = modMetadata.Mods.Find(x => fsFile.FullName.Contains(x.Path)); + var enabled = modData == null || modData.Enabled; + + mods.RomfsContainers.Add(new Mod($"<{applicationDir.Name} RomFs>", fsFile, enabled)); } - AddModsFromDirectory(mods, titleDir, titleDir.Name); + fsFile = new FileInfo(Path.Combine(applicationDir.FullName, ExefsContainer)); + if (fsFile.Exists) + { + var modData = modMetadata.Mods.Find(x => fsFile.FullName.Contains(x.Path)); + var enabled = modData == null || modData.Enabled; + + mods.ExefsContainers.Add(new Mod($"<{applicationDir.Name} ExeFs>", fsFile, enabled)); + } + + AddModsFromDirectory(mods, applicationDir, modMetadata); } - public static void QueryContentsDir(ModCache mods, DirectoryInfo contentsDir, ulong titleId) + public static void QueryContentsDir(ModCache mods, DirectoryInfo contentsDir, ulong applicationId) { if (!contentsDir.Exists) { return; } - Logger.Info?.Print(LogClass.ModLoader, $"Searching mods for {((titleId & 0x1000) != 0 ? "DLC" : "Title")} {titleId:X16}"); + Logger.Info?.Print(LogClass.ModLoader, $"Searching mods for {((applicationId & 0x1000) != 0 ? "DLC" : "Application")} {applicationId:X16} in \"{contentsDir.FullName}\""); - var titleDir = FindTitleDir(contentsDir, $"{titleId:x16}"); + var applicationDir = FindApplicationDir(contentsDir, $"{applicationId:x16}"); - if (titleDir != null) + if (applicationDir != null) { - QueryTitleDir(mods, titleDir); + QueryApplicationDir(mods, applicationDir, applicationId); } } @@ -387,9 +440,9 @@ namespace Ryujinx.HLE.HOS { if (IsContentsDir(searchDir.Name)) { - foreach ((ulong titleId, ModCache cache) in modCaches) + foreach ((ulong applicationId, ModCache cache) in modCaches) { - QueryContentsDir(cache, searchDir, titleId); + QueryContentsDir(cache, searchDir, applicationId); } return true; @@ -410,7 +463,7 @@ namespace Ryujinx.HLE.HOS if (!searchDir.Exists) { Logger.Warning?.Print(LogClass.ModLoader, $"Mod Search Dir '{searchDir.FullName}' doesn't exist"); - continue; + return; } if (!TryQuery(searchDir, patches, modCaches)) @@ -425,21 +478,21 @@ namespace Ryujinx.HLE.HOS patches.Initialized = true; } - public void CollectMods(IEnumerable titles, params string[] searchDirPaths) + public void CollectMods(IEnumerable applications, params string[] searchDirPaths) { Clear(); - foreach (ulong titleId in titles) + foreach (ulong applicationId in applications) { - _appMods[titleId] = new ModCache(); + _appMods[applicationId] = new ModCache(); } CollectMods(_appMods, _patches, searchDirPaths); } - internal IStorage ApplyRomFsMods(ulong titleId, IStorage baseStorage) + internal IStorage ApplyRomFsMods(ulong applicationId, IStorage baseStorage) { - if (!_appMods.TryGetValue(titleId, out ModCache mods) || mods.RomfsDirs.Count + mods.RomfsContainers.Count == 0) + if (!_appMods.TryGetValue(applicationId, out ModCache mods) || mods.RomfsDirs.Count + mods.RomfsContainers.Count == 0) { return baseStorage; } @@ -448,14 +501,19 @@ namespace Ryujinx.HLE.HOS var builder = new RomFsBuilder(); int count = 0; - Logger.Info?.Print(LogClass.ModLoader, $"Applying RomFS mods for Title {titleId:X16}"); + Logger.Info?.Print(LogClass.ModLoader, $"Applying RomFS mods for Application {applicationId:X16}"); // Prioritize loose files first foreach (var mod in mods.RomfsDirs) { + if (!mod.Enabled) + { + continue; + } + using (IFileSystem fs = new LocalFileSystem(mod.Path.FullName)) { - AddFiles(fs, mod.Name, fileSet, builder); + AddFiles(fs, mod.Name, mod.Path.FullName, fileSet, builder); } count++; } @@ -463,10 +521,15 @@ namespace Ryujinx.HLE.HOS // Then files inside images foreach (var mod in mods.RomfsContainers) { - Logger.Info?.Print(LogClass.ModLoader, $"Found 'romfs.bin' for Title {titleId:X16}"); + if (!mod.Enabled) + { + continue; + } + + Logger.Info?.Print(LogClass.ModLoader, $"Found 'romfs.bin' for Application {applicationId:X16}"); using (IFileSystem fs = new RomFsFileSystem(mod.Path.OpenRead().AsStorage())) { - AddFiles(fs, mod.Name, fileSet, builder); + AddFiles(fs, mod.Name, mod.Path.FullName, fileSet, builder); } count++; } @@ -499,18 +562,18 @@ namespace Ryujinx.HLE.HOS return newStorage; } - private static void AddFiles(IFileSystem fs, string modName, ISet fileSet, RomFsBuilder builder) + private static void AddFiles(IFileSystem fs, string modName, string rootPath, ISet fileSet, RomFsBuilder builder) { foreach (var entry in fs.EnumerateEntries() + .AsParallel() .Where(f => f.Type == DirectoryEntryType.File) .OrderBy(f => f.FullPath, StringComparer.Ordinal)) { - using var file = new UniqueRef(); + var file = new LazyFile(entry.FullPath, rootPath, fs); - fs.OpenFile(ref file.Ref, entry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure(); if (fileSet.Add(entry.FullPath)) { - builder.AddFile(entry.FullPath, file.Release()); + builder.AddFile(entry.FullPath, file); } else { @@ -519,9 +582,9 @@ namespace Ryujinx.HLE.HOS } } - internal bool ReplaceExefsPartition(ulong titleId, ref IFileSystem exefs) + internal bool ReplaceExefsPartition(ulong applicationId, ref IFileSystem exefs) { - if (!_appMods.TryGetValue(titleId, out ModCache mods) || mods.ExefsContainers.Count == 0) + if (!_appMods.TryGetValue(applicationId, out ModCache mods) || mods.ExefsContainers.Count == 0) { return false; } @@ -549,7 +612,7 @@ namespace Ryujinx.HLE.HOS public bool Modified => (Stubs.Data | Replaces.Data) != 0; } - internal ModLoadResult ApplyExefsMods(ulong titleId, NsoExecutable[] nsos) + internal ModLoadResult ApplyExefsMods(ulong applicationId, NsoExecutable[] nsos) { ModLoadResult modLoadResult = new() { @@ -557,7 +620,7 @@ namespace Ryujinx.HLE.HOS Replaces = new BitVector32(), }; - if (!_appMods.TryGetValue(titleId, out ModCache mods) || mods.ExefsDirs.Count == 0) + if (!_appMods.TryGetValue(applicationId, out ModCache mods) || mods.ExefsDirs.Count == 0) { return modLoadResult; } @@ -571,6 +634,11 @@ namespace Ryujinx.HLE.HOS foreach (var mod in exeMods) { + if (!mod.Enabled) + { + continue; + } + for (int i = 0; i < ProcessConst.ExeFsPrefixes.Length; ++i) { var nsoName = ProcessConst.ExeFsPrefixes[i]; @@ -637,11 +705,11 @@ namespace Ryujinx.HLE.HOS ApplyProgramPatches(nroPatches, 0, nro); } - internal bool ApplyNsoPatches(ulong titleId, params IExecutable[] programs) + internal bool ApplyNsoPatches(ulong applicationId, params IExecutable[] programs) { IEnumerable> nsoMods = _patches.NsoPatches; - if (_appMods.TryGetValue(titleId, out ModCache mods)) + if (_appMods.TryGetValue(applicationId, out ModCache mods)) { nsoMods = nsoMods.Concat(mods.ExefsDirs); } @@ -651,7 +719,7 @@ namespace Ryujinx.HLE.HOS return ApplyProgramPatches(nsoMods, 0x100, programs); } - internal void LoadCheats(ulong titleId, ProcessTamperInfo tamperInfo, TamperMachine tamperMachine) + internal void LoadCheats(ulong applicationId, ProcessTamperInfo tamperInfo, TamperMachine tamperMachine) { if (tamperInfo?.BuildIds == null || tamperInfo.CodeAddresses == null) { @@ -660,9 +728,9 @@ namespace Ryujinx.HLE.HOS return; } - Logger.Info?.Print(LogClass.ModLoader, $"Build ids found for title {titleId:X16}:\n {String.Join("\n ", tamperInfo.BuildIds)}"); + Logger.Info?.Print(LogClass.ModLoader, $"Build ids found for application {applicationId:X16}:\n {String.Join("\n ", tamperInfo.BuildIds)}"); - if (!_appMods.TryGetValue(titleId, out ModCache mods) || mods.Cheats.Count == 0) + if (!_appMods.TryGetValue(applicationId, out ModCache mods) || mods.Cheats.Count == 0) { return; } @@ -687,12 +755,12 @@ namespace Ryujinx.HLE.HOS tamperMachine.InstallAtmosphereCheat(cheat.Name, cheatId, cheat.Instructions, tamperInfo, exeAddress); } - EnableCheats(titleId, tamperMachine); + EnableCheats(applicationId, tamperMachine); } - internal static void EnableCheats(ulong titleId, TamperMachine tamperMachine) + internal static void EnableCheats(ulong applicationId, TamperMachine tamperMachine) { - var contentDirectory = FindTitleDir(new DirectoryInfo(Path.Combine(GetModsBasePath(), AmsContentsDir)), $"{titleId:x16}"); + var contentDirectory = FindApplicationDir(new DirectoryInfo(Path.Combine(GetModsBasePath(), AmsContentsDir)), $"{applicationId:x16}"); string enabledCheatsPath = Path.Combine(contentDirectory.FullName, CheatDir, "enabled.txt"); if (File.Exists(enabledCheatsPath)) @@ -724,6 +792,11 @@ namespace Ryujinx.HLE.HOS // Collect patches foreach (var mod in mods) { + if (!mod.Enabled) + { + continue; + } + var patchDir = mod.Path; foreach (var patchFile in patchDir.EnumerateFiles()) { diff --git a/src/Ryujinx.HLE/HOS/ResultCode.cs b/src/Ryujinx.HLE/HOS/ResultCode.cs index 3fec365cd..f13094600 100644 --- a/src/Ryujinx.HLE/HOS/ResultCode.cs +++ b/src/Ryujinx.HLE/HOS/ResultCode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS +namespace Ryujinx.HLE.HOS { public enum ResultCode { diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountManager.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountManager.cs index a6dde3c53..c724660ea 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountManager.cs @@ -1,9 +1,10 @@ -using LibHac; +using LibHac; using LibHac.Common; using LibHac.Fs; using LibHac.Fs.Shim; using Ryujinx.Common; using Ryujinx.Common.Logging; +using Ryujinx.Horizon.Sdk.Account; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -11,7 +12,7 @@ using System.Linq; namespace Ryujinx.HLE.HOS.Services.Account.Acc { - public class AccountManager + public class AccountManager : IEmulatorAccountManager { public static readonly UserId DefaultUserId = new("00000000000000010000000000000000"); @@ -106,6 +107,11 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc _accountSaveDataManager.Save(_profiles); } + public void OpenUserOnlinePlay(Uid userId) + { + OpenUserOnlinePlay(new UserId((long)userId.Low, (long)userId.High)); + } + public void OpenUserOnlinePlay(UserId userId) { if (_profiles.TryGetValue(userId.ToString(), out UserProfile profile)) @@ -127,6 +133,11 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc _accountSaveDataManager.Save(_profiles); } + public void CloseUserOnlinePlay(Uid userId) + { + CloseUserOnlinePlay(new UserId((long)userId.Low, (long)userId.High)); + } + public void CloseUserOnlinePlay(UserId userId) { if (_profiles.TryGetValue(userId.ToString(), out UserProfile profile)) diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountSaveDataManager.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountSaveDataManager.cs index c2ae0119c..b1ef0761c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountSaveDataManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountSaveDataManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Configuration; +using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Common.Utilities; using Ryujinx.HLE.HOS.Services.Account.Acc.Types; diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ManagerServer.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ManagerServer.cs index c43186de1..ec7fa5c4f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ManagerServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ManagerServer.cs @@ -1,10 +1,12 @@ -using Microsoft.IdentityModel.Tokens; +using Microsoft.IdentityModel.JsonWebTokens; +using Microsoft.IdentityModel.Tokens; using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.HLE.HOS.Services.Account.Acc.AsyncContext; using System; -using System.IdentityModel.Tokens.Jwt; +using System.Collections.Generic; using System.Security.Cryptography; +using System.Security.Principal; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -37,11 +39,6 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService credentials.Key.KeyId = parameters.ToString(); - var header = new JwtHeader(credentials) - { - { "jku", "https://e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1.0.0/certificates" }, - }; - byte[] rawUserId = new byte[0x10]; RandomNumberGenerator.Fill(rawUserId); @@ -51,23 +48,25 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService byte[] deviceAccountId = new byte[0x10]; RandomNumberGenerator.Fill(deviceId); - var payload = new JwtPayload + var descriptor = new SecurityTokenDescriptor { - { "sub", Convert.ToHexString(rawUserId).ToLower() }, - { "aud", "ed9e2f05d286f7b8" }, - { "di", Convert.ToHexString(deviceId).ToLower() }, - { "sn", "XAW10000000000" }, - { "bs:did", Convert.ToHexString(deviceAccountId).ToLower() }, - { "iss", "https://e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com" }, - { "typ", "id_token" }, - { "iat", DateTimeOffset.UtcNow.ToUnixTimeSeconds() }, - { "jti", Guid.NewGuid().ToString() }, - { "exp", (DateTimeOffset.UtcNow + TimeSpan.FromHours(3)).ToUnixTimeSeconds() }, + Subject = new GenericIdentity(Convert.ToHexString(rawUserId).ToLower()), + SigningCredentials = credentials, + Audience = "ed9e2f05d286f7b8", + Issuer = "https://e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com", + TokenType = "id_token", + IssuedAt = DateTime.UtcNow, + Expires = DateTime.UtcNow + TimeSpan.FromHours(3), + Claims = new Dictionary + { + { "jku", "https://e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1.0.0/certificates" }, + { "di", Convert.ToHexString(deviceId).ToLower() }, + { "sn", "XAW10000000000" }, + { "bs:did", Convert.ToHexString(deviceAccountId).ToLower() } + } }; - JwtSecurityToken securityToken = new(header, payload); - - return new JwtSecurityTokenHandler().WriteToken(securityToken); + return new JsonWebTokenHandler().CreateToken(descriptor); } public ResultCode CheckAvailability(ServiceCtx context) diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ProfileServer.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ProfileServer.cs index 08400baf2..72560618c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ProfileServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ProfileServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Cpu; using Ryujinx.HLE.Utilities; using System.Text; diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/ApplicationServiceServer.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/ApplicationServiceServer.cs index b30a81e94..da3555c83 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/ApplicationServiceServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/ApplicationServiceServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.Cpu; using Ryujinx.HLE.HOS.Kernel.Threading; diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/AsyncContext/AsyncExecution.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/AsyncContext/AsyncExecution.cs index c5f3d91ec..9e329b8db 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/AsyncContext/AsyncExecution.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/AsyncContext/AsyncExecution.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Kernel.Threading; using System; using System.Threading; diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForAdministrator.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForAdministrator.cs index 121b79373..74c135aed 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForAdministrator.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForAdministrator.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Account.Acc.AccountService; diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForSystemService.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForSystemService.cs index a586d21cc..682b5327f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForSystemService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForSystemService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.HLE.HOS.Services.Account.Acc.AccountService; namespace Ryujinx.HLE.HOS.Services.Account.Acc diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncContext.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncContext.cs index 2fa354b19..91daba5f0 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncContext.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncContext.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Ipc; +using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Services.Account.Acc.AsyncContext; using Ryujinx.Horizon.Common; using System; diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncNetworkServiceLicenseKindContext.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncNetworkServiceLicenseKindContext.cs index a7b0c0638..175838506 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncNetworkServiceLicenseKindContext.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncNetworkServiceLicenseKindContext.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Account.Acc.AsyncContext; +using Ryujinx.HLE.HOS.Services.Account.Acc.AsyncContext; namespace Ryujinx.HLE.HOS.Services.Account.Acc { diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IBaasAccessTokenAccessor.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IBaasAccessTokenAccessor.cs index f86e30746..b88815778 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IBaasAccessTokenAccessor.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IBaasAccessTokenAccessor.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Account.Acc +namespace Ryujinx.HLE.HOS.Services.Account.Acc { [Service("acc:aa", AccountServiceFlag.BaasAccessTokenAccessor)] // Max Sessions: 4 class IBaasAccessTokenAccessor : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/ProfilesJsonSerializerContext.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/ProfilesJsonSerializerContext.cs index d6446e735..7b5be9534 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/ProfilesJsonSerializerContext.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/ProfilesJsonSerializerContext.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Account.Acc.Types; +using Ryujinx.HLE.HOS.Services.Account.Acc.Types; using System.Text.Json.Serialization; namespace Ryujinx.HLE.HOS.Services.Account.Acc diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/AccountServiceFlag.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/AccountServiceFlag.cs index 5dbf9a673..44478e932 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/AccountServiceFlag.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/AccountServiceFlag.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Account.Acc +namespace Ryujinx.HLE.HOS.Services.Account.Acc { enum AccountServiceFlag { diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/NetworkServiceLicenseKind.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/NetworkServiceLicenseKind.cs index a766edeff..5fe0e8664 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/NetworkServiceLicenseKind.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/NetworkServiceLicenseKind.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Account.Acc +namespace Ryujinx.HLE.HOS.Services.Account.Acc { enum NetworkServiceLicenseKind : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/ProfilesJson.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/ProfilesJson.cs index 4e22f434e..01c1482c3 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/ProfilesJson.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/ProfilesJson.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace Ryujinx.HLE.HOS.Services.Account.Acc.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserId.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserId.cs index ed7bf4e56..c9c78af9a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserId.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserId.cs @@ -1,4 +1,4 @@ -using LibHac.Account; +using LibHac.Account; using System; using System.Globalization; using System.IO; diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserProfile.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserProfile.cs index 4482de2dd..e6484822e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserProfile.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserProfile.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Account.Acc { diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserProfileJson.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserProfileJson.cs index e51aa8d1b..2e0e88230 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserProfileJson.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserProfileJson.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Account.Acc.Types +namespace Ryujinx.HLE.HOS.Services.Account.Acc.Types { internal struct UserProfileJson { diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Dauth/IService.cs b/src/Ryujinx.HLE/HOS/Services/Account/Dauth/IService.cs index 698c01a4a..24fc7aad8 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Dauth/IService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Dauth/IService.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Account.Dauth +namespace Ryujinx.HLE.HOS.Services.Account.Dauth { [Service("dauth:0")] // 5.0.0+ class IService : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ILibraryAppletProxy.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ILibraryAppletProxy.cs index 6821c7111..7700cac09 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ILibraryAppletProxy.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ILibraryAppletProxy.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletProxy; +using Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletProxy; using Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy; namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletCreator/ILibraryAppletAccessor.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletCreator/ILibraryAppletAccessor.cs index d35cfdbe2..148628136 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletCreator/ILibraryAppletAccessor.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletCreator/ILibraryAppletAccessor.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Applets; using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Kernel; diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/AppletStandalone.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/AppletStandalone.cs index b523f02f1..c996ed3b7 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/AppletStandalone.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/AppletStandalone.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletProxy { diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/ILibraryAppletSelfAccessor.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/ILibraryAppletSelfAccessor.cs index 85bdd985c..fc02ea172 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/ILibraryAppletSelfAccessor.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/ILibraryAppletSelfAccessor.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using System; namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletProxy diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/IProcessWindingController.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/IProcessWindingController.cs index e1857fb3e..d86a896d6 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/IProcessWindingController.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/IProcessWindingController.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletProxy { diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/IAppletCommonFunctions.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/IAppletCommonFunctions.cs index fbcc33204..13cdd8f11 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/IAppletCommonFunctions.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/IAppletCommonFunctions.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy +namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy { class IAppletCommonFunctions : IpcService { diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/Types/AlbumReportOption.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/Types/AlbumReportOption.cs index e4b434956..b0b582324 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/Types/AlbumReportOption.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/Types/AlbumReportOption.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.Types +namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.Types { enum AlbumReportOption { diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/Types/WirelessPriorityMode.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/Types/WirelessPriorityMode.cs index 3ea923f55..b06057b5f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/Types/WirelessPriorityMode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/Types/WirelessPriorityMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.Types +namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.Types { enum WirelessPriorityMode { diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AppletFifo.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AppletFifo.cs index e7482b789..926632531 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AppletFifo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AppletFifo.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AppletSession.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AppletSession.cs index 63eb2ca54..a3f44a45d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AppletSession.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AppletSession.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Am.AppletAE { diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/IAppletFifo.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/IAppletFifo.cs index ca79bac7a..24f183d23 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/IAppletFifo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/IAppletFifo.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Concurrent; namespace Ryujinx.HLE.HOS.Services.Am.AppletAE diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Storage/StorageHelper.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Storage/StorageHelper.cs index ef5951d70..6c23720ee 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Storage/StorageHelper.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Storage/StorageHelper.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.HLE.HOS.Services.Account.Acc; using System.IO; diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Types/AppletId.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Types/AppletId.cs index 503de4d2e..d9970341f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Types/AppletId.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Types/AppletId.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Am.AppletAE +namespace Ryujinx.HLE.HOS.Services.Am.AppletAE { enum AppletId { diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Types/AppletIdentityInfo.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Types/AppletIdentityInfo.cs index 84fd1b4ca..1f04c7ebb 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Types/AppletIdentityInfo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Types/AppletIdentityInfo.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Am.AppletAE { diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Types/AppletProcessLaunchReason.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Types/AppletProcessLaunchReason.cs index b6c32da5d..461c84eaa 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Types/AppletProcessLaunchReason.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Types/AppletProcessLaunchReason.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Am.AppletAE { diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Types/LibraryAppletInfo.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Types/LibraryAppletInfo.cs index 1205a7dcf..f8a911d42 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Types/LibraryAppletInfo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Types/LibraryAppletInfo.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Am.AppletAE { diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Types/LibraryAppletMode.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Types/LibraryAppletMode.cs index 044a3168c..629aee07d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Types/LibraryAppletMode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/Types/LibraryAppletMode.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Am.AppletAE { diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/Types/LaunchParameterKind.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/Types/LaunchParameterKind.cs index 7d82dcf5f..e3c90dc58 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/Types/LaunchParameterKind.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/Types/LaunchParameterKind.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.Types +namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.Types { public enum LaunchParameterKind : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/Types/ProgramSpecifyKind.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/Types/ProgramSpecifyKind.cs index 29ecf4217..47a755f93 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/Types/ProgramSpecifyKind.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/Types/ProgramSpecifyKind.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.Types +namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.Types { public enum ProgramSpecifyKind : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Am/Idle/IPolicyManagerSystem.cs b/src/Ryujinx.HLE/HOS/Services/Am/Idle/IPolicyManagerSystem.cs index 824d4c22f..1ff0e6d21 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/Idle/IPolicyManagerSystem.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/Idle/IPolicyManagerSystem.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Am.Idle +namespace Ryujinx.HLE.HOS.Services.Am.Idle { [Service("idle:sys")] class IPolicyManagerSystem : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Am/Omm/IOperationModeManager.cs b/src/Ryujinx.HLE/HOS/Services/Am/Omm/IOperationModeManager.cs index 44c4dafce..c9a402e70 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/Omm/IOperationModeManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/Omm/IOperationModeManager.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Am.Omm +namespace Ryujinx.HLE.HOS.Services.Am.Omm { [Service("omm")] class IOperationModeManager : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Am/Spsm/IPowerStateInterface.cs b/src/Ryujinx.HLE/HOS/Services/Am/Spsm/IPowerStateInterface.cs index 40a1300c1..b24acb247 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/Spsm/IPowerStateInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/Spsm/IPowerStateInterface.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Am.Spsm +namespace Ryujinx.HLE.HOS.Services.Am.Spsm { [Service("spsm")] class IPowerStateInterface : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Am/Tcap/IManager.cs b/src/Ryujinx.HLE/HOS/Services/Am/Tcap/IManager.cs index edb9618c6..6c6af3db0 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/Tcap/IManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/Tcap/IManager.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Am.Tcap +namespace Ryujinx.HLE.HOS.Services.Am.Tcap { [Service("tcap")] class IManager : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Apm/ManagerServer.cs b/src/Ryujinx.HLE/HOS/Services/Apm/ManagerServer.cs index 9a3a0462f..16bc4407b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Apm/ManagerServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Apm/ManagerServer.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Apm +namespace Ryujinx.HLE.HOS.Services.Apm { [Service("apm")] [Service("apm:am")] // 8.0.0+ diff --git a/src/Ryujinx.HLE/HOS/Services/Apm/PerformanceState.cs b/src/Ryujinx.HLE/HOS/Services/Apm/PerformanceState.cs index 0fb6c28a6..86a1491de 100644 --- a/src/Ryujinx.HLE/HOS/Services/Apm/PerformanceState.cs +++ b/src/Ryujinx.HLE/HOS/Services/Apm/PerformanceState.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Apm +namespace Ryujinx.HLE.HOS.Services.Apm { class PerformanceState { diff --git a/src/Ryujinx.HLE/HOS/Services/Apm/SessionServer.cs b/src/Ryujinx.HLE/HOS/Services/Apm/SessionServer.cs index 260992be7..d238e422a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Apm/SessionServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Apm/SessionServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; namespace Ryujinx.HLE.HOS.Services.Apm { diff --git a/src/Ryujinx.HLE/HOS/Services/Apm/SystemManagerServer.cs b/src/Ryujinx.HLE/HOS/Services/Apm/SystemManagerServer.cs index 3fe5b3834..e8b7d12aa 100644 --- a/src/Ryujinx.HLE/HOS/Services/Apm/SystemManagerServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Apm/SystemManagerServer.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Apm +namespace Ryujinx.HLE.HOS.Services.Apm { [Service("apm:sys")] class SystemManagerServer : ISystemManager diff --git a/src/Ryujinx.HLE/HOS/Services/Apm/Types/CpuBoostMode.cs b/src/Ryujinx.HLE/HOS/Services/Apm/Types/CpuBoostMode.cs index c84d32baf..263501571 100644 --- a/src/Ryujinx.HLE/HOS/Services/Apm/Types/CpuBoostMode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Apm/Types/CpuBoostMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Apm +namespace Ryujinx.HLE.HOS.Services.Apm { enum CpuBoostMode { diff --git a/src/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceConfiguration.cs b/src/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceConfiguration.cs index 6dd193f9b..650e4f4cb 100644 --- a/src/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceConfiguration.cs +++ b/src/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceConfiguration.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Apm +namespace Ryujinx.HLE.HOS.Services.Apm { enum PerformanceConfiguration : uint // Clocks are all in MHz. { // CPU | GPU | RAM | NOTE diff --git a/src/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceMode.cs b/src/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceMode.cs index 0a7719657..74f54c445 100644 --- a/src/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceMode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Apm +namespace Ryujinx.HLE.HOS.Services.Apm { enum PerformanceMode : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Arp/ApplicationLaunchProperty.cs b/src/Ryujinx.HLE/HOS/Services/Arp/ApplicationLaunchProperty.cs index 9c2b9d19a..26089bddb 100644 --- a/src/Ryujinx.HLE/HOS/Services/Arp/ApplicationLaunchProperty.cs +++ b/src/Ryujinx.HLE/HOS/Services/Arp/ApplicationLaunchProperty.cs @@ -1,4 +1,4 @@ -using LibHac.Ncm; +using LibHac.Ncm; namespace Ryujinx.HLE.HOS.Services.Arp { diff --git a/src/Ryujinx.HLE/HOS/Services/Arp/IReader.cs b/src/Ryujinx.HLE/HOS/Services/Arp/IReader.cs deleted file mode 100644 index 90cba861a..000000000 --- a/src/Ryujinx.HLE/HOS/Services/Arp/IReader.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Arp -{ - [Service("arp:r")] - class IReader : IpcService - { - public IReader(ServiceCtx context) { } - } -} diff --git a/src/Ryujinx.HLE/HOS/Services/Arp/IWriter.cs b/src/Ryujinx.HLE/HOS/Services/Arp/IWriter.cs deleted file mode 100644 index 7c3992c73..000000000 --- a/src/Ryujinx.HLE/HOS/Services/Arp/IWriter.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Arp -{ - [Service("arp:w")] - class IWriter : IpcService - { - public IWriter(ServiceCtx context) { } - } -} diff --git a/src/Ryujinx.HLE/HOS/Services/Arp/LibHacIReader.cs b/src/Ryujinx.HLE/HOS/Services/Arp/LibHacIReader.cs index fdddb79e5..f69d85003 100644 --- a/src/Ryujinx.HLE/HOS/Services/Arp/LibHacIReader.cs +++ b/src/Ryujinx.HLE/HOS/Services/Arp/LibHacIReader.cs @@ -1,4 +1,4 @@ -using LibHac; +using LibHac; using LibHac.Common; using LibHac.Ncm; using LibHac.Ns; diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioIn/AudioIn.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioIn/AudioIn.cs index ee8e46436..acf83f488 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/AudioIn/AudioIn.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioIn/AudioIn.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Common; +using Ryujinx.Audio.Common; using Ryujinx.Audio.Input; using Ryujinx.Audio.Integration; using Ryujinx.HLE.HOS.Kernel; diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioIn/AudioInServer.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioIn/AudioInServer.cs index 81b76e7a8..3f138021c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/AudioIn/AudioInServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioIn/AudioInServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Common; +using Ryujinx.Audio.Common; using Ryujinx.Cpu; using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Kernel.Threading; diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioIn/IAudioIn.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioIn/IAudioIn.cs index b5073fcee..4e67303df 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/AudioIn/IAudioIn.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioIn/IAudioIn.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Common; +using Ryujinx.Audio.Common; using Ryujinx.HLE.HOS.Kernel.Threading; using System; diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioInManager.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioInManager.cs index ba7462d36..1e759e0ca 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/AudioInManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioInManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Common; +using Ryujinx.Audio.Common; using Ryujinx.Audio.Input; using Ryujinx.HLE.HOS.Services.Audio.AudioIn; using AudioInManagerImpl = Ryujinx.Audio.Input.AudioInputManager; diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioInManagerServer.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioInManagerServer.cs index ac1863abe..1b35a62d8 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/AudioInManagerServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioInManagerServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Common; +using Ryujinx.Audio.Common; using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.Cpu; diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioOut/AudioOut.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioOut/AudioOut.cs index 8624ab9bc..2ccf0657f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/AudioOut/AudioOut.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioOut/AudioOut.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Common; +using Ryujinx.Audio.Common; using Ryujinx.Audio.Integration; using Ryujinx.Audio.Output; using Ryujinx.HLE.HOS.Kernel; diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioOut/AudioOutServer.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioOut/AudioOutServer.cs index 3b6834f7c..e1b252631 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/AudioOut/AudioOutServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioOut/AudioOutServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Common; +using Ryujinx.Audio.Common; using Ryujinx.Cpu; using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Kernel.Threading; diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioOut/IAudioOut.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioOut/IAudioOut.cs index 8533d3c51..8c8c68629 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/AudioOut/IAudioOut.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioOut/IAudioOut.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Common; +using Ryujinx.Audio.Common; using Ryujinx.HLE.HOS.Kernel.Threading; using System; diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioOutManager.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioOutManager.cs index fbbb3e1df..c45a485bc 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/AudioOutManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioOutManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Common; +using Ryujinx.Audio.Common; using Ryujinx.Audio.Output; using Ryujinx.HLE.HOS.Services.Audio.AudioOut; using AudioOutManagerImpl = Ryujinx.Audio.Output.AudioOutputManager; diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioOutManagerServer.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioOutManagerServer.cs index ca4d61630..79ae6a141 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/AudioOutManagerServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioOutManagerServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Common; +using Ryujinx.Audio.Common; using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.Cpu; diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioDevice.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioDevice.cs index 9a08f1ba9..6497a3b84 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioDevice.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioDevice.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Renderer.Device; +using Ryujinx.Audio.Renderer.Device; using Ryujinx.Audio.Renderer.Server; using Ryujinx.HLE.HOS.Kernel; using Ryujinx.HLE.HOS.Kernel.Threading; diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioDeviceServer.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioDeviceServer.cs index 9694406d6..6206215d5 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioDeviceServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioDeviceServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Cpu; using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Kernel.Threading; diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioKernelEvent.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioKernelEvent.cs index 55bf29ae1..414c70a43 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioKernelEvent.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioKernelEvent.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Integration; +using Ryujinx.Audio.Integration; using Ryujinx.HLE.HOS.Kernel.Threading; namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioRenderer.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioRenderer.cs index 8b8e55fb2..88456be3e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioRenderer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioRenderer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Integration; +using Ryujinx.Audio.Integration; using Ryujinx.Audio.Renderer.Server; using Ryujinx.HLE.HOS.Kernel.Threading; using System; diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioRendererServer.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioRendererServer.cs index af8d20ba7..baea01072 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioRendererServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/AudioRendererServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Common.Memory; using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Kernel.Threading; diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/IAudioDevice.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/IAudioDevice.cs index 4a1b5ffb1..0f181a477 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/IAudioDevice.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/IAudioDevice.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Kernel.Threading; +using Ryujinx.HLE.HOS.Kernel.Threading; namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer { diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/IAudioRenderer.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/IAudioRenderer.cs index 404bf4c10..6bb4a5dec 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/IAudioRenderer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioRenderer/IAudioRenderer.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Kernel.Threading; +using Ryujinx.HLE.HOS.Kernel.Threading; using System; namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager.cs index b40c32a12..87d0001e3 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Renderer.Device; +using Ryujinx.Audio.Renderer.Device; using Ryujinx.Audio.Renderer.Parameter; using Ryujinx.Audio.Renderer.Server; using Ryujinx.HLE.HOS.Kernel.Memory; diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManagerServer.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManagerServer.cs index 58a1daf10..38a841d82 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManagerServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManagerServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Renderer.Parameter; +using Ryujinx.Audio.Renderer.Parameter; using Ryujinx.Audio.Renderer.Server; using Ryujinx.Common; using Ryujinx.Common.Logging; diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioController.cs b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioController.cs index 223675808..a250ec799 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioController.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioController.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Audio +namespace Ryujinx.HLE.HOS.Services.Audio { [Service("audctl")] class IAudioController : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioInManager.cs b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioInManager.cs index 709320c82..861e9f2dc 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioInManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioInManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Common; +using Ryujinx.Audio.Common; using Ryujinx.HLE.HOS.Services.Audio.AudioIn; namespace Ryujinx.HLE.HOS.Services.Audio diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioInManagerForApplet.cs b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioInManagerForApplet.cs index 1735768c0..d0c385b56 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioInManagerForApplet.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioInManagerForApplet.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Audio +namespace Ryujinx.HLE.HOS.Services.Audio { [Service("audin:a")] class IAudioInManagerForApplet : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioInManagerForDebugger.cs b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioInManagerForDebugger.cs index ebdcfd8c2..120136158 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioInManagerForDebugger.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioInManagerForDebugger.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Audio +namespace Ryujinx.HLE.HOS.Services.Audio { [Service("audin:d")] class IAudioInManagerForDebugger : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioOutManager.cs b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioOutManager.cs index 70e60d2ed..cd7cbe41c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioOutManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioOutManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Common; +using Ryujinx.Audio.Common; using Ryujinx.HLE.HOS.Services.Audio.AudioOut; namespace Ryujinx.HLE.HOS.Services.Audio diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioOutManagerForApplet.cs b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioOutManagerForApplet.cs index 1c3502d6c..9925777e2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioOutManagerForApplet.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioOutManagerForApplet.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Audio +namespace Ryujinx.HLE.HOS.Services.Audio { [Service("audout:a")] class IAudioOutManagerForApplet : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioOutManagerForDebugger.cs b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioOutManagerForDebugger.cs index 1da017cbe..c41767a01 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioOutManagerForDebugger.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioOutManagerForDebugger.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Audio +namespace Ryujinx.HLE.HOS.Services.Audio { [Service("audout:d")] class IAudioOutManagerForDebugger : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioRendererManager.cs b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioRendererManager.cs index 642e25255..112e246c0 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioRendererManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioRendererManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Audio.Renderer.Parameter; +using Ryujinx.Audio.Renderer.Parameter; using Ryujinx.HLE.HOS.Kernel.Memory; using Ryujinx.HLE.HOS.Services.Audio.AudioRenderer; diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioRendererManagerForApplet.cs b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioRendererManagerForApplet.cs index 28aa6d8c9..dd767993d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioRendererManagerForApplet.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioRendererManagerForApplet.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Audio +namespace Ryujinx.HLE.HOS.Services.Audio { [Service("audren:a")] class IAudioRendererManagerForApplet : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioRendererManagerForDebugger.cs b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioRendererManagerForDebugger.cs index 50754f8a8..cd2af09b2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioRendererManagerForDebugger.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioRendererManagerForDebugger.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Audio +namespace Ryujinx.HLE.HOS.Services.Audio { [Service("audren:d")] class IAudioRendererManagerForDebugger : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioSnoopManager.cs b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioSnoopManager.cs index 73bc629fe..aa9789ac5 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/IAudioSnoopManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/IAudioSnoopManager.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Audio +namespace Ryujinx.HLE.HOS.Services.Audio { [Service("auddev")] // 6.0.0+ class IAudioSnoopManager : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/IFinalOutputRecorderManager.cs b/src/Ryujinx.HLE/HOS/Services/Audio/IFinalOutputRecorderManager.cs index 56647d04f..9b58213e9 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/IFinalOutputRecorderManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/IFinalOutputRecorderManager.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Audio +namespace Ryujinx.HLE.HOS.Services.Audio { [Service("audrec:u")] class IFinalOutputRecorderManager : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/IFinalOutputRecorderManagerForApplet.cs b/src/Ryujinx.HLE/HOS/Services/Audio/IFinalOutputRecorderManagerForApplet.cs index 6dfd5f968..e2d62eee3 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/IFinalOutputRecorderManagerForApplet.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/IFinalOutputRecorderManagerForApplet.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Audio +namespace Ryujinx.HLE.HOS.Services.Audio { [Service("audrec:a")] class IFinalOutputRecorderManagerForApplet : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/IFinalOutputRecorderManagerForDebugger.cs b/src/Ryujinx.HLE/HOS/Services/Audio/IFinalOutputRecorderManagerForDebugger.cs index 653ab598c..7ded79435 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/IFinalOutputRecorderManagerForDebugger.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/IFinalOutputRecorderManagerForDebugger.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Audio +namespace Ryujinx.HLE.HOS.Services.Audio { [Service("audrec:d")] class IFinalOutputRecorderManagerForDebugger : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/Types/OpusDecoderFlags.cs b/src/Ryujinx.HLE/HOS/Services/Audio/Types/OpusDecoderFlags.cs index e49c294c0..572535a92 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/Types/OpusDecoderFlags.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/Types/OpusDecoderFlags.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Audio.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/Types/OpusPacketHeader.cs b/src/Ryujinx.HLE/HOS/Services/Audio/Types/OpusPacketHeader.cs index 2c5478276..099769b3a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/Types/OpusPacketHeader.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/Types/OpusPacketHeader.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Buffers.Binary; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/Types/OpusParametersEx.cs b/src/Ryujinx.HLE/HOS/Services/Audio/Types/OpusParametersEx.cs index f088ed012..4d1e0c824 100644 --- a/src/Ryujinx.HLE/HOS/Services/Audio/Types/OpusParametersEx.cs +++ b/src/Ryujinx.HLE/HOS/Services/Audio/Types/OpusParametersEx.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Audio.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Bgtc/IStateControlService.cs b/src/Ryujinx.HLE/HOS/Services/Bgtc/IStateControlService.cs index 97d0cf946..3045712e8 100644 --- a/src/Ryujinx.HLE/HOS/Services/Bgtc/IStateControlService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Bgtc/IStateControlService.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Bgct +namespace Ryujinx.HLE.HOS.Services.Bgct { [Service("bgtc:sc")] class IStateControlService : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Bgtc/ITaskService.cs b/src/Ryujinx.HLE/HOS/Services/Bgtc/ITaskService.cs index 1b4b45f61..138c10afe 100644 --- a/src/Ryujinx.HLE/HOS/Services/Bgtc/ITaskService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Bgtc/ITaskService.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Bgct +namespace Ryujinx.HLE.HOS.Services.Bgct { [Service("bgtc:t")] class ITaskService : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Bluetooth/BluetoothDriver/BluetoothEventManager.cs b/src/Ryujinx.HLE/HOS/Services/Bluetooth/BluetoothDriver/BluetoothEventManager.cs index 5b8624001..2c7275276 100644 --- a/src/Ryujinx.HLE/HOS/Services/Bluetooth/BluetoothDriver/BluetoothEventManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Bluetooth/BluetoothDriver/BluetoothEventManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Kernel.Threading; +using Ryujinx.HLE.HOS.Kernel.Threading; namespace Ryujinx.HLE.HOS.Services.Bluetooth.BluetoothDriver { diff --git a/src/Ryujinx.HLE/HOS/Services/Bluetooth/IBluetoothDriver.cs b/src/Ryujinx.HLE/HOS/Services/Bluetooth/IBluetoothDriver.cs index ace2c86a4..8f2642695 100644 --- a/src/Ryujinx.HLE/HOS/Services/Bluetooth/IBluetoothDriver.cs +++ b/src/Ryujinx.HLE/HOS/Services/Bluetooth/IBluetoothDriver.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Ipc; +using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.HLE.HOS.Services.Bluetooth.BluetoothDriver; using Ryujinx.HLE.HOS.Services.Settings; diff --git a/src/Ryujinx.HLE/HOS/Services/Bluetooth/IBluetoothUser.cs b/src/Ryujinx.HLE/HOS/Services/Bluetooth/IBluetoothUser.cs index 04782d08e..ea4a46f92 100644 --- a/src/Ryujinx.HLE/HOS/Services/Bluetooth/IBluetoothUser.cs +++ b/src/Ryujinx.HLE/HOS/Services/Bluetooth/IBluetoothUser.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Ipc; +using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Services.Bluetooth.BluetoothDriver; using Ryujinx.HLE.HOS.Services.Settings; diff --git a/src/Ryujinx.HLE/HOS/Services/BluetoothManager/BtmUser/IBtmUserCore.cs b/src/Ryujinx.HLE/HOS/Services/BluetoothManager/BtmUser/IBtmUserCore.cs index da45dc776..d4e23b93d 100644 --- a/src/Ryujinx.HLE/HOS/Services/BluetoothManager/BtmUser/IBtmUserCore.cs +++ b/src/Ryujinx.HLE/HOS/Services/BluetoothManager/BtmUser/IBtmUserCore.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.Horizon.Common; diff --git a/src/Ryujinx.HLE/HOS/Services/BluetoothManager/IBtm.cs b/src/Ryujinx.HLE/HOS/Services/BluetoothManager/IBtm.cs index 13d14151a..87f4706a2 100644 --- a/src/Ryujinx.HLE/HOS/Services/BluetoothManager/IBtm.cs +++ b/src/Ryujinx.HLE/HOS/Services/BluetoothManager/IBtm.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.BluetoothManager +namespace Ryujinx.HLE.HOS.Services.BluetoothManager { [Service("btm")] class IBtm : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/BluetoothManager/IBtmDebug.cs b/src/Ryujinx.HLE/HOS/Services/BluetoothManager/IBtmDebug.cs index 43a6ccc6c..20e2b04e4 100644 --- a/src/Ryujinx.HLE/HOS/Services/BluetoothManager/IBtmDebug.cs +++ b/src/Ryujinx.HLE/HOS/Services/BluetoothManager/IBtmDebug.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.BluetoothManager +namespace Ryujinx.HLE.HOS.Services.BluetoothManager { [Service("btm:dbg")] class IBtmDebug : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/BluetoothManager/IBtmSystem.cs b/src/Ryujinx.HLE/HOS/Services/BluetoothManager/IBtmSystem.cs index 67d851b49..0efab8763 100644 --- a/src/Ryujinx.HLE/HOS/Services/BluetoothManager/IBtmSystem.cs +++ b/src/Ryujinx.HLE/HOS/Services/BluetoothManager/IBtmSystem.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.BluetoothManager +namespace Ryujinx.HLE.HOS.Services.BluetoothManager { [Service("btm:sys")] class IBtmSystem : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/BluetoothManager/IBtmUser.cs b/src/Ryujinx.HLE/HOS/Services/BluetoothManager/IBtmUser.cs index 225a71e33..78f8fd8f5 100644 --- a/src/Ryujinx.HLE/HOS/Services/BluetoothManager/IBtmUser.cs +++ b/src/Ryujinx.HLE/HOS/Services/BluetoothManager/IBtmUser.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.BluetoothManager.BtmUser; +using Ryujinx.HLE.HOS.Services.BluetoothManager.BtmUser; namespace Ryujinx.HLE.HOS.Services.BluetoothManager { diff --git a/src/Ryujinx.HLE/HOS/Services/BluetoothManager/ResultCode.cs b/src/Ryujinx.HLE/HOS/Services/BluetoothManager/ResultCode.cs index 01e62d2af..f729a688d 100644 --- a/src/Ryujinx.HLE/HOS/Services/BluetoothManager/ResultCode.cs +++ b/src/Ryujinx.HLE/HOS/Services/BluetoothManager/ResultCode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.BluetoothManager +namespace Ryujinx.HLE.HOS.Services.BluetoothManager { enum ResultCode { diff --git a/src/Ryujinx.HLE/HOS/Services/Caps/CaptureManager.cs b/src/Ryujinx.HLE/HOS/Services/Caps/CaptureManager.cs index 349dd34f9..91a8958e6 100644 --- a/src/Ryujinx.HLE/HOS/Services/Caps/CaptureManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Caps/CaptureManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.HLE.HOS.Services.Caps.Types; using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; diff --git a/src/Ryujinx.HLE/HOS/Services/Caps/IScreenShotApplicationService.cs b/src/Ryujinx.HLE/HOS/Services/Caps/IScreenShotApplicationService.cs index fb62b710d..0dad46c14 100644 --- a/src/Ryujinx.HLE/HOS/Services/Caps/IScreenShotApplicationService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Caps/IScreenShotApplicationService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.HLE.HOS.Services.Caps.Types; namespace Ryujinx.HLE.HOS.Services.Caps diff --git a/src/Ryujinx.HLE/HOS/Services/Caps/IScreenShotControlService.cs b/src/Ryujinx.HLE/HOS/Services/Caps/IScreenShotControlService.cs index c3e2036bb..77876b496 100644 --- a/src/Ryujinx.HLE/HOS/Services/Caps/IScreenShotControlService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Caps/IScreenShotControlService.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Caps +namespace Ryujinx.HLE.HOS.Services.Caps { [Service("caps:sc")] class IScreenShotControlService : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Caps/ResultCode.cs b/src/Ryujinx.HLE/HOS/Services/Caps/ResultCode.cs index 51a6fd8ac..7617ae9d3 100644 --- a/src/Ryujinx.HLE/HOS/Services/Caps/ResultCode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Caps/ResultCode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Caps +namespace Ryujinx.HLE.HOS.Services.Caps { enum ResultCode { diff --git a/src/Ryujinx.HLE/HOS/Services/Caps/Types/AlbumFileDateTime.cs b/src/Ryujinx.HLE/HOS/Services/Caps/Types/AlbumFileDateTime.cs index 09c9b1760..00c514525 100644 --- a/src/Ryujinx.HLE/HOS/Services/Caps/Types/AlbumFileDateTime.cs +++ b/src/Ryujinx.HLE/HOS/Services/Caps/Types/AlbumFileDateTime.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Caps.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Caps/Types/AlbumImageOrientation.cs b/src/Ryujinx.HLE/HOS/Services/Caps/Types/AlbumImageOrientation.cs index 2a1fbcac6..26afbd387 100644 --- a/src/Ryujinx.HLE/HOS/Services/Caps/Types/AlbumImageOrientation.cs +++ b/src/Ryujinx.HLE/HOS/Services/Caps/Types/AlbumImageOrientation.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Caps.Types +namespace Ryujinx.HLE.HOS.Services.Caps.Types { enum AlbumImageOrientation : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Caps/Types/AlbumStorage.cs b/src/Ryujinx.HLE/HOS/Services/Caps/Types/AlbumStorage.cs index 2fe99d455..9ae9767fd 100644 --- a/src/Ryujinx.HLE/HOS/Services/Caps/Types/AlbumStorage.cs +++ b/src/Ryujinx.HLE/HOS/Services/Caps/Types/AlbumStorage.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Caps.Types +namespace Ryujinx.HLE.HOS.Services.Caps.Types { enum AlbumStorage : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Caps/Types/ApplicationAlbumEntry.cs b/src/Ryujinx.HLE/HOS/Services/Caps/Types/ApplicationAlbumEntry.cs index 701fa63d9..fac5e58ff 100644 --- a/src/Ryujinx.HLE/HOS/Services/Caps/Types/ApplicationAlbumEntry.cs +++ b/src/Ryujinx.HLE/HOS/Services/Caps/Types/ApplicationAlbumEntry.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Caps.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Caps/Types/ContentType.cs b/src/Ryujinx.HLE/HOS/Services/Caps/Types/ContentType.cs index 56023d2ea..7b1d4062f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Caps/Types/ContentType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Caps/Types/ContentType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Caps.Types +namespace Ryujinx.HLE.HOS.Services.Caps.Types { enum ContentType : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Caps/Types/ScreenShotAttribute.cs b/src/Ryujinx.HLE/HOS/Services/Caps/Types/ScreenShotAttribute.cs index e7d8d0afd..d932f1b87 100644 --- a/src/Ryujinx.HLE/HOS/Services/Caps/Types/ScreenShotAttribute.cs +++ b/src/Ryujinx.HLE/HOS/Services/Caps/Types/ScreenShotAttribute.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Caps.Types diff --git a/src/Ryujinx.HLE/HOS/Services/CommandCmifAttribute.cs b/src/Ryujinx.HLE/HOS/Services/CommandCmifAttribute.cs index 5b4f30da9..17a5960ec 100644 --- a/src/Ryujinx.HLE/HOS/Services/CommandCmifAttribute.cs +++ b/src/Ryujinx.HLE/HOS/Services/CommandCmifAttribute.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services { diff --git a/src/Ryujinx.HLE/HOS/Services/CommandTIpcAttribute.cs b/src/Ryujinx.HLE/HOS/Services/CommandTIpcAttribute.cs index 0d29f92ca..b9c603546 100644 --- a/src/Ryujinx.HLE/HOS/Services/CommandTIpcAttribute.cs +++ b/src/Ryujinx.HLE/HOS/Services/CommandTIpcAttribute.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services { diff --git a/src/Ryujinx.HLE/HOS/Services/DisposableIpcService.cs b/src/Ryujinx.HLE/HOS/Services/DisposableIpcService.cs index 2d0802a7c..b06158a86 100644 --- a/src/Ryujinx.HLE/HOS/Services/DisposableIpcService.cs +++ b/src/Ryujinx.HLE/HOS/Services/DisposableIpcService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading; namespace Ryujinx.HLE.HOS.Services diff --git a/src/Ryujinx.HLE/HOS/Services/DummyService.cs b/src/Ryujinx.HLE/HOS/Services/DummyService.cs index 838a9018e..d890f5742 100644 --- a/src/Ryujinx.HLE/HOS/Services/DummyService.cs +++ b/src/Ryujinx.HLE/HOS/Services/DummyService.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services +namespace Ryujinx.HLE.HOS.Services { class DummyService : IpcService { diff --git a/src/Ryujinx.HLE/HOS/Services/Ectx/IReaderForSystem.cs b/src/Ryujinx.HLE/HOS/Services/Ectx/IReaderForSystem.cs index 09f02fc4b..fc2b35aaa 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ectx/IReaderForSystem.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ectx/IReaderForSystem.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ectx +namespace Ryujinx.HLE.HOS.Services.Ectx { [Service("ectx:r")] // 11.0.0+ class IReaderForSystem : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Ectx/IWriterForApplication.cs b/src/Ryujinx.HLE/HOS/Services/Ectx/IWriterForApplication.cs index a61fca553..cf2cdddc2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ectx/IWriterForApplication.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ectx/IWriterForApplication.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ectx +namespace Ryujinx.HLE.HOS.Services.Ectx { [Service("ectx:aw")] // 11.0.0+ class IWriterForApplication : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Ectx/IWriterForSystem.cs b/src/Ryujinx.HLE/HOS/Services/Ectx/IWriterForSystem.cs index 30c22d1fc..468a5a5b3 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ectx/IWriterForSystem.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ectx/IWriterForSystem.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ectx +namespace Ryujinx.HLE.HOS.Services.Ectx { [Service("ectx:w")] // 11.0.0+ class IWriterForSystem : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Erpt/IContext.cs b/src/Ryujinx.HLE/HOS/Services/Erpt/IContext.cs index eadd3ea8b..bd0880db7 100644 --- a/src/Ryujinx.HLE/HOS/Services/Erpt/IContext.cs +++ b/src/Ryujinx.HLE/HOS/Services/Erpt/IContext.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Erpt +namespace Ryujinx.HLE.HOS.Services.Erpt { [Service("erpt:c")] class IContext : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Erpt/ISession.cs b/src/Ryujinx.HLE/HOS/Services/Erpt/ISession.cs index b43cb30a2..cd9006a23 100644 --- a/src/Ryujinx.HLE/HOS/Services/Erpt/ISession.cs +++ b/src/Ryujinx.HLE/HOS/Services/Erpt/ISession.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Erpt +namespace Ryujinx.HLE.HOS.Services.Erpt { [Service("erpt:r")] class ISession : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Es/IETicketService.cs b/src/Ryujinx.HLE/HOS/Services/Es/IETicketService.cs index ced213f02..486565522 100644 --- a/src/Ryujinx.HLE/HOS/Services/Es/IETicketService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Es/IETicketService.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Es +namespace Ryujinx.HLE.HOS.Services.Es { [Service("es")] class IETicketService : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Eupld/IControl.cs b/src/Ryujinx.HLE/HOS/Services/Eupld/IControl.cs index 4b069c60a..db79d4714 100644 --- a/src/Ryujinx.HLE/HOS/Services/Eupld/IControl.cs +++ b/src/Ryujinx.HLE/HOS/Services/Eupld/IControl.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Eupld +namespace Ryujinx.HLE.HOS.Services.Eupld { [Service("eupld:c")] class IControl : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Eupld/IRequest.cs b/src/Ryujinx.HLE/HOS/Services/Eupld/IRequest.cs index e14e4df4d..7c6f9c814 100644 --- a/src/Ryujinx.HLE/HOS/Services/Eupld/IRequest.cs +++ b/src/Ryujinx.HLE/HOS/Services/Eupld/IRequest.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Eupld +namespace Ryujinx.HLE.HOS.Services.Eupld { [Service("eupld:r")] class IRequest : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Fatal/IPrivateService.cs b/src/Ryujinx.HLE/HOS/Services/Fatal/IPrivateService.cs index 4cb3a2c18..3c48f519a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fatal/IPrivateService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fatal/IPrivateService.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Fatal +namespace Ryujinx.HLE.HOS.Services.Fatal { [Service("fatal:p")] class IPrivateService : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Fatal/IService.cs b/src/Ryujinx.HLE/HOS/Services/Fatal/IService.cs index a62d633e2..21daf8758 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fatal/IService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fatal/IService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Fatal.Types; using System; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Fatal/Types/CpuContext32.cs b/src/Ryujinx.HLE/HOS/Services/Fatal/Types/CpuContext32.cs index 5eb1406a1..8429774e8 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fatal/Types/CpuContext32.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fatal/Types/CpuContext32.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.HLE.HOS.Services.Fatal.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Fatal/Types/CpuContext64.cs b/src/Ryujinx.HLE/HOS/Services/Fatal/Types/CpuContext64.cs index 58fd3c4ac..17b5036d2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fatal/Types/CpuContext64.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fatal/Types/CpuContext64.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.HLE.HOS.Services.Fatal.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Fatal/Types/FatalPolicy.cs b/src/Ryujinx.HLE/HOS/Services/Fatal/Types/FatalPolicy.cs index f536d17d3..b0da0e375 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fatal/Types/FatalPolicy.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fatal/Types/FatalPolicy.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Fatal.Types +namespace Ryujinx.HLE.HOS.Services.Fatal.Types { enum FatalPolicy { diff --git a/src/Ryujinx.HLE/HOS/Services/Friend/IServiceCreator.cs b/src/Ryujinx.HLE/HOS/Services/Friend/IServiceCreator.cs deleted file mode 100644 index 3f15f3fc6..000000000 --- a/src/Ryujinx.HLE/HOS/Services/Friend/IServiceCreator.cs +++ /dev/null @@ -1,55 +0,0 @@ -using Ryujinx.Common; -using Ryujinx.HLE.HOS.Services.Account.Acc; -using Ryujinx.HLE.HOS.Services.Friend.ServiceCreator; - -namespace Ryujinx.HLE.HOS.Services.Friend -{ - [Service("friend:a", FriendServicePermissionLevel.Administrator)] - [Service("friend:m", FriendServicePermissionLevel.Manager)] - [Service("friend:s", FriendServicePermissionLevel.System)] - [Service("friend:u", FriendServicePermissionLevel.User)] - [Service("friend:v", FriendServicePermissionLevel.Viewer)] - class IServiceCreator : IpcService - { - private readonly FriendServicePermissionLevel _permissionLevel; - - public IServiceCreator(ServiceCtx context, FriendServicePermissionLevel permissionLevel) - { - _permissionLevel = permissionLevel; - } - - [CommandCmif(0)] - // CreateFriendService() -> object - public ResultCode CreateFriendService(ServiceCtx context) - { - MakeObject(context, new IFriendService(_permissionLevel)); - - return ResultCode.Success; - } - - [CommandCmif(1)] // 2.0.0+ - // CreateNotificationService(nn::account::Uid userId) -> object - public ResultCode CreateNotificationService(ServiceCtx context) - { - UserId userId = context.RequestData.ReadStruct(); - - if (userId.IsNull) - { - return ResultCode.InvalidArgument; - } - - MakeObject(context, new INotificationService(context, userId, _permissionLevel)); - - return ResultCode.Success; - } - - [CommandCmif(2)] // 4.0.0+ - // CreateDaemonSuspendSessionService() -> object - public ResultCode CreateDaemonSuspendSessionService(ServiceCtx context) - { - MakeObject(context, new IDaemonSuspendSessionService(_permissionLevel)); - - return ResultCode.Success; - } - } -} diff --git a/src/Ryujinx.HLE/HOS/Services/Friend/ResultCode.cs b/src/Ryujinx.HLE/HOS/Services/Friend/ResultCode.cs deleted file mode 100644 index 82462b4ed..000000000 --- a/src/Ryujinx.HLE/HOS/Services/Friend/ResultCode.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Friend -{ - enum ResultCode - { - ModuleId = 121, - ErrorCodeShift = 9, - - Success = 0, - - InvalidArgument = (2 << ErrorCodeShift) | ModuleId, - InternetRequestDenied = (6 << ErrorCodeShift) | ModuleId, - NotificationQueueEmpty = (15 << ErrorCodeShift) | ModuleId, - } -} diff --git a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/FriendService/Types/Friend.cs b/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/FriendService/Types/Friend.cs deleted file mode 100644 index e727cafbb..000000000 --- a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/FriendService/Types/Friend.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Ryujinx.HLE.HOS.Services.Account.Acc; -using System.Runtime.InteropServices; - -namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator.FriendService -{ - [StructLayout(LayoutKind.Sequential, Pack = 0x8, Size = 0x200, CharSet = CharSet.Ansi)] - struct Friend - { - public UserId UserId; - public long NetworkUserId; - - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x21)] - public string Nickname; - - public UserPresence presence; - - [MarshalAs(UnmanagedType.I1)] - public bool IsFavourite; - - [MarshalAs(UnmanagedType.I1)] - public bool IsNew; - - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x6)] - readonly char[] Unknown; - - [MarshalAs(UnmanagedType.I1)] - public bool IsValid; - } -} diff --git a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/FriendService/Types/FriendFilter.cs b/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/FriendService/Types/FriendFilter.cs deleted file mode 100644 index 6f10a7579..000000000 --- a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/FriendService/Types/FriendFilter.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Runtime.InteropServices; - -namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator.FriendService -{ - [StructLayout(LayoutKind.Sequential)] - struct FriendFilter - { - public PresenceStatusFilter PresenceStatus; - - [MarshalAs(UnmanagedType.I1)] - public bool IsFavoriteOnly; - - [MarshalAs(UnmanagedType.I1)] - public bool IsSameAppPresenceOnly; - - [MarshalAs(UnmanagedType.I1)] - public bool IsSameAppPlayedOnly; - - [MarshalAs(UnmanagedType.I1)] - public bool IsArbitraryAppPlayedOnly; - - public long PresenceGroupId; - } -} diff --git a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/FriendService/Types/UserPresence.cs b/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/FriendService/Types/UserPresence.cs deleted file mode 100644 index 9769e1609..000000000 --- a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/FriendService/Types/UserPresence.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Ryujinx.Common.Memory; -using Ryujinx.HLE.HOS.Services.Account.Acc; -using System; -using System.Runtime.InteropServices; - -namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator.FriendService -{ - [StructLayout(LayoutKind.Sequential, Pack = 0x8)] - struct UserPresence - { - public UserId UserId; - public long LastTimeOnlineTimestamp; - public PresenceStatus Status; - - [MarshalAs(UnmanagedType.I1)] - public bool SamePresenceGroupApplication; - - public Array3 Unknown; - private AppKeyValueStorageHolder _appKeyValueStorage; - - public Span AppKeyValueStorage => MemoryMarshal.Cast(MemoryMarshal.CreateSpan(ref _appKeyValueStorage, AppKeyValueStorageHolder.Size)); - - [StructLayout(LayoutKind.Sequential, Pack = 0x1, Size = Size)] - private struct AppKeyValueStorageHolder - { - public const int Size = 0xC0; - } - - public readonly override string ToString() - { - return $"UserPresence {{ UserId: {UserId}, LastTimeOnlineTimestamp: {LastTimeOnlineTimestamp}, Status: {Status} }}"; - } - } -} diff --git a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/IDaemonSuspendSessionService.cs b/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/IDaemonSuspendSessionService.cs deleted file mode 100644 index 3b1601abb..000000000 --- a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/IDaemonSuspendSessionService.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator -{ - class IDaemonSuspendSessionService : IpcService - { -#pragma warning disable IDE0052 // Remove unread private member - private readonly FriendServicePermissionLevel _permissionLevel; -#pragma warning restore IDE0052 - - public IDaemonSuspendSessionService(FriendServicePermissionLevel permissionLevel) - { - _permissionLevel = permissionLevel; - } - } -} diff --git a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/IFriendService.cs b/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/IFriendService.cs deleted file mode 100644 index 54d23e88c..000000000 --- a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/IFriendService.cs +++ /dev/null @@ -1,374 +0,0 @@ -using LibHac.Ns; -using Ryujinx.Common; -using Ryujinx.Common.Logging; -using Ryujinx.Common.Memory; -using Ryujinx.Common.Utilities; -using Ryujinx.HLE.HOS.Ipc; -using Ryujinx.HLE.HOS.Kernel.Threading; -using Ryujinx.HLE.HOS.Services.Account.Acc; -using Ryujinx.HLE.HOS.Services.Friend.ServiceCreator.FriendService; -using Ryujinx.Horizon.Common; -using System; -using System.Runtime.InteropServices; - -namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator -{ - class IFriendService : IpcService - { -#pragma warning disable IDE0052 // Remove unread private member - private readonly FriendServicePermissionLevel _permissionLevel; -#pragma warning restore IDE0052 - private KEvent _completionEvent; - - public IFriendService(FriendServicePermissionLevel permissionLevel) - { - _permissionLevel = permissionLevel; - } - - [CommandCmif(0)] - // GetCompletionEvent() -> handle - public ResultCode GetCompletionEvent(ServiceCtx context) - { - _completionEvent ??= new KEvent(context.Device.System.KernelContext); - - if (context.Process.HandleTable.GenerateHandle(_completionEvent.ReadableEvent, out int completionEventHandle) != Result.Success) - { - throw new InvalidOperationException("Out of handles!"); - } - - _completionEvent.WritableEvent.Signal(); - - context.Response.HandleDesc = IpcHandleDesc.MakeCopy(completionEventHandle); - - return ResultCode.Success; - } - - [CommandCmif(1)] - // nn::friends::Cancel() - public ResultCode Cancel(ServiceCtx context) - { - // TODO: Original service sets an internal field to 1 here. Determine usage. - Logger.Stub?.PrintStub(LogClass.ServiceFriend); - - return ResultCode.Success; - } - - [CommandCmif(10100)] - // nn::friends::GetFriendListIds(int offset, nn::account::Uid userId, nn::friends::detail::ipc::SizedFriendFilter friendFilter, ulong pidPlaceHolder, pid) - // -> int outCount, array - public ResultCode GetFriendListIds(ServiceCtx context) - { - int offset = context.RequestData.ReadInt32(); - - // Padding - context.RequestData.ReadInt32(); - - UserId userId = context.RequestData.ReadStruct(); - FriendFilter filter = context.RequestData.ReadStruct(); - - // Pid placeholder - context.RequestData.ReadInt64(); - - if (userId.IsNull) - { - return ResultCode.InvalidArgument; - } - - // There are no friends online, so we return 0 because the nn::account::NetworkServiceAccountId array is empty. - context.ResponseData.Write(0); - - Logger.Stub?.PrintStub(LogClass.ServiceFriend, new - { - UserId = userId.ToString(), - offset, - filter.PresenceStatus, - filter.IsFavoriteOnly, - filter.IsSameAppPresenceOnly, - filter.IsSameAppPlayedOnly, - filter.IsArbitraryAppPlayedOnly, - filter.PresenceGroupId, - }); - - return ResultCode.Success; - } - - [CommandCmif(10101)] - // nn::friends::GetFriendList(int offset, nn::account::Uid userId, nn::friends::detail::ipc::SizedFriendFilter friendFilter, ulong pidPlaceHolder, pid) - // -> int outCount, array - public ResultCode GetFriendList(ServiceCtx context) - { - int offset = context.RequestData.ReadInt32(); - - // Padding - context.RequestData.ReadInt32(); - - UserId userId = context.RequestData.ReadStruct(); - FriendFilter filter = context.RequestData.ReadStruct(); - - // Pid placeholder - context.RequestData.ReadInt64(); - - if (userId.IsNull) - { - return ResultCode.InvalidArgument; - } - - // There are no friends online, so we return 0 because the nn::account::NetworkServiceAccountId array is empty. - context.ResponseData.Write(0); - - Logger.Stub?.PrintStub(LogClass.ServiceFriend, new - { - UserId = userId.ToString(), - offset, - filter.PresenceStatus, - filter.IsFavoriteOnly, - filter.IsSameAppPresenceOnly, - filter.IsSameAppPlayedOnly, - filter.IsArbitraryAppPlayedOnly, - filter.PresenceGroupId, - }); - - return ResultCode.Success; - } - - [CommandCmif(10120)] // 10.0.0+ - // nn::friends::IsFriendListCacheAvailable(nn::account::Uid userId) -> bool - public ResultCode IsFriendListCacheAvailable(ServiceCtx context) - { - UserId userId = context.RequestData.ReadStruct(); - - if (userId.IsNull) - { - return ResultCode.InvalidArgument; - } - - // TODO: Service mount the friends:/ system savedata and try to load friend.cache file, returns true if exists, false otherwise. - // NOTE: If no cache is available, guest then calls nn::friends::EnsureFriendListAvailable, we can avoid that by faking the cache check. - context.ResponseData.Write(true); - - // TODO: Since we don't support friend features, it's fine to stub it for now. - Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { UserId = userId.ToString() }); - - return ResultCode.Success; - } - - [CommandCmif(10121)] // 10.0.0+ - // nn::friends::EnsureFriendListAvailable(nn::account::Uid userId) - public ResultCode EnsureFriendListAvailable(ServiceCtx context) - { - UserId userId = context.RequestData.ReadStruct(); - - if (userId.IsNull) - { - return ResultCode.InvalidArgument; - } - - // TODO: Service mount the friends:/ system savedata and create a friend.cache file for the given user id. - // Since we don't support friend features, it's fine to stub it for now. - Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { UserId = userId.ToString() }); - - return ResultCode.Success; - } - - [CommandCmif(10400)] - // nn::friends::GetBlockedUserListIds(int offset, nn::account::Uid userId) -> (u32, buffer) - public ResultCode GetBlockedUserListIds(ServiceCtx context) - { - int offset = context.RequestData.ReadInt32(); - - // Padding - context.RequestData.ReadInt32(); - - UserId userId = context.RequestData.ReadStruct(); - - // There are no friends blocked, so we return 0 because the nn::account::NetworkServiceAccountId array is empty. - context.ResponseData.Write(0); - - Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { offset, UserId = userId.ToString() }); - - return ResultCode.Success; - } - - [CommandCmif(10420)] - // nn::friends::CheckBlockedUserListAvailability(nn::account::Uid userId) -> bool - public ResultCode CheckBlockedUserListAvailability(ServiceCtx context) - { - UserId userId = context.RequestData.ReadStruct(); - - // Yes, it is available. - context.ResponseData.Write(true); - - Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { UserId = userId.ToString() }); - - return ResultCode.Success; - } - - [CommandCmif(10600)] - // nn::friends::DeclareOpenOnlinePlaySession(nn::account::Uid userId) - public ResultCode DeclareOpenOnlinePlaySession(ServiceCtx context) - { - UserId userId = context.RequestData.ReadStruct(); - - if (userId.IsNull) - { - return ResultCode.InvalidArgument; - } - - context.Device.System.AccountManager.OpenUserOnlinePlay(userId); - - Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { UserId = userId.ToString() }); - - return ResultCode.Success; - } - - [CommandCmif(10601)] - // nn::friends::DeclareCloseOnlinePlaySession(nn::account::Uid userId) - public ResultCode DeclareCloseOnlinePlaySession(ServiceCtx context) - { - UserId userId = context.RequestData.ReadStruct(); - - if (userId.IsNull) - { - return ResultCode.InvalidArgument; - } - - context.Device.System.AccountManager.CloseUserOnlinePlay(userId); - - Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { UserId = userId.ToString() }); - - return ResultCode.Success; - } - - [CommandCmif(10610)] - // nn::friends::UpdateUserPresence(nn::account::Uid, u64, pid, buffer) - public ResultCode UpdateUserPresence(ServiceCtx context) - { - UserId uuid = context.RequestData.ReadStruct(); - - // Pid placeholder - context.RequestData.ReadInt64(); - - ulong position = context.Request.PtrBuff[0].Position; - ulong size = context.Request.PtrBuff[0].Size; - - ReadOnlySpan userPresenceInputArray = MemoryMarshal.Cast(context.Memory.GetSpan(position, (int)size)); - - if (uuid.IsNull) - { - return ResultCode.InvalidArgument; - } - - Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { UserId = uuid.ToString(), userPresenceInputArray = userPresenceInputArray.ToArray() }); - - return ResultCode.Success; - } - - [CommandCmif(10700)] - // nn::friends::GetPlayHistoryRegistrationKey(b8 unknown, nn::account::Uid) -> buffer - public ResultCode GetPlayHistoryRegistrationKey(ServiceCtx context) - { - bool unknownBool = context.RequestData.ReadBoolean(); - UserId userId = context.RequestData.ReadStruct(); - - context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize(0x40UL); - - ulong bufferPosition = context.Request.RecvListBuff[0].Position; - - if (userId.IsNull) - { - return ResultCode.InvalidArgument; - } - - // NOTE: Calls nn::friends::detail::service::core::PlayHistoryManager::GetInstance and stores the instance. - - byte[] randomBytes = new byte[8]; - - Random.Shared.NextBytes(randomBytes); - - // NOTE: Calls nn::friends::detail::service::core::UuidManager::GetInstance and stores the instance. - // Then call nn::friends::detail::service::core::AccountStorageManager::GetInstance and store the instance. - // Then it checks if an Uuid is already stored for the UserId, if not it generates a random Uuid. - // And store it in the savedata 8000000000000080 in the friends:/uid.bin file. - - Array16 randomGuid = new(); - - Guid.NewGuid().ToByteArray().AsSpan().CopyTo(randomGuid.AsSpan()); - - PlayHistoryRegistrationKey playHistoryRegistrationKey = new() - { - Type = 0x101, - KeyIndex = (byte)(randomBytes[0] & 7), - UserIdBool = 0, // TODO: Find it. - UnknownBool = (byte)(unknownBool ? 1 : 0), // TODO: Find it. - Reserved = new Array11(), - Uuid = randomGuid, - }; - - ReadOnlySpan playHistoryRegistrationKeyBuffer = SpanHelpers.AsByteSpan(ref playHistoryRegistrationKey); - - /* - - NOTE: The service uses the KeyIndex to get a random key from a keys buffer (since the key index is stored in the returned buffer). - We currently don't support play history and online services so we can use a blank key for now. - Code for reference: - - byte[] hmacKey = new byte[0x20]; - - HMACSHA256 hmacSha256 = new HMACSHA256(hmacKey); - byte[] hmacHash = hmacSha256.ComputeHash(playHistoryRegistrationKeyBuffer); - - */ - - context.Memory.Write(bufferPosition, playHistoryRegistrationKeyBuffer); - context.Memory.Write(bufferPosition + 0x20, new byte[0x20]); // HmacHash - - return ResultCode.Success; - } - - [CommandCmif(10702)] - // nn::friends::AddPlayHistory(nn::account::Uid, u64, pid, buffer, buffer, buffer) - public ResultCode AddPlayHistory(ServiceCtx context) - { - UserId userId = context.RequestData.ReadStruct(); - - // Pid placeholder - context.RequestData.ReadInt64(); -#pragma warning disable IDE0059 // Remove unnecessary value assignment - ulong pid = context.Request.HandleDesc.PId; - - ulong playHistoryRegistrationKeyPosition = context.Request.PtrBuff[0].Position; - ulong playHistoryRegistrationKeySize = context.Request.PtrBuff[0].Size; - - ulong inAppScreenName1Position = context.Request.PtrBuff[1].Position; -#pragma warning restore IDE0059 - ulong inAppScreenName1Size = context.Request.PtrBuff[1].Size; - -#pragma warning disable IDE0059 // Remove unnecessary value assignment - ulong inAppScreenName2Position = context.Request.PtrBuff[2].Position; -#pragma warning restore IDE0059 - ulong inAppScreenName2Size = context.Request.PtrBuff[2].Size; - - if (userId.IsNull || inAppScreenName1Size > 0x48 || inAppScreenName2Size > 0x48) - { - return ResultCode.InvalidArgument; - } - - // TODO: Call nn::arp::GetApplicationControlProperty here when implemented. -#pragma warning disable IDE0059 // Remove unnecessary value assignment - ApplicationControlProperty controlProperty = context.Device.Processes.ActiveApplication.ApplicationControlProperties; -#pragma warning restore IDE0059 - - /* - - NOTE: The service calls nn::friends::detail::service::core::PlayHistoryManager to store informations using the registration key computed in GetPlayHistoryRegistrationKey. - Then calls nn::friends::detail::service::core::FriendListManager to update informations on the friend list. - We currently don't support play history and online services so it's fine to do nothing. - - */ - - Logger.Stub?.PrintStub(LogClass.ServiceFriend); - - return ResultCode.Success; - } - } -} diff --git a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/INotificationService.cs b/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/INotificationService.cs deleted file mode 100644 index 8fc7a4609..000000000 --- a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/INotificationService.cs +++ /dev/null @@ -1,178 +0,0 @@ -using Ryujinx.Common; -using Ryujinx.HLE.HOS.Ipc; -using Ryujinx.HLE.HOS.Kernel.Threading; -using Ryujinx.HLE.HOS.Services.Account.Acc; -using Ryujinx.HLE.HOS.Services.Friend.ServiceCreator.NotificationService; -using Ryujinx.Horizon.Common; -using System; -using System.Collections.Generic; - -namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator -{ - class INotificationService : DisposableIpcService - { - private readonly UserId _userId; - private readonly FriendServicePermissionLevel _permissionLevel; - - private readonly object _lock = new(); - - private readonly KEvent _notificationEvent; - private int _notificationEventHandle = 0; - - private readonly LinkedList _notifications; - - private bool _hasNewFriendRequest; - private bool _hasFriendListUpdate; - - public INotificationService(ServiceCtx context, UserId userId, FriendServicePermissionLevel permissionLevel) - { - _userId = userId; - _permissionLevel = permissionLevel; - _notifications = new LinkedList(); - _notificationEvent = new KEvent(context.Device.System.KernelContext); - - _hasNewFriendRequest = false; - _hasFriendListUpdate = false; - - NotificationEventHandler.Instance.RegisterNotificationService(this); - } - - [CommandCmif(0)] //2.0.0+ - // nn::friends::detail::ipc::INotificationService::GetEvent() -> handle - public ResultCode GetEvent(ServiceCtx context) - { - if (_notificationEventHandle == 0) - { - if (context.Process.HandleTable.GenerateHandle(_notificationEvent.ReadableEvent, out _notificationEventHandle) != Result.Success) - { - throw new InvalidOperationException("Out of handles!"); - } - } - - context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_notificationEventHandle); - - return ResultCode.Success; - } - - [CommandCmif(1)] //2.0.0+ - // nn::friends::detail::ipc::INotificationService::Clear() - public ResultCode Clear(ServiceCtx context) - { - lock (_lock) - { - _hasNewFriendRequest = false; - _hasFriendListUpdate = false; - - _notifications.Clear(); - } - - return ResultCode.Success; - } - - [CommandCmif(2)] // 2.0.0+ - // nn::friends::detail::ipc::INotificationService::Pop() -> nn::friends::detail::ipc::SizedNotificationInfo - public ResultCode Pop(ServiceCtx context) - { - lock (_lock) - { - if (_notifications.Count >= 1) - { - NotificationInfo notificationInfo = _notifications.First.Value; - _notifications.RemoveFirst(); - - if (notificationInfo.Type == NotificationEventType.FriendListUpdate) - { - _hasFriendListUpdate = false; - } - else if (notificationInfo.Type == NotificationEventType.NewFriendRequest) - { - _hasNewFriendRequest = false; - } - - context.ResponseData.WriteStruct(notificationInfo); - - return ResultCode.Success; - } - } - - return ResultCode.NotificationQueueEmpty; - } - - public void SignalFriendListUpdate(UserId targetId) - { - lock (_lock) - { - if (_userId == targetId) - { - if (!_hasFriendListUpdate) - { - NotificationInfo friendListNotification = new(); - - if (_notifications.Count != 0) - { - friendListNotification = _notifications.First.Value; - _notifications.RemoveFirst(); - } - - friendListNotification.Type = NotificationEventType.FriendListUpdate; - _hasFriendListUpdate = true; - - if (_hasNewFriendRequest) - { - NotificationInfo newFriendRequestNotification = new(); - - if (_notifications.Count != 0) - { - newFriendRequestNotification = _notifications.First.Value; - _notifications.RemoveFirst(); - } - - newFriendRequestNotification.Type = NotificationEventType.NewFriendRequest; - _notifications.AddFirst(newFriendRequestNotification); - } - - // We defer this to make sure we are on top of the queue. - _notifications.AddFirst(friendListNotification); - } - - _notificationEvent.ReadableEvent.Signal(); - } - } - } - - public void SignalNewFriendRequest(UserId targetId) - { - lock (_lock) - { - if ((_permissionLevel & FriendServicePermissionLevel.ViewerMask) != 0 && _userId == targetId) - { - if (!_hasNewFriendRequest) - { - if (_notifications.Count == 100) - { - SignalFriendListUpdate(targetId); - } - - NotificationInfo newFriendRequestNotification = new() - { - Type = NotificationEventType.NewFriendRequest, - }; - - _notifications.AddLast(newFriendRequestNotification); - _hasNewFriendRequest = true; - } - - _notificationEvent.ReadableEvent.Signal(); - } - } - } - - protected override void Dispose(bool isDisposing) - { - if (isDisposing) - { - NotificationEventHandler.Instance.UnregisterNotificationService(this); - } - } - } -} diff --git a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/NotificationService/NotificationEventHandler.cs b/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/NotificationService/NotificationEventHandler.cs deleted file mode 100644 index f0970d166..000000000 --- a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/NotificationService/NotificationEventHandler.cs +++ /dev/null @@ -1,74 +0,0 @@ -using Ryujinx.HLE.HOS.Services.Account.Acc; - -namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator.NotificationService -{ - public sealed class NotificationEventHandler - { - private static NotificationEventHandler _instance; - private static readonly object _instanceLock = new(); - - private readonly INotificationService[] _registry; - - public static NotificationEventHandler Instance - { - get - { - lock (_instanceLock) - { - _instance ??= new NotificationEventHandler(); - - return _instance; - } - } - } - - NotificationEventHandler() - { - _registry = new INotificationService[0x20]; - } - - internal void RegisterNotificationService(INotificationService service) - { - // NOTE: in case there isn't space anymore in the registry array, Nintendo doesn't return any errors. - for (int i = 0; i < _registry.Length; i++) - { - if (_registry[i] == null) - { - _registry[i] = service; - break; - } - } - } - - internal void UnregisterNotificationService(INotificationService service) - { - // NOTE: in case there isn't the entry in the registry array, Nintendo doesn't return any errors. - for (int i = 0; i < _registry.Length; i++) - { - if (_registry[i] == service) - { - _registry[i] = null; - break; - } - } - } - - // TODO: Use this when we will have enough things to go online. - public void SignalFriendListUpdate(UserId targetId) - { - for (int i = 0; i < _registry.Length; i++) - { - _registry[i]?.SignalFriendListUpdate(targetId); - } - } - - // TODO: Use this when we will have enough things to go online. - public void SignalNewFriendRequest(UserId targetId) - { - for (int i = 0; i < _registry.Length; i++) - { - _registry[i]?.SignalNewFriendRequest(targetId); - } - } - } -} diff --git a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/NotificationService/Types/NotificationInfo.cs b/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/NotificationService/Types/NotificationInfo.cs deleted file mode 100644 index 1073c47d3..000000000 --- a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/NotificationService/Types/NotificationInfo.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Ryujinx.Common.Memory; -using System.Runtime.InteropServices; - -namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator.NotificationService -{ - [StructLayout(LayoutKind.Sequential, Size = 0x10)] - struct NotificationInfo - { - public NotificationEventType Type; - private Array4 _padding; - public long NetworkUserIdPlaceholder; - } -} diff --git a/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/FileSystemProxyHelper.cs b/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/FileSystemProxyHelper.cs index 1ef52a00d..20ffb996d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/FileSystemProxyHelper.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/FileSystemProxyHelper.cs @@ -1,4 +1,4 @@ -using LibHac; +using LibHac; using LibHac.Common; using LibHac.Common.Keys; using LibHac.Fs; diff --git a/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFileSystem.cs b/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFileSystem.cs index 66020d57b..e19d17912 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFileSystem.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFileSystem.cs @@ -2,6 +2,7 @@ using LibHac; using LibHac.Common; using LibHac.Fs; using LibHac.Fs.Fsa; +using Ryujinx.Common.Logging; using Path = LibHac.FsSrv.Sf.Path; namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy @@ -149,7 +150,13 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy // Commit() public ResultCode Commit(ServiceCtx context) { - return (ResultCode)_fileSystem.Get.Commit().Value; + ResultCode resultCode = (ResultCode)_fileSystem.Get.Commit().Value; + if (resultCode == ResultCode.PathAlreadyInUse) + { + Logger.Warning?.Print(LogClass.ServiceFs, "The file system is already in use by another process."); + } + + return resultCode; } [CommandCmif(11)] diff --git a/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/LazyFile.cs b/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/LazyFile.cs new file mode 100644 index 000000000..a179e8e38 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/LazyFile.cs @@ -0,0 +1,65 @@ +using LibHac; +using LibHac.Common; +using LibHac.Fs; +using System; +using System.IO; + +namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy +{ + class LazyFile : LibHac.Fs.Fsa.IFile + { + private readonly LibHac.Fs.Fsa.IFileSystem _fs; + private readonly string _filePath; + private readonly UniqueRef _fileReference = new(); + private readonly FileInfo _fileInfo; + + public LazyFile(string filePath, string prefix, LibHac.Fs.Fsa.IFileSystem fs) + { + _fs = fs; + _filePath = filePath; + _fileInfo = new FileInfo(prefix + "/" + filePath); + } + + private void PrepareFile() + { + if (_fileReference.Get == null) + { + _fs.OpenFile(ref _fileReference.Ref, _filePath.ToU8Span(), OpenMode.Read).ThrowIfFailure(); + } + } + + protected override Result DoRead(out long bytesRead, long offset, Span destination, in ReadOption option) + { + PrepareFile(); + + return _fileReference.Get!.Read(out bytesRead, offset, destination); + } + + protected override Result DoWrite(long offset, ReadOnlySpan source, in WriteOption option) + { + throw new NotSupportedException(); + } + + protected override Result DoFlush() + { + throw new NotSupportedException(); + } + + protected override Result DoSetSize(long size) + { + throw new NotSupportedException(); + } + + protected override Result DoGetSize(out long size) + { + size = _fileInfo.Length; + + return Result.Success; + } + + protected override Result DoOperateRange(Span outBuffer, OperationId operationId, long offset, long size, ReadOnlySpan inBuffer) + { + throw new NotSupportedException(); + } + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs b/src/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs index 2a40aea4f..49453e83a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs @@ -1,4 +1,4 @@ -using LibHac; +using LibHac; using LibHac.Common; using GameCardHandle = System.UInt32; diff --git a/src/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxyForLoader.cs b/src/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxyForLoader.cs index c3e228758..82c593848 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxyForLoader.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxyForLoader.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Fs +namespace Ryujinx.HLE.HOS.Services.Fs { [Service("fsp-ldr")] class IFileSystemProxyForLoader : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Fs/IMultiCommitManager.cs b/src/Ryujinx.HLE/HOS/Services/Fs/IMultiCommitManager.cs index aa04a7e64..134e2ed8c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fs/IMultiCommitManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fs/IMultiCommitManager.cs @@ -1,4 +1,4 @@ -using LibHac; +using LibHac; using LibHac.Common; using Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy; diff --git a/src/Ryujinx.HLE/HOS/Services/Fs/IProgramRegistry.cs b/src/Ryujinx.HLE/HOS/Services/Fs/IProgramRegistry.cs index 4554a053a..9383a1d37 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fs/IProgramRegistry.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fs/IProgramRegistry.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Fs +namespace Ryujinx.HLE.HOS.Services.Fs { [Service("fsp-pr")] class IProgramRegistry : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Fs/ISaveDataInfoReader.cs b/src/Ryujinx.HLE/HOS/Services/Fs/ISaveDataInfoReader.cs index 022d7b819..7ed6dadc2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fs/ISaveDataInfoReader.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fs/ISaveDataInfoReader.cs @@ -1,4 +1,4 @@ -using LibHac; +using LibHac; using LibHac.Common; using LibHac.Sf; diff --git a/src/Ryujinx.HLE/HOS/Services/Fs/Types/FileSystemType.cs b/src/Ryujinx.HLE/HOS/Services/Fs/Types/FileSystemType.cs index 369df9b68..17756e124 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fs/Types/FileSystemType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fs/Types/FileSystemType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Fs +namespace Ryujinx.HLE.HOS.Services.Fs { enum FileSystemType { diff --git a/src/Ryujinx.HLE/HOS/Services/Grc/IGrcService.cs b/src/Ryujinx.HLE/HOS/Services/Grc/IGrcService.cs index 131ba541c..da01f64be 100644 --- a/src/Ryujinx.HLE/HOS/Services/Grc/IGrcService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Grc/IGrcService.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Grc +namespace Ryujinx.HLE.HOS.Services.Grc { [Service("grc:c")] // 4.0.0+ class IGrcService : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Grc/IRemoteVideoTransfer.cs b/src/Ryujinx.HLE/HOS/Services/Grc/IRemoteVideoTransfer.cs index 1d200ac3c..08e7365c1 100644 --- a/src/Ryujinx.HLE/HOS/Services/Grc/IRemoteVideoTransfer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Grc/IRemoteVideoTransfer.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Grc +namespace Ryujinx.HLE.HOS.Services.Grc { [Service("grc:d")] // 6.0.0+ class IRemoteVideoTransfer : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/HidUtils.cs b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/HidUtils.cs index d76704b3e..8e2e854fb 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/HidUtils.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/HidUtils.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Hid.HidServer { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/NpadHandheldActivationMode.cs b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/NpadHandheldActivationMode.cs index 02e3d803f..ba56e93cb 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/NpadHandheldActivationMode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/NpadHandheldActivationMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid +namespace Ryujinx.HLE.HOS.Services.Hid { public enum NpadHandheldActivationMode { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/NpadJoyDeviceType.cs b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/NpadJoyDeviceType.cs index f52e18f28..ac0bb3575 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/NpadJoyDeviceType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/NpadJoyDeviceType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid +namespace Ryujinx.HLE.HOS.Services.Hid { public enum NpadJoyDeviceType { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/AccelerometerParameters.cs b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/AccelerometerParameters.cs index 8e4d80e24..baabffa05 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/AccelerometerParameters.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/AccelerometerParameters.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid +namespace Ryujinx.HLE.HOS.Services.Hid { public struct AccelerometerParameters { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/GyroscopeZeroDriftMode.cs b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/GyroscopeZeroDriftMode.cs index 659afa0df..d73c60251 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/GyroscopeZeroDriftMode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/GyroscopeZeroDriftMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid +namespace Ryujinx.HLE.HOS.Services.Hid { public enum GyroscopeZeroDriftMode { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/SensorFusionParameters.cs b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/SensorFusionParameters.cs index 37cef783a..c74214565 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/SensorFusionParameters.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/SensorFusionParameters.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid +namespace Ryujinx.HLE.HOS.Services.Hid { public struct SensorFusionParameters { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDeviceHandle.cs b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDeviceHandle.cs index d59afe513..02f4b6840 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDeviceHandle.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDeviceHandle.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid +namespace Ryujinx.HLE.HOS.Services.Hid { public struct VibrationDeviceHandle { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDevicePosition.cs b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDevicePosition.cs index 19d52f9fd..90f4abcc3 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDevicePosition.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDevicePosition.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid +namespace Ryujinx.HLE.HOS.Services.Hid { public enum VibrationDevicePosition { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDeviceType.cs b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDeviceType.cs index 4849c3426..db586bb34 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDeviceType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDeviceType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid +namespace Ryujinx.HLE.HOS.Services.Hid { public enum VibrationDeviceType { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDeviceValue.cs b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDeviceValue.cs index 8ac06cb79..feed8764d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDeviceValue.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDeviceValue.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid +namespace Ryujinx.HLE.HOS.Services.Hid { public struct VibrationDeviceValue { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationValue.cs b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationValue.cs index c6143a013..490d1e6ab 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationValue.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationValue.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Hid { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/IHidDebugServer.cs b/src/Ryujinx.HLE/HOS/Services/Hid/IHidDebugServer.cs index 0d1867db5..2444c4436 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/IHidDebugServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/IHidDebugServer.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid +namespace Ryujinx.HLE.HOS.Services.Hid { [Service("hid:dbg")] class IHidDebugServer : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/IHidSystemServer.cs b/src/Ryujinx.HLE/HOS/Services/Hid/IHidSystemServer.cs index 685f6841d..0b4eba948 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/IHidSystemServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/IHidSystemServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Hid.HidServer; using Ryujinx.HLE.HOS.Services.Hid.Types; diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/IHidbusServer.cs b/src/Ryujinx.HLE/HOS/Services/Hid/IHidbusServer.cs index 7c624dfc3..d6531cc18 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/IHidbusServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/IHidbusServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Common.Logging; namespace Ryujinx.HLE.HOS.Services.Hid diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/ISystemServer.cs b/src/Ryujinx.HLE/HOS/Services/Hid/ISystemServer.cs index daff6fda9..c00b083a3 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/ISystemServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/ISystemServer.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid +namespace Ryujinx.HLE.HOS.Services.Hid { [Service("xcd:sys")] class ISystemServer : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Irs/IIrSensorSystemServer.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Irs/IIrSensorSystemServer.cs index ad78d4f1e..5046268cb 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Irs/IIrSensorSystemServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Irs/IIrSensorSystemServer.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid.Irs +namespace Ryujinx.HLE.HOS.Services.Hid.Irs { [Service("irs:sys")] class IIrSensorSystemServer : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Irs/ResultCode.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Irs/ResultCode.cs index 322f9349b..8cee32cdf 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Irs/ResultCode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Irs/ResultCode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid.Irs +namespace Ryujinx.HLE.HOS.Services.Hid.Irs { public enum ResultCode { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/ImageTransferProcessorState.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/ImageTransferProcessorState.cs index 7f28667ce..76a07f797 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/ImageTransferProcessorState.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/ImageTransferProcessorState.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Hid.Irs.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/IrCameraHandle.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/IrCameraHandle.cs index 282f92796..a15e445c7 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/IrCameraHandle.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/IrCameraHandle.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Hid.Irs.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/PackedClusteringProcessorConfig.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/PackedClusteringProcessorConfig.cs index a65a1ba61..d12513fab 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/PackedClusteringProcessorConfig.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/PackedClusteringProcessorConfig.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Hid.Irs.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/PackedImageTransferProcessorConfig.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/PackedImageTransferProcessorConfig.cs index c97de27a8..0bc709f20 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/PackedImageTransferProcessorConfig.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/PackedImageTransferProcessorConfig.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Hid.Irs.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/PackedMomentProcessorConfig.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/PackedMomentProcessorConfig.cs index bbee28156..f1905ee3a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/PackedMomentProcessorConfig.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/PackedMomentProcessorConfig.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Hid.Irs.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/PackedTeraPluginProcessorConfig.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/PackedTeraPluginProcessorConfig.cs index 4fada04af..1cc2533a2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/PackedTeraPluginProcessorConfig.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Irs/Types/PackedTeraPluginProcessorConfig.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Hid.Irs.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/ResultCode.cs b/src/Ryujinx.HLE/HOS/Services/Hid/ResultCode.cs index 993ff7076..488356d44 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/ResultCode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/ResultCode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid +namespace Ryujinx.HLE.HOS.Services.Hid { enum ResultCode { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/AppletFooterUiType.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/AppletFooterUiType.cs index 1eccd856e..b9b0c5f99 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/AppletFooterUiType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/AppletFooterUiType.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Hid.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusHandle.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusHandle.cs index 033eb3069..8e061351e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusHandle.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusHandle.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Hid { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusType.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusType.cs index 25b36ca45..6c70ac25c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid +namespace Ryujinx.HLE.HOS.Services.Hid { public enum BusType : long { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadIdType.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadIdType.cs index 5a9247d92..8f08481cd 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadIdType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadIdType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid +namespace Ryujinx.HLE.HOS.Services.Hid { public enum NpadIdType { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadStyleIndex.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadStyleIndex.cs index 04550b6fe..c42a5bc56 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadStyleIndex.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadStyleIndex.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid +namespace Ryujinx.HLE.HOS.Services.Hid { public enum NpadStyleIndex : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/NpadJoyHoldType.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/NpadJoyHoldType.cs index 19297de4c..cd61dc92c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/NpadJoyHoldType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/NpadJoyHoldType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid.Types +namespace Ryujinx.HLE.HOS.Services.Hid.Types { enum NpadJoyHoldType { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/AnalogStickState.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/AnalogStickState.cs index bf4b58885..b9af211c1 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/AnalogStickState.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/AnalogStickState.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common { struct AnalogStickState { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/AtomicStorage.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/AtomicStorage.cs index b6bc288e6..c9f59ce0f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/AtomicStorage.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/AtomicStorage.cs @@ -1,4 +1,4 @@ -using System.Threading; +using System.Threading; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledDataStruct.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledDataStruct.cs index ae1997d4e..312075bc4 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledDataStruct.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledDataStruct.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Buffers.Binary; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/RingLifo.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/RingLifo.cs index 26ea1cff1..99f2f59e4 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/RingLifo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/RingLifo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System; using System.Runtime.CompilerServices; using System.Threading; diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadAttribute.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadAttribute.cs index abc6990b8..dadaf6b29 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadAttribute.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadAttribute.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugPad { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadButton.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadButton.cs index dc713a038..b0bb9b959 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadButton.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadButton.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugPad { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadState.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadState.cs index 0846cfc73..f26440c4b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadState.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadState.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugPad diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardKey.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardKey.cs index 336037ab1..7f75bc3f9 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardKey.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardKey.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Keyboard { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardKeyShift.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardKeyShift.cs index 46461ad84..c19b5e614 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardKeyShift.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardKeyShift.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Keyboard +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Keyboard { enum KeyboardKeyShift { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardModifier.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardModifier.cs index ad94619ed..890daa0d0 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardModifier.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardModifier.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Keyboard { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardState.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardState.cs index 4de92813b..3f7d9409d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardState.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardState.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Keyboard diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseAttribute.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseAttribute.cs index ce3dd9462..048dd357c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseAttribute.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseAttribute.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Mouse { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseButton.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseButton.cs index 3e0259938..4a6f73b8b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseButton.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseButton.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Mouse { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseState.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseState.cs index c953c7945..41fe68b8b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseState.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseState.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Mouse diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/DeviceType.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/DeviceType.cs index 259c712b8..d56f849a6 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/DeviceType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/DeviceType.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadAttribute.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadAttribute.cs index 6ad2531f4..6d7719e82 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadAttribute.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadAttribute.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadBatteryLevel.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadBatteryLevel.cs index a84e0259d..7f5b17ff5 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadBatteryLevel.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadBatteryLevel.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad { enum NpadBatteryLevel { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadButton.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadButton.cs index 442d4089b..c20db8e0b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadButton.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadButton.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadColorAttribute.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadColorAttribute.cs index 1a7846dbc..e8140459c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadColorAttribute.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadColorAttribute.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad { enum NpadColorAttribute : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadCommonState.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadCommonState.cs index e1d70a8a2..d3caf7170 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadCommonState.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadCommonState.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadFullKeyColorState.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadFullKeyColorState.cs index 92d4a2ae0..77127c2c2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadFullKeyColorState.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadFullKeyColorState.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad { struct NpadFullKeyColorState { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadGcTriggerState.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadGcTriggerState.cs index 39453984f..41e841342 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadGcTriggerState.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadGcTriggerState.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadInternalState.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadInternalState.cs index 60d16fd83..f79a2657e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadInternalState.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadInternalState.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadJoyAssignmentMode.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadJoyAssignmentMode.cs index c50abe16e..b8a4623f4 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadJoyAssignmentMode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadJoyAssignmentMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad { enum NpadJoyAssignmentMode : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadJoyColorState.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadJoyColorState.cs index 6fec613b6..4e00b5aea 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadJoyColorState.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadJoyColorState.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad { struct NpadJoyColorState { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadLarkType.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadLarkType.cs index a487a911a..013c5fee5 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadLarkType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadLarkType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad { enum NpadLarkType : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadLuciaType.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadLuciaType.cs index e12e84e4f..18756bc34 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadLuciaType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadLuciaType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad { enum NpadLuciaType { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadState.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadState.cs index 643234fc2..fb32e716d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadState.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadState.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadStyleTag.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadStyleTag.cs index d9ecdcd1a..bf4d91879 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadStyleTag.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadStyleTag.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadSystemButtonProperties.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadSystemButtonProperties.cs index 56a4a80f7..6f820ef69 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadSystemButtonProperties.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadSystemButtonProperties.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadSystemProperties.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadSystemProperties.cs index 817c6c143..79110fe44 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadSystemProperties.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadSystemProperties.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/SixAxisSensorAttribute.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/SixAxisSensorAttribute.cs index 0190f09d7..b6e57496c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/SixAxisSensorAttribute.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/SixAxisSensorAttribute.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/SixAxisSensorState.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/SixAxisSensorState.cs index 25f65a0ef..f3c2b208f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/SixAxisSensorState.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/SixAxisSensorState.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/SharedMemory.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/SharedMemory.cs index 640076b34..d6283eb57 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/SharedMemory.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/SharedMemory.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugPad; using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Keyboard; diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchAttribute.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchAttribute.cs index 7c43e6cd4..44d7c22aa 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchAttribute.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchAttribute.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.TouchScreen { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchScreenState.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchScreenState.cs index 5ce51ee3c..d256da0de 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchScreenState.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchScreenState.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchState.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchState.cs index 908f9ed5e..06be9b24c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchState.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchState.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.TouchScreen +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.TouchScreen { struct TouchState { diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/IMonitorServiceCreator.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/IMonitorServiceCreator.cs index a7e99241c..4bea3945a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/IMonitorServiceCreator.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/IMonitorServiceCreator.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ldn +namespace Ryujinx.HLE.HOS.Services.Ldn { [Service("ldn:m")] class IMonitorServiceCreator : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/ISystemServiceCreator.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/ISystemServiceCreator.cs index 9acfef5c9..535013b0b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/ISystemServiceCreator.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/ISystemServiceCreator.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ldn +namespace Ryujinx.HLE.HOS.Services.Ldn { [Service("ldn:s")] class ISystemServiceCreator : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/IUserServiceCreator.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/IUserServiceCreator.cs index 7bcb7785f..633d5f739 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/IUserServiceCreator.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/IUserServiceCreator.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator; +using Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator; namespace Ryujinx.HLE.HOS.Services.Ldn { diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/Lp2p/IServiceCreator.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/Lp2p/IServiceCreator.cs index f2fd482dd..797a7a9bd 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/Lp2p/IServiceCreator.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/Lp2p/IServiceCreator.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ldn.Lp2p +namespace Ryujinx.HLE.HOS.Services.Ldn.Lp2p { [Service("lp2p:app")] // 9.0.0+ [Service("lp2p:sys")] // 9.0.0+ diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/NetworkInterface.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/NetworkInterface.cs index 26696cbeb..e4a16dbb1 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/NetworkInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/NetworkInterface.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.HLE.HOS.Services.Ldn.Types; using System.Net; diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/AcceptPolicy.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/AcceptPolicy.cs index 272a2fd8b..f49b7bddb 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/AcceptPolicy.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/AcceptPolicy.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ldn.Types +namespace Ryujinx.HLE.HOS.Services.Ldn.Types { enum AcceptPolicy : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/CommonNetworkInfo.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/CommonNetworkInfo.cs index cd3a5716c..217bca4fb 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/CommonNetworkInfo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/CommonNetworkInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Ldn.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/DisconnectReason.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/DisconnectReason.cs index e3fd0ed43..00a70f228 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/DisconnectReason.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/DisconnectReason.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ldn.Types +namespace Ryujinx.HLE.HOS.Services.Ldn.Types { enum DisconnectReason : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/IntentId.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/IntentId.cs index e1ffec5e4..2c5cdd95b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/IntentId.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/IntentId.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Ldn.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NetworkConfig.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NetworkConfig.cs index aea9a4a7e..4da5fe42b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NetworkConfig.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NetworkConfig.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Ldn.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NetworkId.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NetworkId.cs index 9579647b3..7039256fa 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NetworkId.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NetworkId.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Ldn.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NetworkInfo.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NetworkInfo.cs index c1fb87d4a..98434b690 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NetworkInfo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NetworkInfo.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Ldn.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NetworkState.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NetworkState.cs index 61fd831df..5b613552b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NetworkState.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NetworkState.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ldn.Types +namespace Ryujinx.HLE.HOS.Services.Ldn.Types { enum NetworkState { diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NetworkType.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NetworkType.cs index a9ca153fb..5db23efbe 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NetworkType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NetworkType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ldn.Types +namespace Ryujinx.HLE.HOS.Services.Ldn.Types { enum NetworkType : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NodeLatestUpdateFlags.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NodeLatestUpdateFlags.cs index 3b69b2798..66442f13e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NodeLatestUpdateFlags.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/NodeLatestUpdateFlags.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Ldn.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/ScanFilter.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/ScanFilter.cs index a5991074a..449c923cc 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/ScanFilter.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/ScanFilter.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Ldn.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/ScanFilterFlag.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/ScanFilterFlag.cs index f27b52c35..c59224cbc 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/ScanFilterFlag.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/ScanFilterFlag.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Ldn.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/SecurityMode.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/SecurityMode.cs index a621d20fc..1cdb7957f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/SecurityMode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/SecurityMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ldn.Types +namespace Ryujinx.HLE.HOS.Services.Ldn.Types { enum SecurityMode : ushort { diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/SecurityParameter.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/SecurityParameter.cs index 534dbc7ae..dbcaa9eeb 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/Types/SecurityParameter.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/Types/SecurityParameter.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Ldn.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/INetworkClient.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/INetworkClient.cs index 81825e977..7ad6de51d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/INetworkClient.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/INetworkClient.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Ldn.Types; +using Ryujinx.HLE.HOS.Services.Ldn.Types; using Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.Types; using System; diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/IUserLocalCommunicationService.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/IUserLocalCommunicationService.cs index 8c6ea66f7..1d4b5485e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/IUserLocalCommunicationService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/IUserLocalCommunicationService.cs @@ -1,4 +1,4 @@ -using LibHac.Ns; +using LibHac.Ns; using Ryujinx.Common; using Ryujinx.Common.Configuration.Multiplayer; using Ryujinx.Common.Logging; diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnDisabledClient.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnDisabledClient.cs index e5340b4e9..e3385a1ed 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnDisabledClient.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnDisabledClient.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Ldn.Types; +using Ryujinx.HLE.HOS.Services.Ldn.Types; using Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.Types; using System; diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/LanDiscovery.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/LanDiscovery.cs index 8cfd77acb..b5f643d23 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/LanDiscovery.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/LanDiscovery.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Common.Memory; using Ryujinx.Common.Utilities; using Ryujinx.HLE.HOS.Services.Ldn.Types; diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/LanProtocol.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/LanProtocol.cs index f22e430bd..4b01bfe31 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/LanProtocol.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/LanProtocol.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Common.Memory; using Ryujinx.Common.Utilities; using Ryujinx.HLE.HOS.Services.Ldn.Types; diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/LdnMitmClient.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/LdnMitmClient.cs index 068013053..273acdd5e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/LdnMitmClient.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/LdnMitmClient.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Common.Utilities; using Ryujinx.HLE.HOS.Services.Ldn.Types; using Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.Types; diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/ILdnSocket.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/ILdnSocket.cs index b6e6cea9e..9427cc944 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/ILdnSocket.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/ILdnSocket.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net; namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnMitm.Proxy diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/ILdnTcpSocket.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/ILdnTcpSocket.cs index 97e3bd627..dfdd5fe7d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/ILdnTcpSocket.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/ILdnTcpSocket.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnMitm.Proxy +namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnMitm.Proxy { internal interface ILdnTcpSocket : ILdnSocket { diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/LdnProxyTcpClient.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/LdnProxyTcpClient.cs index cfe9a8aae..7f755b409 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/LdnProxyTcpClient.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/LdnProxyTcpClient.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using System; using System.Net; using System.Net.Sockets; diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/LdnProxyTcpServer.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/LdnProxyTcpServer.cs index 0ca12b9f6..d15e2b55d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/LdnProxyTcpServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/LdnProxyTcpServer.cs @@ -1,4 +1,4 @@ -using NetCoreServer; +using NetCoreServer; using Ryujinx.Common.Logging; using System; using System.Net; diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/LdnProxyTcpSession.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/LdnProxyTcpSession.cs index f30c4b011..667230b81 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/LdnProxyTcpSession.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/LdnProxyTcpSession.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Ldn.Types; using System.Net; using System.Net.Sockets; diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/LdnProxyUdpServer.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/LdnProxyUdpServer.cs index b1519d1ff..0f5875a1d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/LdnProxyUdpServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Proxy/LdnProxyUdpServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Ldn.Types; using Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnMitm.Types; using System; diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Types/LanPacketHeader.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Types/LanPacketHeader.cs index 4cebe414d..1eca1bb84 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Types/LanPacketHeader.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Types/LanPacketHeader.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnMitm.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Types/LanPacketType.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Types/LanPacketType.cs index 901f00b00..826ea7232 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Types/LanPacketType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/Types/LanPacketType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnMitm.Types +namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnMitm.Types { internal enum LanPacketType : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/NetworkChangeEventArgs.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/NetworkChangeEventArgs.cs index b379d2680..a23e110f0 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/NetworkChangeEventArgs.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/NetworkChangeEventArgs.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Ldn.Types; +using Ryujinx.HLE.HOS.Services.Ldn.Types; using System; namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/Types/ConnectPrivateRequest.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/Types/ConnectPrivateRequest.cs index 058ce62d0..a402f653c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/Types/ConnectPrivateRequest.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/Types/ConnectPrivateRequest.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Ldn.Types; +using Ryujinx.HLE.HOS.Services.Ldn.Types; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/Types/ConnectRequest.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/Types/ConnectRequest.cs index 136589b2a..4ea2fceb1 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/Types/ConnectRequest.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/Types/ConnectRequest.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Ldn.Types; +using Ryujinx.HLE.HOS.Services.Ldn.Types; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/Types/CreateAccessPointPrivateRequest.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/Types/CreateAccessPointPrivateRequest.cs index ec0668884..ac0ff7d94 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/Types/CreateAccessPointPrivateRequest.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/Types/CreateAccessPointPrivateRequest.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Ldn.Types; +using Ryujinx.HLE.HOS.Services.Ldn.Types; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/Types/CreateAccessPointRequest.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/Types/CreateAccessPointRequest.cs index eecea5eb0..f67f0aac9 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/Types/CreateAccessPointRequest.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/Types/CreateAccessPointRequest.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Ldn.Types; +using Ryujinx.HLE.HOS.Services.Ldn.Types; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Loader/IDebugMonitorInterface.cs b/src/Ryujinx.HLE/HOS/Services/Loader/IDebugMonitorInterface.cs index 78c405b4e..5e4e59755 100644 --- a/src/Ryujinx.HLE/HOS/Services/Loader/IDebugMonitorInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Loader/IDebugMonitorInterface.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Loader +namespace Ryujinx.HLE.HOS.Services.Loader { [Service("ldr:dmnt")] class IDebugMonitorInterface : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Loader/IProcessManagerInterface.cs b/src/Ryujinx.HLE/HOS/Services/Loader/IProcessManagerInterface.cs index 693d68dac..cb5a26d17 100644 --- a/src/Ryujinx.HLE/HOS/Services/Loader/IProcessManagerInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Loader/IProcessManagerInterface.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Loader +namespace Ryujinx.HLE.HOS.Services.Loader { [Service("ldr:pm")] class IProcessManagerInterface : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Loader/IShellInterface.cs b/src/Ryujinx.HLE/HOS/Services/Loader/IShellInterface.cs index d2dc57bdb..f9cf44d9d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Loader/IShellInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Loader/IShellInterface.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Loader +namespace Ryujinx.HLE.HOS.Services.Loader { [Service("ldr:shel")] class IShellInterface : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Loader/ResultCode.cs b/src/Ryujinx.HLE/HOS/Services/Loader/ResultCode.cs index ec1166480..6744563d9 100644 --- a/src/Ryujinx.HLE/HOS/Services/Loader/ResultCode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Loader/ResultCode.cs @@ -1,4 +1,4 @@ -using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.CodeAnalysis; namespace Ryujinx.HLE.HOS.Services.Loader { diff --git a/src/Ryujinx.HLE/HOS/Services/Mig/IService.cs b/src/Ryujinx.HLE/HOS/Services/Mig/IService.cs index 81f858f8f..a4d432849 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mig/IService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mig/IService.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mig +namespace Ryujinx.HLE.HOS.Services.Mig { [Service("mig:usr")] // 4.0.0+ class IService : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/DatabaseImpl.cs b/src/Ryujinx.HLE/HOS/Services/Mii/DatabaseImpl.cs index 5041dc882..4bb736992 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/DatabaseImpl.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/DatabaseImpl.cs @@ -1,4 +1,4 @@ -using LibHac; +using LibHac; using Ryujinx.Cpu; using Ryujinx.HLE.HOS.Services.Mii.Types; using System; diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/DatabaseSessionMetadata.cs b/src/Ryujinx.HLE/HOS/Services/Mii/DatabaseSessionMetadata.cs index 56486c434..b01295d80 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/DatabaseSessionMetadata.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/DatabaseSessionMetadata.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Mii.Types; +using Ryujinx.HLE.HOS.Services.Mii.Types; namespace Ryujinx.HLE.HOS.Services.Mii { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Helper.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Helper.cs index 71b9ab43f..f4d288e9c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Helper.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Helper.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System; using System.Buffers.Binary; diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/IImageDatabaseService.cs b/src/Ryujinx.HLE/HOS/Services/Mii/IImageDatabaseService.cs index 0a763da1c..88d7d7b3c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/IImageDatabaseService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/IImageDatabaseService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; namespace Ryujinx.HLE.HOS.Services.Mii { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/IStaticService.cs b/src/Ryujinx.HLE/HOS/Services/Mii/IStaticService.cs index acf358eea..8a6800024 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/IStaticService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/IStaticService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.HLE.HOS.Services.Mii.StaticService; using Ryujinx.HLE.HOS.Services.Mii.Types; diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/MiiDatabaseManager.cs b/src/Ryujinx.HLE/HOS/Services/Mii/MiiDatabaseManager.cs index cb43ed2ad..23a52d908 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/MiiDatabaseManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/MiiDatabaseManager.cs @@ -1,4 +1,4 @@ -using LibHac; +using LibHac; using LibHac.Common; using LibHac.Fs; using LibHac.Fs.Fsa; diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/ResultCode.cs b/src/Ryujinx.HLE/HOS/Services/Mii/ResultCode.cs index 8611d5af1..cccc519ec 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/ResultCode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/ResultCode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mii +namespace Ryujinx.HLE.HOS.Services.Mii { public enum ResultCode { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/StaticService/DatabaseServiceImpl.cs b/src/Ryujinx.HLE/HOS/Services/Mii/StaticService/DatabaseServiceImpl.cs index 0d286e1cc..fc12e2533 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/StaticService/DatabaseServiceImpl.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/StaticService/DatabaseServiceImpl.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Mii.Types; +using Ryujinx.HLE.HOS.Services.Mii.Types; using Ryujinx.HLE.HOS.Services.Settings; using System; diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/StaticService/IDatabaseService.cs b/src/Ryujinx.HLE/HOS/Services/Mii/StaticService/IDatabaseService.cs index 051921f50..1a1c20d6e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/StaticService/IDatabaseService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/StaticService/IDatabaseService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Services.Mii.Types; using System; diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/Age.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/Age.cs index a443ad09a..9c89ffd31 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/Age.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/Age.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mii.Types +namespace Ryujinx.HLE.HOS.Services.Mii.Types { enum Age : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/BeardType.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/BeardType.cs index 85fda6713..8f362c154 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/BeardType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/BeardType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mii.Types +namespace Ryujinx.HLE.HOS.Services.Mii.Types { enum BeardType : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/CharInfo.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/CharInfo.cs index 14b616870..63f44694f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/CharInfo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/CharInfo.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Mii.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/CharInfoElement.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/CharInfoElement.cs index fead4861a..974fc239e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/CharInfoElement.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/CharInfoElement.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Mii.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/CommonColor.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/CommonColor.cs index 3f61232ce..a21eb8227 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/CommonColor.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/CommonColor.cs @@ -1,4 +1,4 @@ - + namespace Ryujinx.HLE.HOS.Services.Mii.Types { enum CommonColor : byte diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/CoreData.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/CoreData.cs index 4f6e289e2..aaeb8aa10 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/CoreData.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/CoreData.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/CreateId.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/CreateId.cs index f61e83d73..96533a04d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/CreateId.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/CreateId.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Mii.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/DefaultMii.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/DefaultMii.cs index e3c6a42e6..b7a63d16b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/DefaultMii.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/DefaultMii.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Mii.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/EyeType.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/EyeType.cs index 70b6e31c5..0d385c451 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/EyeType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/EyeType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mii.Types +namespace Ryujinx.HLE.HOS.Services.Mii.Types { enum EyeType : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/EyebrowType.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/EyebrowType.cs index 3790128a8..1c9f3436f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/EyebrowType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/EyebrowType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mii.Types +namespace Ryujinx.HLE.HOS.Services.Mii.Types { enum EyebrowType : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/FacelineColor.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/FacelineColor.cs index 4571168f1..dc432eacf 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/FacelineColor.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/FacelineColor.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mii.Types +namespace Ryujinx.HLE.HOS.Services.Mii.Types { enum FacelineColor : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/FacelineMake.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/FacelineMake.cs index acd94ca2e..fdd7160e8 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/FacelineMake.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/FacelineMake.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mii.Types +namespace Ryujinx.HLE.HOS.Services.Mii.Types { enum FacelineMake : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/FacelineType.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/FacelineType.cs index 29d14a126..82d87dd40 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/FacelineType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/FacelineType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mii.Types +namespace Ryujinx.HLE.HOS.Services.Mii.Types { enum FacelineType : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/FacelineWrinkle.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/FacelineWrinkle.cs index 1a144748b..6b45e27ac 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/FacelineWrinkle.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/FacelineWrinkle.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mii.Types +namespace Ryujinx.HLE.HOS.Services.Mii.Types { enum FacelineWrinkle : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/FontRegion.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/FontRegion.cs index c981a5ede..b10a5d736 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/FontRegion.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/FontRegion.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mii.Types +namespace Ryujinx.HLE.HOS.Services.Mii.Types { enum FontRegion : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/Gender.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/Gender.cs index c120c7581..b7833cb52 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/Gender.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/Gender.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mii.Types +namespace Ryujinx.HLE.HOS.Services.Mii.Types { enum Gender : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/GlassType.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/GlassType.cs index e2b6e6f5b..3bf28dc51 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/GlassType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/GlassType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mii.Types +namespace Ryujinx.HLE.HOS.Services.Mii.Types { enum GlassType : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/HairFlip.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/HairFlip.cs index dee42e0d1..4e719e15c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/HairFlip.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/HairFlip.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mii.Types +namespace Ryujinx.HLE.HOS.Services.Mii.Types { enum HairFlip : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/HairType.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/HairType.cs index a3e183961..37b7f6bc9 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/HairType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/HairType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mii.Types +namespace Ryujinx.HLE.HOS.Services.Mii.Types { enum HairType : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/IElement.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/IElement.cs index 94c65b23b..0f604e89d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/IElement.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/IElement.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mii.Types +namespace Ryujinx.HLE.HOS.Services.Mii.Types { interface IElement { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/IStoredData.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/IStoredData.cs index a6552a57c..804e0343d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/IStoredData.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/IStoredData.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Mii.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/MoleType.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/MoleType.cs index 7ed274d2a..6aa9517c2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/MoleType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/MoleType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mii.Types +namespace Ryujinx.HLE.HOS.Services.Mii.Types { enum MoleType : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/MouthType.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/MouthType.cs index 69236bd42..89447b081 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/MouthType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/MouthType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mii.Types +namespace Ryujinx.HLE.HOS.Services.Mii.Types { enum MouthType : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/MustacheType.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/MustacheType.cs index 7b0255f20..6f13c1a69 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/MustacheType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/MustacheType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mii.Types +namespace Ryujinx.HLE.HOS.Services.Mii.Types { enum MustacheType : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/Nickname.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/Nickname.cs index 6665ca6d4..4cebfe55d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/Nickname.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/Nickname.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System; using System.Runtime.InteropServices; using System.Text; diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/NintendoFigurineDatabase.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/NintendoFigurineDatabase.cs index 1e36788e7..5865fb11a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/NintendoFigurineDatabase.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/NintendoFigurineDatabase.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/NoseType.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/NoseType.cs index 3144b132a..00f0ed12b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/NoseType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/NoseType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mii.Types +namespace Ryujinx.HLE.HOS.Services.Mii.Types { enum NoseType : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/Race.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/Race.cs index 5f304a4e8..953858b30 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/Race.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/Race.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mii.Types +namespace Ryujinx.HLE.HOS.Services.Mii.Types { enum Race : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/RandomMiiConstants.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/RandomMiiConstants.cs index ab08247b4..092733f7e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/RandomMiiConstants.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/RandomMiiConstants.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/Source.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/Source.cs index f4d2b8cb9..0980564fa 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/Source.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/Source.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Mii.Types +namespace Ryujinx.HLE.HOS.Services.Mii.Types { enum Source { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/SourceFlag.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/SourceFlag.cs index c04eb0437..7f6ddf471 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/SourceFlag.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/SourceFlag.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Mii.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/SpecialMiiKeyCode.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/SpecialMiiKeyCode.cs index be2433ddf..efa83605d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/SpecialMiiKeyCode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/SpecialMiiKeyCode.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Mii.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/StoreData.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/StoreData.cs index 178b48318..44054e6b8 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/StoreData.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/StoreData.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/StoreDataElement.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/StoreDataElement.cs index 2008c1ffa..629c76f59 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/StoreDataElement.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/StoreDataElement.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Mii.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/Ver3StoreData.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/Ver3StoreData.cs index 1c7db8e66..3930b3312 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/Ver3StoreData.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/Ver3StoreData.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Common.Utilities; using System; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/UtilityImpl.cs b/src/Ryujinx.HLE/HOS/Services/Mii/UtilityImpl.cs index 30b201f65..32dbb4946 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/UtilityImpl.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/UtilityImpl.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using Ryujinx.Cpu; using Ryujinx.HLE.HOS.Services.Mii.Types; using Ryujinx.HLE.HOS.Services.Time; diff --git a/src/Ryujinx.HLE/HOS/Services/Mnpp/IServiceForApplication.cs b/src/Ryujinx.HLE/HOS/Services/Mnpp/IServiceForApplication.cs index 7c20579be..8cdab6419 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mnpp/IServiceForApplication.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mnpp/IServiceForApplication.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.Cpu; using Ryujinx.HLE.HOS.Services.Account.Acc; diff --git a/src/Ryujinx.HLE/HOS/Services/Ncm/IContentManager.cs b/src/Ryujinx.HLE/HOS/Services/Ncm/IContentManager.cs index cf0d41494..7c3cc4cbb 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ncm/IContentManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ncm/IContentManager.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ncm +namespace Ryujinx.HLE.HOS.Services.Ncm { [Service("ncm")] class IContentManager : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Ncm/Lr/ILocationResolverManager.cs b/src/Ryujinx.HLE/HOS/Services/Ncm/Lr/ILocationResolverManager.cs index f59216786..35e311c4d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ncm/Lr/ILocationResolverManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ncm/Lr/ILocationResolverManager.cs @@ -1,4 +1,4 @@ -using LibHac.Ncm; +using LibHac.Ncm; using Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager; namespace Ryujinx.HLE.HOS.Services.Ncm.Lr diff --git a/src/Ryujinx.HLE/HOS/Services/Ncm/Lr/LocationResolverManager/ILocationResolver.cs b/src/Ryujinx.HLE/HOS/Services/Ncm/Lr/LocationResolverManager/ILocationResolver.cs index f5a0c665c..71ed56385 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ncm/Lr/LocationResolverManager/ILocationResolver.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ncm/Lr/LocationResolverManager/ILocationResolver.cs @@ -1,4 +1,4 @@ -using LibHac.Ncm; +using LibHac.Ncm; using LibHac.Tools.FsSystem.NcaUtils; using Ryujinx.HLE.FileSystem; using System.Text; diff --git a/src/Ryujinx.HLE/HOS/Services/Ncm/Lr/ResultCode.cs b/src/Ryujinx.HLE/HOS/Services/Ncm/Lr/ResultCode.cs index 3a027fd04..66b9217e3 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ncm/Lr/ResultCode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ncm/Lr/ResultCode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ncm.Lr +namespace Ryujinx.HLE.HOS.Services.Ncm.Lr { enum ResultCode { diff --git a/src/Ryujinx.HLE/HOS/Services/News/IServiceCreator.cs b/src/Ryujinx.HLE/HOS/Services/News/IServiceCreator.cs index 5d33e1a2b..3d14629ca 100644 --- a/src/Ryujinx.HLE/HOS/Services/News/IServiceCreator.cs +++ b/src/Ryujinx.HLE/HOS/Services/News/IServiceCreator.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.News +namespace Ryujinx.HLE.HOS.Services.News { [Service("news:a")] [Service("news:c")] diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/IAmManager.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/IAmManager.cs index 142c4da48..770d423fd 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/IAmManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/IAmManager.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nfc +namespace Ryujinx.HLE.HOS.Services.Nfc { [Service("nfc:am")] class IAmManager : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/ISystemManager.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/ISystemManager.cs index 50453117d..be23d2cdc 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/ISystemManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/ISystemManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Nfc.NfcManager; +using Ryujinx.HLE.HOS.Services.Nfc.NfcManager; namespace Ryujinx.HLE.HOS.Services.Nfc { diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/IUserManager.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/IUserManager.cs index 69c3bd191..5b8afce79 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/IUserManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/IUserManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Nfc.NfcManager; +using Ryujinx.HLE.HOS.Services.Nfc.NfcManager; namespace Ryujinx.HLE.HOS.Services.Nfc { diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Mifare/IUserManager.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Mifare/IUserManager.cs index 2c5aaa2e9..295c7e71a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Mifare/IUserManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Mifare/IUserManager.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nfc.Mifare +namespace Ryujinx.HLE.HOS.Services.Nfc.Mifare { [Service("nfc:mf:u")] class IUserManager : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/NfcManager/INfc.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/NfcManager/INfc.cs index dac0c4c33..72027cf48 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/NfcManager/INfc.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/NfcManager/INfc.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; namespace Ryujinx.HLE.HOS.Services.Nfc.NfcManager { diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/NfcManager/Types/NfcPermissionLevel.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/NfcManager/Types/NfcPermissionLevel.cs index 37a78dfd3..11ed5678f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/NfcManager/Types/NfcPermissionLevel.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/NfcManager/Types/NfcPermissionLevel.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nfc.NfcManager +namespace Ryujinx.HLE.HOS.Services.Nfc.NfcManager { enum NfcPermissionLevel { diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/AmiiboJsonSerializerContext.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/AmiiboJsonSerializerContext.cs index d48671126..94dde5b88 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/AmiiboJsonSerializerContext.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/AmiiboJsonSerializerContext.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager; +using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager; using System.Text.Json.Serialization; namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/IDebugManager.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/IDebugManager.cs index 8196f42d1..b3eff0c2d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/IDebugManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/IDebugManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager; +using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager; namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp { diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/ISystemManager.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/ISystemManager.cs index d5933a4ce..4cb541a6c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/ISystemManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/ISystemManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager; +using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager; namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp { diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/IUserManager.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/IUserManager.cs index fa80e9b86..229386c01 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/IUserManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/IUserManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager; +using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager; namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp { diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/INfp.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/INfp.cs index 9dc75cd2c..20f67a4ef 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/INfp.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/INfp.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Cpu; using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Ipc; diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/AmiiboConstants.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/AmiiboConstants.cs index a5d420cb1..9139ab0b2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/AmiiboConstants.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/AmiiboConstants.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager +namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager { static class AmiiboConstants { diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/CommonInfo.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/CommonInfo.cs index ba953125e..80bf4077c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/CommonInfo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/CommonInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/DeviceType.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/DeviceType.cs index 17b09eb78..f75c2f168 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/DeviceType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/DeviceType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager +namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager { enum DeviceType : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/ModelInfo.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/ModelInfo.cs index 48aba269d..cddd87070 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/ModelInfo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/ModelInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/MountTarget.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/MountTarget.cs index d71d7eea8..8e5da97b4 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/MountTarget.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/MountTarget.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager +namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager { enum MountTarget : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/NfpDevice.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/NfpDevice.cs index 82602837a..3320238a8 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/NfpDevice.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/NfpDevice.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Kernel.Threading; +using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.HLE.HOS.Services.Hid; namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/NfpDeviceState.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/NfpDeviceState.cs index d0e0c8baa..9e92e8484 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/NfpDeviceState.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/NfpDeviceState.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager +namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager { enum NfpDeviceState { diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/NfpPermissionLevel.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/NfpPermissionLevel.cs index 972f0af34..9c440c45b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/NfpPermissionLevel.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/NfpPermissionLevel.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager +namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager { enum NfpPermissionLevel { diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/RegisterInfo.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/RegisterInfo.cs index 28d8fae20..424b0193e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/RegisterInfo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/RegisterInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.HLE.HOS.Services.Mii.Types; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/State.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/State.cs index ca7faf042..71a85b44d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/State.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/State.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager +namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager { enum State { diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/TagInfo.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/TagInfo.cs index 903743f13..d6d206005 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/TagInfo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/TagInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/VirtualAmiiboFile.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/VirtualAmiiboFile.cs index 51e04dcac..65d380979 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/VirtualAmiiboFile.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/VirtualAmiiboFile.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/ResultCode.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/ResultCode.cs index 233877073..92184fb40 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/ResultCode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/ResultCode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp +namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp { public enum ResultCode { diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/VirtualAmiibo.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/VirtualAmiibo.cs index 3d1426530..ba4a81e0e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/VirtualAmiibo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/VirtualAmiibo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Configuration; +using Ryujinx.Common.Configuration; using Ryujinx.Common.Memory; using Ryujinx.Common.Utilities; using Ryujinx.Cpu; diff --git a/src/Ryujinx.HLE/HOS/Services/Ngct/IService.cs b/src/Ryujinx.HLE/HOS/Services/Ngct/IService.cs index 802be7514..d9ca70047 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ngct/IService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ngct/IService.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ngct +namespace Ryujinx.HLE.HOS.Services.Ngct { [Service("ngct:u")] // 9.0.0+ class IService : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Ngct/IServiceWithManagementApi.cs b/src/Ryujinx.HLE/HOS/Services/Ngct/IServiceWithManagementApi.cs index 7ef998359..88995335c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ngct/IServiceWithManagementApi.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ngct/IServiceWithManagementApi.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ngct +namespace Ryujinx.HLE.HOS.Services.Ngct { [Service("ngct:s")] // 9.0.0+ class IServiceWithManagementApi : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Ngct/NgctServer.cs b/src/Ryujinx.HLE/HOS/Services/Ngct/NgctServer.cs index ae00842d7..f652ecda8 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ngct/NgctServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ngct/NgctServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using System.Text; namespace Ryujinx.HLE.HOS.Services.Ngct diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/GeneralService/GeneralServiceManager.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/GeneralService/GeneralServiceManager.cs index 5f26f2114..16eefc87d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/GeneralService/GeneralServiceManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/GeneralService/GeneralServiceManager.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.GeneralService diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/GeneralService/Types/GeneralServiceDetail.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/GeneralService/Types/GeneralServiceDetail.cs index fab158515..73853a830 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/GeneralService/Types/GeneralServiceDetail.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/GeneralService/Types/GeneralServiceDetail.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.GeneralService +namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.GeneralService { class GeneralServiceDetail { diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/DnsSetting.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/DnsSetting.cs index 4a9d782db..af80db480 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/DnsSetting.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/DnsSetting.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net.NetworkInformation; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionState.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionState.cs index 8c9efa61e..ba8efd198 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionState.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionState.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types +namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types { enum InternetConnectionState : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionStatus.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionStatus.cs index 1bf41fc6b..fa780fd2e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionStatus.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionStatus.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionType.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionType.cs index ab03382d4..4917b8f8b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types +namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types { enum InternetConnectionType : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpAddressSetting.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpAddressSetting.cs index 5ea9d849c..4fa674de9 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpAddressSetting.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpAddressSetting.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net.NetworkInformation; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpSettingData.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpSettingData.cs index 328dc7da6..c966999b5 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpSettingData.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpSettingData.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpV4Address.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpV4Address.cs index e5c2f39ac..9d902a1ad 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpV4Address.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpV4Address.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/NetworkProfileData.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/NetworkProfileData.cs index 12a1c30fa..fe69fef1b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/NetworkProfileData.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/NetworkProfileData.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/ProxySetting.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/ProxySetting.cs index 909138e80..4d872d343 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/ProxySetting.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/ProxySetting.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Common.Utilities; using System; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/WirelessSettingData.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/WirelessSettingData.cs index 53855a4ef..4bbc69ec7 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/WirelessSettingData.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/WirelessSettingData.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Nim/INetworkInstallManager.cs b/src/Ryujinx.HLE/HOS/Services/Nim/INetworkInstallManager.cs index 7ed1ffa62..4e62b97bd 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nim/INetworkInstallManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nim/INetworkInstallManager.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nim +namespace Ryujinx.HLE.HOS.Services.Nim { [Service("nim")] class INetworkInstallManager : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessServer.cs b/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessServer.cs index 29a47baf6..4deecc531 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface.ShopServiceAccessServer; namespace Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface diff --git a/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessServerInterface.cs b/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessServerInterface.cs index 847a432e9..52412489a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessServerInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessServerInterface.cs @@ -1,4 +1,4 @@ -using LibHac.Ncm; +using LibHac.Ncm; using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Arp; using Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface; diff --git a/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessSystemInterface.cs b/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessSystemInterface.cs index a57677aed..dfec2efd2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessSystemInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessSystemInterface.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nim +namespace Ryujinx.HLE.HOS.Services.Nim { [Service("nim:ecas")] // 7.0.0+ class IShopServiceAccessSystemInterface : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessor.cs b/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessor.cs index 4d3002cc1..c1f58a076 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessor.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAccessor.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface.ShopServiceAccessServer.ShopServiceAccessor; diff --git a/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAsync.cs b/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAsync.cs index 150d48d4d..225b9a704 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAsync.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceAsync.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface.ShopServiceAccessServer.ShopServiceAccessor +namespace Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface.ShopServiceAccessServer.ShopServiceAccessor { class IShopServiceAsync : IpcService { diff --git a/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceManager.cs b/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceManager.cs index b5a2f6b55..8f2e0703a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nim/IShopServiceManager.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nim +namespace Ryujinx.HLE.HOS.Services.Nim { [Service("nim:shp")] class IShopServiceManager : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Nim/Ntc/IStaticService.cs b/src/Ryujinx.HLE/HOS/Services/Nim/Ntc/IStaticService.cs index 2b078be7d..ed6e4472e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nim/Ntc/IStaticService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nim/Ntc/IStaticService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Nim.Ntc.StaticService; namespace Ryujinx.HLE.HOS.Services.Nim.Ntc diff --git a/src/Ryujinx.HLE/HOS/Services/Nim/Ntc/StaticService/IEnsureNetworkClockAvailabilityService.cs b/src/Ryujinx.HLE/HOS/Services/Nim/Ntc/StaticService/IEnsureNetworkClockAvailabilityService.cs index 9fee7b1ac..2bd6f4f0d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nim/Ntc/StaticService/IEnsureNetworkClockAvailabilityService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nim/Ntc/StaticService/IEnsureNetworkClockAvailabilityService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.Horizon.Common; diff --git a/src/Ryujinx.HLE/HOS/Services/Notification/INotificationServicesForApplication.cs b/src/Ryujinx.HLE/HOS/Services/Notification/INotificationServicesForApplication.cs index 0d77dd6e6..29f8bfa85 100644 --- a/src/Ryujinx.HLE/HOS/Services/Notification/INotificationServicesForApplication.cs +++ b/src/Ryujinx.HLE/HOS/Services/Notification/INotificationServicesForApplication.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Notification +namespace Ryujinx.HLE.HOS.Services.Notification { [Service("notif:a")] // 9.0.0+ class INotificationServicesForApplication : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Notification/INotificationServicesForSystem.cs b/src/Ryujinx.HLE/HOS/Services/Notification/INotificationServicesForSystem.cs index 8dc1dac3b..c5946be84 100644 --- a/src/Ryujinx.HLE/HOS/Services/Notification/INotificationServicesForSystem.cs +++ b/src/Ryujinx.HLE/HOS/Services/Notification/INotificationServicesForSystem.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Notification +namespace Ryujinx.HLE.HOS.Services.Notification { [Service("notif:s")] // 9.0.0+ class INotificationServicesForSystem : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Npns/INpnsSystem.cs b/src/Ryujinx.HLE/HOS/Services/Npns/INpnsSystem.cs index 53c5b5392..dc707e6f7 100644 --- a/src/Ryujinx.HLE/HOS/Services/Npns/INpnsSystem.cs +++ b/src/Ryujinx.HLE/HOS/Services/Npns/INpnsSystem.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Npns +namespace Ryujinx.HLE.HOS.Services.Npns { [Service("npns:s")] class INpnsSystem : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Npns/INpnsUser.cs b/src/Ryujinx.HLE/HOS/Services/Npns/INpnsUser.cs index cfa25255a..9a794709e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Npns/INpnsUser.cs +++ b/src/Ryujinx.HLE/HOS/Services/Npns/INpnsUser.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Npns +namespace Ryujinx.HLE.HOS.Services.Npns { [Service("npns:u")] class INpnsUser : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs b/src/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs index a8a2a8e0c..f510da594 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs @@ -1,4 +1,4 @@ -using LibHac.Ns; +using LibHac.Ns; using Ryujinx.Common.Utilities; namespace Ryujinx.HLE.HOS.Services.Ns diff --git a/src/Ryujinx.HLE/HOS/Services/Ns/IReadOnlyApplicationControlDataInterface.cs b/src/Ryujinx.HLE/HOS/Services/Ns/IReadOnlyApplicationControlDataInterface.cs index 8327d6195..ca7d42b48 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ns/IReadOnlyApplicationControlDataInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ns/IReadOnlyApplicationControlDataInterface.cs @@ -1,4 +1,4 @@ -using LibHac.Common; +using LibHac.Common; using LibHac.Ns; namespace Ryujinx.HLE.HOS.Services.Ns diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/Host1xContext.cs b/src/Ryujinx.HLE/HOS/Services/Nv/Host1xContext.cs index 371edbecd..7c7ebf22d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/Host1xContext.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/Host1xContext.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Gpu.Memory; +using Ryujinx.Graphics.Device; using Ryujinx.Graphics.Host1x; using Ryujinx.Graphics.Nvdec; using Ryujinx.Graphics.Vic; @@ -9,7 +9,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv { class Host1xContext : IDisposable { - public MemoryManager Smmu { get; } + public DeviceMemoryManager Smmu { get; } public NvMemoryAllocator MemoryAllocator { get; } public Host1xDevice Host1x { get; } @@ -17,7 +17,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv { MemoryAllocator = new NvMemoryAllocator(); Host1x = new Host1xDevice(gpu.Synchronization); - Smmu = gpu.CreateMemoryManager(pid); + Smmu = gpu.CreateDeviceMemoryManager(pid); var nvdec = new NvdecDevice(Smmu); var vic = new VicDevice(Smmu); Host1x.RegisterDevice(ClassId.Nvdec, nvdec); diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvDebugFSServices.cs b/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvDebugFSServices.cs index 22d0aacc5..a00de31ed 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvDebugFSServices.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvDebugFSServices.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nv +namespace Ryujinx.HLE.HOS.Services.Nv { [Service("nvdrvdbg")] class INvDrvDebugFSServices : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/INvGemControl.cs b/src/Ryujinx.HLE/HOS/Services/Nv/INvGemControl.cs index 2134c026e..9cb2c7e3e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/INvGemControl.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/INvGemControl.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nv +namespace Ryujinx.HLE.HOS.Services.Nv { [Service("nvgem:c")] class INvGemControl : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/INvGemCoreDump.cs b/src/Ryujinx.HLE/HOS/Services/Nv/INvGemCoreDump.cs index ecbbe2226..e79e59008 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/INvGemCoreDump.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/INvGemCoreDump.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nv +namespace Ryujinx.HLE.HOS.Services.Nv { [Service("nvgem:cd")] class INvGemCoreDump : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvDeviceFile.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvDeviceFile.cs index 3eaf8a91b..ef0bac452 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvDeviceFile.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvDeviceFile.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using System; using System.Diagnostics; using System.Reflection; diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/NvHostAsGpuDeviceFile.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/NvHostAsGpuDeviceFile.cs index db460429d..ff9a67644 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/NvHostAsGpuDeviceFile.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/NvHostAsGpuDeviceFile.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Graphics.Gpu.Memory; using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types; using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel; @@ -266,7 +266,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu if (size == 0) { - size = (uint)map.Size; + size = map.Size; } NvInternalResult result = NvInternalResult.Success; diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceContext.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceContext.cs index 36aa10f34..9dd52e6da 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceContext.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceContext.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Gpu.Memory; +using Ryujinx.Graphics.Gpu.Memory; using System.Collections.Generic; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceFlags.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceFlags.cs index 0627d56f5..0d0ae4ca2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceFlags.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceFlags.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AllocSpaceArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AllocSpaceArguments.cs index c9d7724e8..231fa7c13 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AllocSpaceArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AllocSpaceArguments.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/BindChannelArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/BindChannelArguments.cs index 9c6568a3f..51fac8d8f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/BindChannelArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/BindChannelArguments.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/FreeSpaceArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/FreeSpaceArguments.cs index 56e9028e5..f14b751d4 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/FreeSpaceArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/FreeSpaceArguments.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/GetVaRegionsArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/GetVaRegionsArguments.cs index dcb5b49ef..447477823 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/GetVaRegionsArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/GetVaRegionsArguments.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/InitializeExArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/InitializeExArguments.cs index 34b80bd31..e86932bb0 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/InitializeExArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/InitializeExArguments.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/MapBufferExArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/MapBufferExArguments.cs index fdeff9f8b..c0f6d40ee 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/MapBufferExArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/MapBufferExArguments.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/RemapArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/RemapArguments.cs index 1fb224ff0..99afa4bad 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/RemapArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/RemapArguments.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/UnmapBufferArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/UnmapBufferArguments.cs index 46a9659d5..d6bc1bc52 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/UnmapBufferArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/UnmapBufferArguments.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types +namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types { struct UnmapBufferArguments { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostChannelDeviceFile.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostChannelDeviceFile.cs index bd2c5e4d0..bc70b05cf 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostChannelDeviceFile.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostChannelDeviceFile.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Graphics.Gpu; using Ryujinx.Graphics.Gpu.Memory; using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel.Types; @@ -250,12 +250,12 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel { if (map.DmaMapAddress == 0) { - ulong va = _host1xContext.MemoryAllocator.GetFreeAddress((ulong)map.Size, out ulong freeAddressStartPosition, 1, MemoryManager.PageSize); + ulong va = _host1xContext.MemoryAllocator.GetFreeAddress(map.Size, out ulong freeAddressStartPosition, 1, MemoryManager.PageSize); - if (va != NvMemoryAllocator.PteUnmapped && va <= uint.MaxValue && (va + (uint)map.Size) <= uint.MaxValue) + if (va != NvMemoryAllocator.PteUnmapped && va <= uint.MaxValue && (va + map.Size) <= uint.MaxValue) { - _host1xContext.MemoryAllocator.AllocateRange(va, (uint)map.Size, freeAddressStartPosition); - _host1xContext.Smmu.Map(map.Address, va, (uint)map.Size, PteKind.Pitch); // FIXME: This should not use the GMMU. + _host1xContext.MemoryAllocator.AllocateRange(va, map.Size, freeAddressStartPosition); + _host1xContext.Smmu.Map(map.Address, va, map.Size); map.DmaMapAddress = va; } else diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostGpuDeviceFile.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostGpuDeviceFile.cs index 5a1d1a68d..34663e9d7 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostGpuDeviceFile.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostGpuDeviceFile.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Kernel.Threading; +using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel.Types; using Ryujinx.Horizon.Common; using Ryujinx.Memory; diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/AllocGpfifoExArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/AllocGpfifoExArguments.cs index 37577a5f3..9a06fbebd 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/AllocGpfifoExArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/AllocGpfifoExArguments.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Nv.Types; +using Ryujinx.HLE.HOS.Services.Nv.Types; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/AllocObjCtxArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/AllocObjCtxArguments.cs index 1ffbb68fc..4578ec6a9 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/AllocObjCtxArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/AllocObjCtxArguments.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/GetParameterArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/GetParameterArguments.cs index 425e665f4..5e74f6f2c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/GetParameterArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/GetParameterArguments.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/MapCommandBufferArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/MapCommandBufferArguments.cs index 0777e6461..88cd6bd94 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/MapCommandBufferArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/MapCommandBufferArguments.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/NvChannelPriority.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/NvChannelPriority.cs index c267e2df9..ca9a791b4 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/NvChannelPriority.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/NvChannelPriority.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel +namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel { enum NvChannelPriority : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/SetErrorNotifierArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/SetErrorNotifierArguments.cs index 7e5a5e961..f285123a7 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/SetErrorNotifierArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/SetErrorNotifierArguments.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/SubmitArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/SubmitArguments.cs index 05c4280c2..0c4ea7625 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/SubmitArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/SubmitArguments.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/SubmitGpfifoArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/SubmitGpfifoArguments.cs index 1bb08da1b..b6bd1e4e8 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/SubmitGpfifoArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/SubmitGpfifoArguments.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Nv.Types; +using Ryujinx.HLE.HOS.Services.Nv.Types; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/SubmitGpfifoFlags.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/SubmitGpfifoFlags.cs index 1f0609804..23ead4739 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/SubmitGpfifoFlags.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/SubmitGpfifoFlags.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/ZcullBindArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/ZcullBindArguments.cs index 71b124667..fe4c74d66 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/ZcullBindArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/ZcullBindArguments.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/NvHostCtrlDeviceFile.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/NvHostCtrlDeviceFile.cs index 6142611e5..471bca73c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/NvHostCtrlDeviceFile.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/NvHostCtrlDeviceFile.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Graphics.Gpu.Synchronization; using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl.Types; using Ryujinx.HLE.HOS.Services.Nv.Types; diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/EventWaitArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/EventWaitArguments.cs index 84f678bab..0b2133a78 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/EventWaitArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/EventWaitArguments.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Nv.Types; +using Ryujinx.HLE.HOS.Services.Nv.Types; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/GetConfigurationArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/GetConfigurationArguments.cs index a1400f8ef..c94bb4ff1 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/GetConfigurationArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/GetConfigurationArguments.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/SyncptWaitArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/SyncptWaitArguments.cs index b0efb7eda..5138db9ea 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/SyncptWaitArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/SyncptWaitArguments.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Nv.Types; +using Ryujinx.HLE.HOS.Services.Nv.Types; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/SyncptWaitExArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/SyncptWaitExArguments.cs index 7471274ba..7bcd38c75 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/SyncptWaitExArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/SyncptWaitExArguments.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/NvHostCtrlGpuDeviceFile.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/NvHostCtrlGpuDeviceFile.cs index 23cf1f002..d287c6d9e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/NvHostCtrlGpuDeviceFile.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/NvHostCtrlGpuDeviceFile.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu.Types; using Ryujinx.Horizon.Common; diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/GetActiveSlotMaskArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/GetActiveSlotMaskArguments.cs index fd73be9e7..4f447f486 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/GetActiveSlotMaskArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/GetActiveSlotMaskArguments.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/GetCharacteristicsArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/GetCharacteristicsArguments.cs index 64bfbe88d..556786de0 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/GetCharacteristicsArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/GetCharacteristicsArguments.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/GetGpuTimeArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/GetGpuTimeArguments.cs index 084ef71fb..c1c1a6f91 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/GetGpuTimeArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/GetGpuTimeArguments.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/GetTpcMasksArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/GetTpcMasksArguments.cs index dafde6e55..83ff4f090 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/GetTpcMasksArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/GetTpcMasksArguments.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/ZbcSetTableArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/ZbcSetTableArguments.cs index 93c264332..cee339bac 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/ZbcSetTableArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/ZbcSetTableArguments.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/ZcullGetCtxSizeArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/ZcullGetCtxSizeArguments.cs index 1e668f867..16ffacdac 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/ZcullGetCtxSizeArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/ZcullGetCtxSizeArguments.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/ZcullGetInfoArguments.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/ZcullGetInfoArguments.cs index d0d152a3d..343643abf 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/ZcullGetInfoArguments.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrlGpu/Types/ZcullGetInfoArguments.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostDbgGpu/NvHostDbgGpuDeviceFile.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostDbgGpu/NvHostDbgGpuDeviceFile.cs index 667915787..44f01f8ad 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostDbgGpu/NvHostDbgGpuDeviceFile.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostDbgGpu/NvHostDbgGpuDeviceFile.cs @@ -1,4 +1,4 @@ -using Ryujinx.Memory; +using Ryujinx.Memory; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostDbgGpu { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostProfGpu/NvHostProfGpuDeviceFile.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostProfGpu/NvHostProfGpuDeviceFile.cs index 0a2087edc..db4112af2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostProfGpu/NvHostProfGpuDeviceFile.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostProfGpu/NvHostProfGpuDeviceFile.cs @@ -1,4 +1,4 @@ -using Ryujinx.Memory; +using Ryujinx.Memory; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostProfGpu { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvInternalResult.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvInternalResult.cs index c7746a556..c100c817b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvInternalResult.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvInternalResult.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices +namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices { enum NvInternalResult { diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/NvMapDeviceFile.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/NvMapDeviceFile.cs index 06df5f93c..6a0ac58bd 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/NvMapDeviceFile.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/NvMapDeviceFile.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.Graphics.Gpu.Memory; using Ryujinx.Memory; @@ -69,7 +69,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap return NvInternalResult.InvalidInput; } - int size = BitUtils.AlignUp(arguments.Size, (int)MemoryManager.PageSize); + uint size = BitUtils.AlignUp(arguments.Size, (uint)MemoryManager.PageSize); arguments.Handle = CreateHandleFromMap(new NvMapHandle(size)); @@ -128,7 +128,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap map.Align = arguments.Align; map.Kind = (byte)arguments.Kind; - int size = BitUtils.AlignUp(map.Size, (int)MemoryManager.PageSize); + uint size = BitUtils.AlignUp(map.Size, (uint)MemoryManager.PageSize); ulong address = arguments.Address; @@ -191,7 +191,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap switch (arguments.Param) { case NvMapHandleParam.Size: - arguments.Result = map.Size; + arguments.Result = (int)map.Size; break; case NvMapHandleParam.Align: arguments.Result = map.Align; diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/Types/NvMapCreate.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/Types/NvMapCreate.cs index 5380c45c7..f4047497a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/Types/NvMapCreate.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/Types/NvMapCreate.cs @@ -5,7 +5,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap [StructLayout(LayoutKind.Sequential)] struct NvMapCreate { - public int Size; + public uint Size; public int Handle; } } diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/Types/NvMapFree.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/Types/NvMapFree.cs index b0b3fa2d6..ce93e9e5e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/Types/NvMapFree.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/Types/NvMapFree.cs @@ -8,7 +8,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap public int Handle; public int Padding; public ulong Address; - public int Size; + public uint Size; public int Flags; } } diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/Types/NvMapHandle.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/Types/NvMapHandle.cs index 301179747..e821b571d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/Types/NvMapHandle.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/Types/NvMapHandle.cs @@ -8,7 +8,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap public int Handle; public int Id; #pragma warning restore CS0649 - public int Size; + public uint Size; public int Align; public int Kind; public ulong Address; @@ -22,7 +22,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap _dupes = 1; } - public NvMapHandle(int size) : this() + public NvMapHandle(uint size) : this() { Size = size; } diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvIoctl.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvIoctl.cs index c9218e677..40e35fa7a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvIoctl.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvIoctl.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvMemoryAllocator.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvMemoryAllocator.cs index 66c953a2d..4e8193302 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/NvMemoryAllocator.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvMemoryAllocator.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Collections; +using Ryujinx.Common.Collections; using Ryujinx.Common.Logging; using Ryujinx.Graphics.Gpu.Memory; using System; diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/Types/NvFence.cs b/src/Ryujinx.HLE/HOS/Services/Nv/Types/NvFence.cs index 5af613cd6..214987e96 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/Types/NvFence.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/Types/NvFence.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Gpu; +using Ryujinx.Graphics.Gpu; using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl; using System; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/Types/NvIoctlNotImplementedException.cs b/src/Ryujinx.HLE/HOS/Services/Nv/Types/NvIoctlNotImplementedException.cs index 7af7e5337..e05e32aad 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/Types/NvIoctlNotImplementedException.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/Types/NvIoctlNotImplementedException.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices; +using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices; using System; using System.Text; diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/Types/NvQueryEventNotImplementedException.cs b/src/Ryujinx.HLE/HOS/Services/Nv/Types/NvQueryEventNotImplementedException.cs index 844bce135..f9e826fc7 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/Types/NvQueryEventNotImplementedException.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/Types/NvQueryEventNotImplementedException.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices; +using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices; using System; using System.Text; diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/Types/NvStatus.cs b/src/Ryujinx.HLE/HOS/Services/Nv/Types/NvStatus.cs index ad4f70354..645a8433a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/Types/NvStatus.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/Types/NvStatus.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Nv.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Olsc/IOlscServiceForApplication.cs b/src/Ryujinx.HLE/HOS/Services/Olsc/IOlscServiceForApplication.cs index 073e9b1b9..1513d6fed 100644 --- a/src/Ryujinx.HLE/HOS/Services/Olsc/IOlscServiceForApplication.cs +++ b/src/Ryujinx.HLE/HOS/Services/Olsc/IOlscServiceForApplication.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Account.Acc; using System.Collections.Generic; diff --git a/src/Ryujinx.HLE/HOS/Services/Olsc/IOlscServiceForSystemService.cs b/src/Ryujinx.HLE/HOS/Services/Olsc/IOlscServiceForSystemService.cs index 27ac6b9cf..c6e372052 100644 --- a/src/Ryujinx.HLE/HOS/Services/Olsc/IOlscServiceForSystemService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Olsc/IOlscServiceForSystemService.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Olsc +namespace Ryujinx.HLE.HOS.Services.Olsc { [Service("olsc:s")] // 4.0.0+ class IOlscServiceForSystemService : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Pcie/ILogManager.cs b/src/Ryujinx.HLE/HOS/Services/Pcie/ILogManager.cs index 78f927aa4..4812727b1 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pcie/ILogManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pcie/ILogManager.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Pcie +namespace Ryujinx.HLE.HOS.Services.Pcie { [Service("pcie:log")] class ILogManager : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Pcie/IManager.cs b/src/Ryujinx.HLE/HOS/Services/Pcie/IManager.cs index 0450a1ca4..42e480355 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pcie/IManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pcie/IManager.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Pcie +namespace Ryujinx.HLE.HOS.Services.Pcie { [Service("pcie")] class IManager : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Pctl/ParentalControlServiceFactory/IParentalControlService.cs b/src/Ryujinx.HLE/HOS/Services/Pctl/ParentalControlServiceFactory/IParentalControlService.cs index cf8c1f78d..9b026a1c3 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pctl/ParentalControlServiceFactory/IParentalControlService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pctl/ParentalControlServiceFactory/IParentalControlService.cs @@ -159,9 +159,7 @@ namespace Ryujinx.HLE.HOS.Services.Pctl.ParentalControlServiceFactory } else { -#pragma warning disable CS0162 // Unreachable code return ResultCode.StereoVisionRestrictionConfigurableDisabled; -#pragma warning restore CS0162 } } diff --git a/src/Ryujinx.HLE/HOS/Services/Pctl/ResultCode.cs b/src/Ryujinx.HLE/HOS/Services/Pctl/ResultCode.cs index 86ff88142..c3d157ed4 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pctl/ResultCode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pctl/ResultCode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Pctl +namespace Ryujinx.HLE.HOS.Services.Pctl { enum ResultCode { diff --git a/src/Ryujinx.HLE/HOS/Services/Pcv/Bpc/IBoardPowerControlManager.cs b/src/Ryujinx.HLE/HOS/Services/Pcv/Bpc/IBoardPowerControlManager.cs index e078de39a..26fd86908 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pcv/Bpc/IBoardPowerControlManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pcv/Bpc/IBoardPowerControlManager.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Pcv.Bpc +namespace Ryujinx.HLE.HOS.Services.Pcv.Bpc { [Service("bpc")] class IBoardPowerControlManager : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Pcv/Bpc/IRtcManager.cs b/src/Ryujinx.HLE/HOS/Services/Pcv/Bpc/IRtcManager.cs index e185c4787..c37176845 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pcv/Bpc/IRtcManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pcv/Bpc/IRtcManager.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Pcv.Bpc { diff --git a/src/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/ClkrstManager/IClkrstSession.cs b/src/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/ClkrstManager/IClkrstSession.cs index a3ca56bf2..ddc4e5c7d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/ClkrstManager/IClkrstSession.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/ClkrstManager/IClkrstSession.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Pcv.Types; using System.Linq; diff --git a/src/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/IArbitrationManager.cs b/src/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/IArbitrationManager.cs index 492ffa57a..4c7e33003 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/IArbitrationManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/IArbitrationManager.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Pcv.Clkrst +namespace Ryujinx.HLE.HOS.Services.Pcv.Clkrst { [Service("clkrst:a")] // 8.0.0+ class IArbitrationManager : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/IClkrstManager.cs b/src/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/IClkrstManager.cs index 2e18dba74..c7c459196 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/IClkrstManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/IClkrstManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Ipc; +using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Services.Pcv.Clkrst.ClkrstManager; using Ryujinx.HLE.HOS.Services.Pcv.Types; using Ryujinx.Horizon.Common; diff --git a/src/Ryujinx.HLE/HOS/Services/Pcv/IPcvService.cs b/src/Ryujinx.HLE/HOS/Services/Pcv/IPcvService.cs index 5fd8493c9..d25a71b86 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pcv/IPcvService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pcv/IPcvService.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Pcv +namespace Ryujinx.HLE.HOS.Services.Pcv { [Service("pcv")] class IPcvService : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Pcv/Rgltr/IRegulatorManager.cs b/src/Ryujinx.HLE/HOS/Services/Pcv/Rgltr/IRegulatorManager.cs index 9a7d8a098..5a290e42c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pcv/Rgltr/IRegulatorManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pcv/Rgltr/IRegulatorManager.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Pcv.Rgltr +namespace Ryujinx.HLE.HOS.Services.Pcv.Rgltr { [Service("rgltr")] // 8.0.0+ class IRegulatorManager : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Pcv/Rtc/IRtcManager.cs b/src/Ryujinx.HLE/HOS/Services/Pcv/Rtc/IRtcManager.cs index 6e255a1dd..460a7cc76 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pcv/Rtc/IRtcManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pcv/Rtc/IRtcManager.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Pcv.Rtc +namespace Ryujinx.HLE.HOS.Services.Pcv.Rtc { [Service("rtc")] // 8.0.0+ class IRtcManager : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Pcv/Types/DeviceCode.cs b/src/Ryujinx.HLE/HOS/Services/Pcv/Types/DeviceCode.cs index 79f13dbdf..7aa95b21d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pcv/Types/DeviceCode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pcv/Types/DeviceCode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Pcv.Types +namespace Ryujinx.HLE.HOS.Services.Pcv.Types { enum DeviceCode { diff --git a/src/Ryujinx.HLE/HOS/Services/Pm/IBootModeInterface.cs b/src/Ryujinx.HLE/HOS/Services/Pm/IBootModeInterface.cs index 473f74135..1f1aafc16 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pm/IBootModeInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pm/IBootModeInterface.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Pm +namespace Ryujinx.HLE.HOS.Services.Pm { [Service("pm:bm")] class IBootModeInterface : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Pm/IDebugMonitorInterface.cs b/src/Ryujinx.HLE/HOS/Services/Pm/IDebugMonitorInterface.cs index 82190b047..9becc6e46 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pm/IDebugMonitorInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pm/IDebugMonitorInterface.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Ipc; +using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Kernel; using Ryujinx.HLE.HOS.Kernel.Process; using Ryujinx.Horizon.Common; diff --git a/src/Ryujinx.HLE/HOS/Services/Pm/IInformationInterface.cs b/src/Ryujinx.HLE/HOS/Services/Pm/IInformationInterface.cs index 500d121ea..d6440a4d1 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pm/IInformationInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pm/IInformationInterface.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Kernel.Process; +using Ryujinx.HLE.HOS.Kernel.Process; namespace Ryujinx.HLE.HOS.Services.Pm { diff --git a/src/Ryujinx.HLE/HOS/Services/Pm/IShellInterface.cs b/src/Ryujinx.HLE/HOS/Services/Pm/IShellInterface.cs index 962023264..1ee2c377f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pm/IShellInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pm/IShellInterface.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Pm +namespace Ryujinx.HLE.HOS.Services.Pm { [Service("pm:shell")] class IShellInterface : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Ptm/Fan/IManager.cs b/src/Ryujinx.HLE/HOS/Services/Ptm/Fan/IManager.cs index 8011f9193..4498fe0d7 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ptm/Fan/IManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ptm/Fan/IManager.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ptm.Fan +namespace Ryujinx.HLE.HOS.Services.Ptm.Fan { [Service("fan")] class IManager : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Ptm/Fgm/IDebugger.cs b/src/Ryujinx.HLE/HOS/Services/Ptm/Fgm/IDebugger.cs index 8cb671bc3..a9ce42e74 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ptm/Fgm/IDebugger.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ptm/Fgm/IDebugger.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ptm.Fgm +namespace Ryujinx.HLE.HOS.Services.Ptm.Fgm { [Service("fgm:dbg")] // 9.0.0+ class IDebugger : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Ptm/Fgm/ISession.cs b/src/Ryujinx.HLE/HOS/Services/Ptm/Fgm/ISession.cs index 1488c2886..6373ab2d2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ptm/Fgm/ISession.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ptm/Fgm/ISession.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ptm.Fgm +namespace Ryujinx.HLE.HOS.Services.Ptm.Fgm { [Service("fgm")] // 9.0.0+ [Service("fgm:0")] // 9.0.0+ diff --git a/src/Ryujinx.HLE/HOS/Services/Ptm/Pcm/IManager.cs b/src/Ryujinx.HLE/HOS/Services/Ptm/Pcm/IManager.cs index 53f3bc391..e05035ac2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ptm/Pcm/IManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ptm/Pcm/IManager.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ptm.Pcm +namespace Ryujinx.HLE.HOS.Services.Ptm.Pcm { [Service("pcm")] class IManager : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Ptm/Psm/IPsmServer.cs b/src/Ryujinx.HLE/HOS/Services/Ptm/Psm/IPsmServer.cs index 0c475150b..3ce502974 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ptm/Psm/IPsmServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ptm/Psm/IPsmServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; namespace Ryujinx.HLE.HOS.Services.Ptm.Psm { diff --git a/src/Ryujinx.HLE/HOS/Services/Ptm/Psm/IPsmSession.cs b/src/Ryujinx.HLE/HOS/Services/Ptm/Psm/IPsmSession.cs index a603b7e41..edfa60afd 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ptm/Psm/IPsmSession.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ptm/Psm/IPsmSession.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.Horizon.Common; diff --git a/src/Ryujinx.HLE/HOS/Services/Ptm/Psm/Types/ChargerType.cs b/src/Ryujinx.HLE/HOS/Services/Ptm/Psm/Types/ChargerType.cs index a0b0c3dd4..5b6ee42d2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ptm/Psm/Types/ChargerType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ptm/Psm/Types/ChargerType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ptm.Psm +namespace Ryujinx.HLE.HOS.Services.Ptm.Psm { enum ChargerType { diff --git a/src/Ryujinx.HLE/HOS/Services/Ptm/Tc/IManager.cs b/src/Ryujinx.HLE/HOS/Services/Ptm/Tc/IManager.cs index 0317e532b..0342a15b5 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ptm/Tc/IManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ptm/Tc/IManager.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ptm.Tc +namespace Ryujinx.HLE.HOS.Services.Ptm.Tc { [Service("tc")] class IManager : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Ptm/Ts/IMeasurementServer.cs b/src/Ryujinx.HLE/HOS/Services/Ptm/Ts/IMeasurementServer.cs index 07a067688..66ffd0a49 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ptm/Ts/IMeasurementServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ptm/Ts/IMeasurementServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Ptm.Ts.Types; namespace Ryujinx.HLE.HOS.Services.Ptm.Ts diff --git a/src/Ryujinx.HLE/HOS/Services/Ptm/Ts/Types/Location.cs b/src/Ryujinx.HLE/HOS/Services/Ptm/Ts/Types/Location.cs index c04db09ce..409188a97 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ptm/Ts/Types/Location.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ptm/Ts/Types/Location.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ptm.Ts.Types +namespace Ryujinx.HLE.HOS.Services.Ptm.Ts.Types { enum Location : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Ro/IRoInterface.cs b/src/Ryujinx.HLE/HOS/Services/Ro/IRoInterface.cs index 3f31fe9f8..5b5b3bf84 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ro/IRoInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ro/IRoInterface.cs @@ -1,4 +1,4 @@ -using LibHac.Tools.FsSystem; +using LibHac.Tools.FsSystem; using Ryujinx.Common; using Ryujinx.Cpu; using Ryujinx.HLE.HOS.Kernel.Memory; diff --git a/src/Ryujinx.HLE/HOS/Services/Ro/ResultCode.cs b/src/Ryujinx.HLE/HOS/Services/Ro/ResultCode.cs index 1e31e5760..911140342 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ro/ResultCode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ro/ResultCode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ro +namespace Ryujinx.HLE.HOS.Services.Ro { enum ResultCode { diff --git a/src/Ryujinx.HLE/HOS/Services/Ro/Types/NroInfo.cs b/src/Ryujinx.HLE/HOS/Services/Ro/Types/NroInfo.cs index fd4947c6f..4df2793f1 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ro/Types/NroInfo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ro/Types/NroInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.Loaders.Executables; +using Ryujinx.HLE.Loaders.Executables; namespace Ryujinx.HLE.HOS.Services.Ro { diff --git a/src/Ryujinx.HLE/HOS/Services/Ro/Types/NrrInfo.cs b/src/Ryujinx.HLE/HOS/Services/Ro/Types/NrrInfo.cs index b322c06ed..1f394d921 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ro/Types/NrrInfo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ro/Types/NrrInfo.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace Ryujinx.HLE.HOS.Services.Ro { diff --git a/src/Ryujinx.HLE/HOS/Services/Sdb/Avm/IAvmService.cs b/src/Ryujinx.HLE/HOS/Services/Sdb/Avm/IAvmService.cs index ec312108b..9c6ed5c37 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sdb/Avm/IAvmService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sdb/Avm/IAvmService.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Am.Tcap +namespace Ryujinx.HLE.HOS.Services.Am.Tcap { [Service("avm")] // 6.0.0+ class IAvmService : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/INotifyService.cs b/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/INotifyService.cs index c2e042901..208847cc7 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/INotifyService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/INotifyService.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm +namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm { [Service("pdm:ntfy")] class INotifyService : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/IQueryService.cs b/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/IQueryService.cs index c46050b85..6508794ab 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/IQueryService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/IQueryService.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService; +using Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService; namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm { diff --git a/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs b/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs index 7017cc50c..56d389cd2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Cpu; using Ryujinx.HLE.HOS.Services.Account.Acc; using Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService.Types; diff --git a/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/Types/ApplicationPlayStatistics.cs b/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/Types/ApplicationPlayStatistics.cs index b58fd2191..8bfb75c74 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/Types/ApplicationPlayStatistics.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/Types/ApplicationPlayStatistics.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/Types/PlayLogQueryCapability.cs b/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/Types/PlayLogQueryCapability.cs index c1e77ed3b..a4fd3ca92 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/Types/PlayLogQueryCapability.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/Types/PlayLogQueryCapability.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService.Types +namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService.Types { enum PlayLogQueryCapability { diff --git a/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/ResultCode.cs b/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/ResultCode.cs index dd20220f2..85167227a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/ResultCode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/ResultCode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm +namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm { enum ResultCode { diff --git a/src/Ryujinx.HLE/HOS/Services/ServerBase.cs b/src/Ryujinx.HLE/HOS/Services/ServerBase.cs index e892d6ab6..5e18d7981 100644 --- a/src/Ryujinx.HLE/HOS/Services/ServerBase.cs +++ b/src/Ryujinx.HLE/HOS/Services/ServerBase.cs @@ -287,6 +287,10 @@ namespace Ryujinx.HLE.HOS.Services _wakeEvent.WritableEvent.Clear(); } } + else if (rc == KernelResult.PortRemoteClosed && signaledIndex >= 0 && SmObjectFactory != null) + { + DestroySession(handles[signaledIndex]); + } _selfProcess.CpuMemory.Write(messagePtr + 0x0, 0); _selfProcess.CpuMemory.Write(messagePtr + 0x4, 2 << 10); @@ -299,6 +303,16 @@ namespace Ryujinx.HLE.HOS.Services Dispose(); } + private void DestroySession(int serverSessionHandle) + { + _context.Syscall.CloseHandle(serverSessionHandle); + + if (RemoveSessionObj(serverSessionHandle, out var session)) + { + (session as IDisposable)?.Dispose(); + } + } + private bool Process(int serverSessionHandle, ulong recvListAddr) { IpcMessage request = ReadRequest(); @@ -360,7 +374,7 @@ namespace Ryujinx.HLE.HOS.Services response.RawData = _responseDataStream.ToArray(); } else if (request.Type == IpcMessageType.CmifControl || - request.Type == IpcMessageType.CmifControlWithContext) + request.Type == IpcMessageType.CmifControlWithContext) { #pragma warning disable IDE0059 // Remove unnecessary value assignment uint magic = (uint)_requestDataReader.ReadUInt64(); @@ -412,11 +426,7 @@ namespace Ryujinx.HLE.HOS.Services } else if (request.Type == IpcMessageType.CmifCloseSession || request.Type == IpcMessageType.TipcCloseSession) { - _context.Syscall.CloseHandle(serverSessionHandle); - if (RemoveSessionObj(serverSessionHandle, out var session)) - { - (session as IDisposable)?.Dispose(); - } + DestroySession(serverSessionHandle); shouldReply = false; } // If the type is past 0xF, we are using TIPC diff --git a/src/Ryujinx.HLE/HOS/Services/ServiceAttributes.cs b/src/Ryujinx.HLE/HOS/Services/ServiceAttributes.cs index c625af487..112563eb8 100644 --- a/src/Ryujinx.HLE/HOS/Services/ServiceAttributes.cs +++ b/src/Ryujinx.HLE/HOS/Services/ServiceAttributes.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services { diff --git a/src/Ryujinx.HLE/HOS/Services/Settings/IFactorySettingsServer.cs b/src/Ryujinx.HLE/HOS/Services/Settings/IFactorySettingsServer.cs index 174a1c981..aceb28c1f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Settings/IFactorySettingsServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Settings/IFactorySettingsServer.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Am.Tcap +namespace Ryujinx.HLE.HOS.Services.Am.Tcap { [Service("set:cal")] class IFactorySettingsServer : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Settings/IFirmwareDebugSettingsServer.cs b/src/Ryujinx.HLE/HOS/Services/Settings/IFirmwareDebugSettingsServer.cs index 7368cf441..61e366dae 100644 --- a/src/Ryujinx.HLE/HOS/Services/Settings/IFirmwareDebugSettingsServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Settings/IFirmwareDebugSettingsServer.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Settings +namespace Ryujinx.HLE.HOS.Services.Settings { [Service("set:fd")] class IFirmwareDebugSettingsServer : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Settings/ResultCode.cs b/src/Ryujinx.HLE/HOS/Services/Settings/ResultCode.cs index 9d4678091..e925361e9 100644 --- a/src/Ryujinx.HLE/HOS/Services/Settings/ResultCode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Settings/ResultCode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Settings +namespace Ryujinx.HLE.HOS.Services.Settings { enum ResultCode { diff --git a/src/Ryujinx.HLE/HOS/Services/Settings/Types/PlatformRegion.cs b/src/Ryujinx.HLE/HOS/Services/Settings/Types/PlatformRegion.cs index 3953c050c..9bddc4847 100644 --- a/src/Ryujinx.HLE/HOS/Services/Settings/Types/PlatformRegion.cs +++ b/src/Ryujinx.HLE/HOS/Services/Settings/Types/PlatformRegion.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Settings.Types +namespace Ryujinx.HLE.HOS.Services.Settings.Types { enum PlatformRegion { diff --git a/src/Ryujinx.HLE/HOS/Services/Sm/IManagerInterface.cs b/src/Ryujinx.HLE/HOS/Services/Sm/IManagerInterface.cs index 412a33246..5733a49b6 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sm/IManagerInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sm/IManagerInterface.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sm +namespace Ryujinx.HLE.HOS.Services.Sm { [Service("sm:m")] class IManagerInterface : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/BsdContext.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/BsdContext.cs index 254ad6675..7ecd6835d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/BsdContext.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/BsdContext.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; +using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs index d16e7536e..1e8a90051 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl; using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; @@ -121,7 +121,14 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd { IPEndPoint endPoint = isRemote ? socket.RemoteEndPoint : socket.LocalEndPoint; - context.Memory.Write(bufferPosition, BsdSockAddr.FromIPEndPoint(endPoint)); + if (endPoint != null) + { + context.Memory.Write(bufferPosition, BsdSockAddr.FromIPEndPoint(endPoint)); + } + else + { + context.Memory.Write(bufferPosition, new BsdSockAddr()); + } } [CommandCmif(0)] diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IFileDescriptor.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IFileDescriptor.cs index dbeb90222..6c00d5e11 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IFileDescriptor.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IFileDescriptor.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; +using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; using System; namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/ISocket.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/ISocket.cs index e04a35954..fe2f8477f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/ISocket.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/ISocket.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; +using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; using System; using System.Net; using System.Net.Sockets; diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs index 937d2fd70..5b9e6811d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; +using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; using System; using System.Runtime.InteropServices; using System.Threading; diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptorPollManager.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptorPollManager.cs index 9039d49a7..a29554c35 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptorPollManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptorPollManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; using System.Collections.Generic; using System.Threading; diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/ManagedSocket.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/ManagedSocket.cs index 2d8fce1df..c42b7201b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/ManagedSocket.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/ManagedSocket.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/ManagedSocketPollManager.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/ManagedSocketPollManager.cs index 10d9882c1..d0db44086 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/ManagedSocketPollManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/ManagedSocketPollManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; using System.Collections.Generic; using System.Net.Sockets; diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/WSAError.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/WSAError.cs index 5f3495df5..cd8e530c7 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/WSAError.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/WSAError.cs @@ -1,4 +1,4 @@ -using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.CodeAnalysis; namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl { diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/ServerInterface.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/ServerInterface.cs index 9afdf2503..edf9d351b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/ServerInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/ServerInterface.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd { [Service("bsdcfg")] class ServerInterface : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdAddressFamily.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdAddressFamily.cs index 747946386..6bc27ffbd 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdAddressFamily.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdAddressFamily.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { enum BsdAddressFamily : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdIoctl.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdIoctl.cs index 9c330e35d..d38bd02b8 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdIoctl.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdIoctl.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { enum BsdIoctl { diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdMMsgHdr.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdMMsgHdr.cs index f97b8f5be..75f869b6b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdMMsgHdr.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdMMsgHdr.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdMsgHdr.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdMsgHdr.cs index 62a7ccb59..6b6617e21 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdMsgHdr.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdMsgHdr.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSockAddr.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSockAddr.cs index af3a44e88..0dc76fc7e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSockAddr.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSockAddr.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System; using System.Net; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketCreationFlags.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketCreationFlags.cs index ac79deb31..0abd424ee 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketCreationFlags.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketCreationFlags.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketShutdownFlags.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketShutdownFlags.cs index 883e3c31f..4a0478974 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketShutdownFlags.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketShutdownFlags.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { enum BsdSocketShutdownFlags { diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketType.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketType.cs index b54c78863..2938ebe7e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { enum BsdSocketType { diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/EventFdFlags.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/EventFdFlags.cs index 996facd35..c21a997bf 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/EventFdFlags.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/EventFdFlags.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/IPollManager.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/IPollManager.cs index 66b1bcf1b..f6f47dafa 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/IPollManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/IPollManager.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEvent.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEvent.cs index 27a96bd81..b6fd3e324 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEvent.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEvent.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { class PollEvent { diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEventData.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEventData.cs index 16d01055c..3babb0018 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEventData.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEventData.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { struct PollEventData { diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEventTypeMask.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEventTypeMask.cs index d4c96c81f..da47d60a2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEventTypeMask.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEventTypeMask.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/TimeVal.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/TimeVal.cs index 690a63aeb..bff30b049 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/TimeVal.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/TimeVal.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { public struct TimeVal { diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Ethc/IEthInterface.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Ethc/IEthInterface.cs index 1c216ea58..f57662644 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Ethc/IEthInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Ethc/IEthInterface.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Ethc +namespace Ryujinx.HLE.HOS.Services.Sockets.Ethc { [Service("ethc:c")] class IEthInterface : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Ethc/IEthInterfaceGroup.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Ethc/IEthInterfaceGroup.cs index 3147a8928..527b6dd04 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Ethc/IEthInterfaceGroup.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Ethc/IEthInterfaceGroup.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Ethc +namespace Ryujinx.HLE.HOS.Services.Sockets.Ethc { [Service("ethc:i")] class IEthInterfaceGroup : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs index c991db3fb..0c1fa3a9f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Cpu; using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Services.Settings; diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs index a8fbcf092..2ec0f744e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs @@ -1,4 +1,4 @@ -using System.Text; +using System.Text; namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager { diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Types/ApplicationServerEnvironmentType.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Types/ApplicationServerEnvironmentType.cs index 1acb69fce..bc10499ce 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Types/ApplicationServerEnvironmentType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Types/ApplicationServerEnvironmentType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Types +namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Types { enum ApplicationServerEnvironmentType : byte { diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Types/NsdSettings.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Types/NsdSettings.cs index 08fb15e0a..8b37c9fc8 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Types/NsdSettings.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Types/NsdSettings.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd { class NsdSettings { diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Proxy/DnsBlacklist.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Proxy/DnsBlacklist.cs index a2ccd190e..608ea2f51 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Proxy/DnsBlacklist.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Proxy/DnsBlacklist.cs @@ -1,4 +1,4 @@ -using System.Text.RegularExpressions; +using System.Text.RegularExpressions; namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Proxy { diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/AddrInfo4.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/AddrInfo4.cs index 68250022e..de839e3a0 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/AddrInfo4.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/AddrInfo4.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System; using System.Net; using System.Net.Sockets; diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/AddrInfoSerialized.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/AddrInfoSerialized.cs index b57b0d5ca..471c274ca 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/AddrInfoSerialized.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/AddrInfoSerialized.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.HLE.Utilities; using System; using System.Diagnostics; diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/AddrInfoSerializedHeader.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/AddrInfoSerializedHeader.cs index 9c50b1b86..8415382ae 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/AddrInfoSerializedHeader.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/AddrInfoSerializedHeader.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Net; using System.Net.Sockets; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/GaiError.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/GaiError.cs index 46682b3c8..81326c7f8 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/GaiError.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/GaiError.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres +namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres { enum GaiError { diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/NetDBError.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/NetDBError.cs index 0ded59603..8fc30261c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/NetDBError.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/NetDBError.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres +namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres { enum NetDbError { diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/SfdnsresContants.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/SfdnsresContants.cs index 7c51413cf..8af70224f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/SfdnsresContants.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/SfdnsresContants.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Types +namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Types { class SfdnsresContants { diff --git a/src/Ryujinx.HLE/HOS/Services/Spl/IGeneralInterface.cs b/src/Ryujinx.HLE/HOS/Services/Spl/IGeneralInterface.cs index 951ed5301..4a2a910f8 100644 --- a/src/Ryujinx.HLE/HOS/Services/Spl/IGeneralInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Spl/IGeneralInterface.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.FileSystem; +using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.HOS.Kernel.Common; using Ryujinx.HLE.HOS.Services.Spl.Types; diff --git a/src/Ryujinx.HLE/HOS/Services/Spl/IRandomInterface.cs b/src/Ryujinx.HLE/HOS/Services/Spl/IRandomInterface.cs index 922fd34a6..fc58613f5 100644 --- a/src/Ryujinx.HLE/HOS/Services/Spl/IRandomInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Spl/IRandomInterface.cs @@ -1,4 +1,4 @@ -using System.Security.Cryptography; +using System.Security.Cryptography; namespace Ryujinx.HLE.HOS.Services.Spl { diff --git a/src/Ryujinx.HLE/HOS/Services/Spl/Types/ConfigItem.cs b/src/Ryujinx.HLE/HOS/Services/Spl/Types/ConfigItem.cs index 6822ad134..ec5da24a5 100644 --- a/src/Ryujinx.HLE/HOS/Services/Spl/Types/ConfigItem.cs +++ b/src/Ryujinx.HLE/HOS/Services/Spl/Types/ConfigItem.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Spl.Types +namespace Ryujinx.HLE.HOS.Services.Spl.Types { enum ConfigItem { diff --git a/src/Ryujinx.HLE/HOS/Services/Spl/Types/DramId.cs b/src/Ryujinx.HLE/HOS/Services/Spl/Types/DramId.cs index 05a465571..7a53ee112 100644 --- a/src/Ryujinx.HLE/HOS/Services/Spl/Types/DramId.cs +++ b/src/Ryujinx.HLE/HOS/Services/Spl/Types/DramId.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Spl.Types +namespace Ryujinx.HLE.HOS.Services.Spl.Types { enum DramId { diff --git a/src/Ryujinx.HLE/HOS/Services/Spl/Types/HardwareState.cs b/src/Ryujinx.HLE/HOS/Services/Spl/Types/HardwareState.cs index 8ab0ba9b0..de37f591e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Spl/Types/HardwareState.cs +++ b/src/Ryujinx.HLE/HOS/Services/Spl/Types/HardwareState.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Spl.Types +namespace Ryujinx.HLE.HOS.Services.Spl.Types { enum HardwareState { diff --git a/src/Ryujinx.HLE/HOS/Services/Spl/Types/HardwareType.cs b/src/Ryujinx.HLE/HOS/Services/Spl/Types/HardwareType.cs index 82d733308..2a1e0d8c5 100644 --- a/src/Ryujinx.HLE/HOS/Services/Spl/Types/HardwareType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Spl/Types/HardwareType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Spl.Types +namespace Ryujinx.HLE.HOS.Services.Spl.Types { enum HardwareType { diff --git a/src/Ryujinx.HLE/HOS/Services/Spl/Types/SmcResult.cs b/src/Ryujinx.HLE/HOS/Services/Spl/Types/SmcResult.cs index ade0378c5..13bdeccc7 100644 --- a/src/Ryujinx.HLE/HOS/Services/Spl/Types/SmcResult.cs +++ b/src/Ryujinx.HLE/HOS/Services/Spl/Types/SmcResult.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Spl.Types +namespace Ryujinx.HLE.HOS.Services.Spl.Types { enum SmcResult { diff --git a/src/Ryujinx.HLE/HOS/Services/Ssl/BuiltInCertificateManager.cs b/src/Ryujinx.HLE/HOS/Services/Ssl/BuiltInCertificateManager.cs index e31092fda..5d2e06a4f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ssl/BuiltInCertificateManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ssl/BuiltInCertificateManager.cs @@ -1,4 +1,4 @@ -using LibHac; +using LibHac; using LibHac.Common; using LibHac.Fs; using LibHac.Fs.Fsa; diff --git a/src/Ryujinx.HLE/HOS/Services/Ssl/ResultCode.cs b/src/Ryujinx.HLE/HOS/Services/Ssl/ResultCode.cs index 6aae11feb..e23621d0a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ssl/ResultCode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ssl/ResultCode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ssl +namespace Ryujinx.HLE.HOS.Services.Ssl { public enum ResultCode { diff --git a/src/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslConnectionBase.cs b/src/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslConnectionBase.cs index 500e2b896..93d85a262 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslConnectionBase.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslConnectionBase.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Sockets.Bsd; +using Ryujinx.HLE.HOS.Services.Sockets.Bsd; using System; namespace Ryujinx.HLE.HOS.Services.Ssl.SslService diff --git a/src/Ryujinx.HLE/HOS/Services/Ssl/SslService/SslManagedSocketConnection.cs b/src/Ryujinx.HLE/HOS/Services/Ssl/SslService/SslManagedSocketConnection.cs index e3c05df51..8cc761baf 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ssl/SslService/SslManagedSocketConnection.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ssl/SslService/SslManagedSocketConnection.cs @@ -1,8 +1,9 @@ -using Ryujinx.HLE.HOS.Services.Sockets.Bsd; +using Ryujinx.HLE.HOS.Services.Sockets.Bsd; using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl; using Ryujinx.HLE.HOS.Services.Ssl.Types; using System; using System.IO; +using System.Net; using System.Net.Security; using System.Net.Sockets; using System.Security.Authentication; @@ -83,10 +84,40 @@ namespace Ryujinx.HLE.HOS.Services.Ssl.SslService } #pragma warning restore SYSLIB0039 + /// + /// Retrieve the hostname of the current remote in case the provided hostname is null or empty. + /// + /// The current hostname + /// Either the resolved or provided hostname + /// + /// This is done to avoid getting an + /// as the remote certificate will be rejected with RemoteCertificateNameMismatch due to an empty hostname. + /// This is not what the switch does! + /// It might just skip remote hostname verification if the hostname wasn't set with before. + /// TODO: Remove this as soon as we know how the switch deals with empty hostnames + /// + private string RetrieveHostName(string hostName) + { + if (!string.IsNullOrEmpty(hostName)) + { + return hostName; + } + + try + { + return Dns.GetHostEntry(Socket.RemoteEndPoint.Address).HostName; + } + catch (SocketException) + { + return hostName; + } + } + public ResultCode Handshake(string hostName) { StartSslOperation(); _stream = new SslStream(new NetworkStream(((ManagedSocket)Socket).Socket, false), false, null, null); + hostName = RetrieveHostName(hostName); _stream.AuthenticateAsClient(hostName, null, TranslateSslVersion(_sslVersion), false); EndSslOperation(); diff --git a/src/Ryujinx.HLE/HOS/Services/Ssl/Types/BuiltInCertificateInfo.cs b/src/Ryujinx.HLE/HOS/Services/Ssl/Types/BuiltInCertificateInfo.cs index 313220e17..1d7029f7c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ssl/Types/BuiltInCertificateInfo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ssl/Types/BuiltInCertificateInfo.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ssl.Types +namespace Ryujinx.HLE.HOS.Services.Ssl.Types { struct BuiltInCertificateInfo { diff --git a/src/Ryujinx.HLE/HOS/Services/Ssl/Types/CaCertificateId.cs b/src/Ryujinx.HLE/HOS/Services/Ssl/Types/CaCertificateId.cs index a351ce545..2bf061717 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ssl/Types/CaCertificateId.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ssl/Types/CaCertificateId.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ssl.Types +namespace Ryujinx.HLE.HOS.Services.Ssl.Types { enum CaCertificateId : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Ssl/Types/CertificateFormat.cs b/src/Ryujinx.HLE/HOS/Services/Ssl/Types/CertificateFormat.cs index 35842e85b..0b3d4c3bc 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ssl/Types/CertificateFormat.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ssl/Types/CertificateFormat.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ssl.Types +namespace Ryujinx.HLE.HOS.Services.Ssl.Types { enum CertificateFormat : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Ssl/Types/IoMode.cs b/src/Ryujinx.HLE/HOS/Services/Ssl/Types/IoMode.cs index c8b3889c5..b42bccaa1 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ssl/Types/IoMode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ssl/Types/IoMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ssl.Types +namespace Ryujinx.HLE.HOS.Services.Ssl.Types { enum IoMode : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Ssl/Types/OptionType.cs b/src/Ryujinx.HLE/HOS/Services/Ssl/Types/OptionType.cs index 85a813dca..8d0e0b573 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ssl/Types/OptionType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ssl/Types/OptionType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ssl.Types +namespace Ryujinx.HLE.HOS.Services.Ssl.Types { enum OptionType : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Ssl/Types/SessionCacheMode.cs b/src/Ryujinx.HLE/HOS/Services/Ssl/Types/SessionCacheMode.cs index b9c739376..d2f236b00 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ssl/Types/SessionCacheMode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ssl/Types/SessionCacheMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ssl.Types +namespace Ryujinx.HLE.HOS.Services.Ssl.Types { enum SessionCacheMode : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Ssl/Types/SslVersion.cs b/src/Ryujinx.HLE/HOS/Services/Ssl/Types/SslVersion.cs index 7026596e5..2cbb0089f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ssl/Types/SslVersion.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ssl/Types/SslVersion.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Ssl.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Ssl/Types/TrustedCertStatus.cs b/src/Ryujinx.HLE/HOS/Services/Ssl/Types/TrustedCertStatus.cs index e9d348c12..b6f855f27 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ssl/Types/TrustedCertStatus.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ssl/Types/TrustedCertStatus.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Ssl.Types +namespace Ryujinx.HLE.HOS.Services.Ssl.Types { enum TrustedCertStatus : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/Ssl/Types/VerifyOption.cs b/src/Ryujinx.HLE/HOS/Services/Ssl/Types/VerifyOption.cs index 1c13e80f3..215e72b0f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ssl/Types/VerifyOption.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ssl/Types/VerifyOption.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Ssl.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferItemConsumer.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferItemConsumer.cs index 265962106..17045e4e9 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferItemConsumer.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferItemConsumer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Gpu; +using Ryujinx.Graphics.Gpu; using System; namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueue.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueue.cs index 347eb8fba..e95dcc69f 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueue.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueue.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger +namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { static class BufferQueue { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueConsumer.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueConsumer.cs index 4cd45d691..74afa989d 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueConsumer.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueConsumer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.SurfaceFlinger.Types; using Ryujinx.HLE.HOS.Services.Time.Clock; using System; diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueCore.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueCore.cs index f1d2f84b5..5dc02a07e 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueCore.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueCore.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.HLE.HOS.Services.SurfaceFlinger.Types; using System; diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueProducer.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueProducer.cs index 55bfac84d..ae61d0bf7 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueProducer.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueProducer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Cpu; using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.HLE.HOS.Services.Settings; diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferSlot.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferSlot.cs index 4632053df..07d6ab7c6 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferSlot.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferSlot.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.SurfaceFlinger.Types; +using Ryujinx.HLE.HOS.Services.SurfaceFlinger.Types; using Ryujinx.HLE.HOS.Services.Time.Clock; namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferSlotArray.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferSlotArray.cs index 5a6604f14..19c1bb4e4 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferSlotArray.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferSlotArray.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger +namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { class BufferSlotArray { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/ConsumerBase.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/ConsumerBase.cs index d63019972..f8ee84842 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/ConsumerBase.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/ConsumerBase.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.SurfaceFlinger.Types; +using Ryujinx.HLE.HOS.Services.SurfaceFlinger.Types; using System; namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/HOSBinderDriverServer.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/HOSBinderDriverServer.cs index f89eaeeb6..bc7bffcb6 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/HOSBinderDriverServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/HOSBinderDriverServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Kernel.Threading; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IBinder.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IBinder.cs index 9690cd4a1..0fb2dfd2e 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IBinder.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IBinder.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Kernel.Threading; using System; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IConsumerListener.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IConsumerListener.cs index 78f9c2e7e..34a02ca95 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IConsumerListener.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IConsumerListener.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger +namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { interface IConsumerListener { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IFlattenable.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IFlattenable.cs index bfb76952b..7d7e7257c 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IFlattenable.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IFlattenable.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger +namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { interface IFlattenable { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IGraphicBufferProducer.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IGraphicBufferProducer.cs index a70f7fe39..3c01b92fb 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IGraphicBufferProducer.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IGraphicBufferProducer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.HLE.HOS.Services.SurfaceFlinger.Types; using System; diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IHOSBinderDriver.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IHOSBinderDriver.cs index 3d44e23dc..7cb6763b8 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IHOSBinderDriver.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IHOSBinderDriver.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.Horizon.Common; diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IProducerListener.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IProducerListener.cs index 43d2101ef..945d9d829 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IProducerListener.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IProducerListener.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger +namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { interface IProducerListener { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NativeWindowApi.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NativeWindowApi.cs index b565f3f60..45c352ab3 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NativeWindowApi.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NativeWindowApi.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger +namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { enum NativeWindowApi { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NativeWindowAttribute.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NativeWindowAttribute.cs index 075f81369..d49942260 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NativeWindowAttribute.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NativeWindowAttribute.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger +namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { enum NativeWindowAttribute : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NativeWindowScalingMode.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NativeWindowScalingMode.cs index 9b07e43bd..9f521ca2a 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NativeWindowScalingMode.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NativeWindowScalingMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger +namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { enum NativeWindowScalingMode : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NativeWindowTransform.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NativeWindowTransform.cs index 1a0c7d13b..d568b7438 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NativeWindowTransform.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NativeWindowTransform.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Parcel.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Parcel.cs index 431c2cadc..4ac0525ba 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Parcel.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Parcel.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Common.Utilities; using Ryujinx.HLE.HOS.Services.SurfaceFlinger.Types; using System; diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/ParcelHeader.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/ParcelHeader.cs index 27068af27..1937204a6 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/ParcelHeader.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/ParcelHeader.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger +namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { struct ParcelHeader { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/PixelFormat.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/PixelFormat.cs index c0ddea10b..8febb7fbe 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/PixelFormat.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/PixelFormat.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger +namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { enum PixelFormat : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Status.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Status.cs index d328aee9b..14f80fa90 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Status.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Status.cs @@ -1,4 +1,4 @@ -using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.CodeAnalysis; namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs index 712d640c2..fd517b1ae 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Common.PreciseSleep; diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/AndroidFence.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/AndroidFence.cs index 448074cd7..ebc6501ae 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/AndroidFence.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/AndroidFence.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Graphics.Gpu; using Ryujinx.Graphics.Gpu.Synchronization; using Ryujinx.HLE.HOS.Services.Nv.Types; diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/AndroidStrongPointer.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/AndroidStrongPointer.cs index 963a1fe42..85db34d4d 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/AndroidStrongPointer.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/AndroidStrongPointer.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger.Types +namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger.Types { class AndroidStrongPointer where T : unmanaged, IFlattenable { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/BufferInfo.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/BufferInfo.cs index faade87f8..243a88fe7 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/BufferInfo.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/BufferInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Time.Clock; +using Ryujinx.HLE.HOS.Services.Time.Clock; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger.Types diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/BufferItem.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/BufferItem.cs index cbb5ce760..dc752daa3 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/BufferItem.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/BufferItem.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.SurfaceFlinger.Types; +using Ryujinx.HLE.HOS.Services.SurfaceFlinger.Types; using System; namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/BufferState.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/BufferState.cs index d735a294e..89e6dfc6d 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/BufferState.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/BufferState.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger +namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { internal enum BufferState { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorBytePerPixel.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorBytePerPixel.cs index ec119d687..12539032c 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorBytePerPixel.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorBytePerPixel.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger +namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { enum ColorBytePerPixel { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorComponent.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorComponent.cs index e3da29319..6dbeb11b9 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorComponent.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorComponent.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger +namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { enum ColorComponent : uint { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorDataType.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorDataType.cs index 2daa73b80..d30171cb9 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorDataType.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorDataType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger +namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { enum ColorDataType { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorFormat.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorFormat.cs index e13dbd86a..2512393c5 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorFormat.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorFormat.cs @@ -1,4 +1,4 @@ -using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.CodeAnalysis; namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorShift.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorShift.cs index e19ed3eff..1cc8fecbc 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorShift.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorShift.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger +namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { class ColorShift { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorSpace.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorSpace.cs index 5021e356e..7f3f0220c 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorSpace.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorSpace.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger +namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { enum ColorSpace : ulong { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorSwizzle.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorSwizzle.cs index 0473d56b3..0cac6dab4 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorSwizzle.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Color/ColorSwizzle.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger +namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { enum ColorSwizzle { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/GraphicBufferHeader.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/GraphicBufferHeader.cs index c6413ec13..30cb5c375 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/GraphicBufferHeader.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/GraphicBufferHeader.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBuffer.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBuffer.cs index cbae4a902..51daac818 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBuffer.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBuffer.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBufferSurface.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBufferSurface.cs index e0570c70a..4a427b42e 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBufferSurface.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBufferSurface.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBufferSurfaceArray.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBufferSurfaceArray.cs index 8bc30c1f1..94d780a91 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBufferSurfaceArray.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/NvGraphicBufferSurfaceArray.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Rect.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Rect.cs index a5f7efa51..d287fab02 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Rect.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/Rect.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger diff --git a/src/Ryujinx.HLE/HOS/Services/Time/Clock/EphemeralNetworkSystemClockContextWriter.cs b/src/Ryujinx.HLE/HOS/Services/Time/Clock/EphemeralNetworkSystemClockContextWriter.cs index 14d3cb244..4684d4dca 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/Clock/EphemeralNetworkSystemClockContextWriter.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/Clock/EphemeralNetworkSystemClockContextWriter.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Time.Clock +namespace Ryujinx.HLE.HOS.Services.Time.Clock { class EphemeralNetworkSystemClockContextWriter : SystemClockContextUpdateCallback { diff --git a/src/Ryujinx.HLE/HOS/Services/Time/Clock/EphemeralNetworkSystemClockCore.cs b/src/Ryujinx.HLE/HOS/Services/Time/Clock/EphemeralNetworkSystemClockCore.cs index 003863e4c..5aa907cd4 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/Clock/EphemeralNetworkSystemClockCore.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/Clock/EphemeralNetworkSystemClockCore.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Time.Clock +namespace Ryujinx.HLE.HOS.Services.Time.Clock { class EphemeralNetworkSystemClockCore : SystemClockCore { diff --git a/src/Ryujinx.HLE/HOS/Services/Time/Clock/LocalSystemClockContextWriter.cs b/src/Ryujinx.HLE/HOS/Services/Time/Clock/LocalSystemClockContextWriter.cs index 49da1245f..7b1c1adaf 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/Clock/LocalSystemClockContextWriter.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/Clock/LocalSystemClockContextWriter.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Time.Clock +namespace Ryujinx.HLE.HOS.Services.Time.Clock { class LocalSystemClockContextWriter : SystemClockContextUpdateCallback { diff --git a/src/Ryujinx.HLE/HOS/Services/Time/Clock/NetworkSystemClockContextWriter.cs b/src/Ryujinx.HLE/HOS/Services/Time/Clock/NetworkSystemClockContextWriter.cs index ef315ea4d..99a192f40 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/Clock/NetworkSystemClockContextWriter.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/Clock/NetworkSystemClockContextWriter.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Time.Clock +namespace Ryujinx.HLE.HOS.Services.Time.Clock { class NetworkSystemClockContextWriter : SystemClockContextUpdateCallback { diff --git a/src/Ryujinx.HLE/HOS/Services/Time/Clock/StandardLocalSystemClockCore.cs b/src/Ryujinx.HLE/HOS/Services/Time/Clock/StandardLocalSystemClockCore.cs index 458ec4057..cf1e03f30 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/Clock/StandardLocalSystemClockCore.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/Clock/StandardLocalSystemClockCore.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Time.Clock +namespace Ryujinx.HLE.HOS.Services.Time.Clock { class StandardLocalSystemClockCore : SystemClockCore { diff --git a/src/Ryujinx.HLE/HOS/Services/Time/Clock/StandardNetworkSystemClockCore.cs b/src/Ryujinx.HLE/HOS/Services/Time/Clock/StandardNetworkSystemClockCore.cs index 200ab6306..120596335 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/Clock/StandardNetworkSystemClockCore.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/Clock/StandardNetworkSystemClockCore.cs @@ -1,4 +1,4 @@ -using Ryujinx.Cpu; +using Ryujinx.Cpu; namespace Ryujinx.HLE.HOS.Services.Time.Clock { diff --git a/src/Ryujinx.HLE/HOS/Services/Time/Clock/StandardSteadyClockCore.cs b/src/Ryujinx.HLE/HOS/Services/Time/Clock/StandardSteadyClockCore.cs index 3ae699ae0..bc785ca7b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/Clock/StandardSteadyClockCore.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/Clock/StandardSteadyClockCore.cs @@ -1,4 +1,4 @@ -using Ryujinx.Cpu; +using Ryujinx.Cpu; namespace Ryujinx.HLE.HOS.Services.Time.Clock { diff --git a/src/Ryujinx.HLE/HOS/Services/Time/Clock/StandardUserSystemClockCore.cs b/src/Ryujinx.HLE/HOS/Services/Time/Clock/StandardUserSystemClockCore.cs index e50ee7da6..147faa848 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/Clock/StandardUserSystemClockCore.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/Clock/StandardUserSystemClockCore.cs @@ -1,4 +1,4 @@ -using Ryujinx.Cpu; +using Ryujinx.Cpu; using Ryujinx.HLE.HOS.Kernel.Threading; using System; diff --git a/src/Ryujinx.HLE/HOS/Services/Time/Clock/SteadyClockCore.cs b/src/Ryujinx.HLE/HOS/Services/Time/Clock/SteadyClockCore.cs index 2d12a2a06..95cf2a899 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/Clock/SteadyClockCore.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/Clock/SteadyClockCore.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using Ryujinx.Cpu; using System; diff --git a/src/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockContextUpdateCallback.cs b/src/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockContextUpdateCallback.cs index 3f191820f..119096dcf 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockContextUpdateCallback.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockContextUpdateCallback.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Kernel.Threading; +using Ryujinx.HLE.HOS.Kernel.Threading; using System.Collections.Generic; using System.Threading; diff --git a/src/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockCore.cs b/src/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockCore.cs index f8a995b71..c46380513 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockCore.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockCore.cs @@ -1,4 +1,4 @@ -using Ryujinx.Cpu; +using Ryujinx.Cpu; using Ryujinx.HLE.HOS.Kernel.Threading; namespace Ryujinx.HLE.HOS.Services.Time.Clock diff --git a/src/Ryujinx.HLE/HOS/Services/Time/Clock/TickBasedSteadyClockCore.cs b/src/Ryujinx.HLE/HOS/Services/Time/Clock/TickBasedSteadyClockCore.cs index 99e981ecd..5c10c6930 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/Clock/TickBasedSteadyClockCore.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/Clock/TickBasedSteadyClockCore.cs @@ -1,4 +1,4 @@ -using Ryujinx.Cpu; +using Ryujinx.Cpu; namespace Ryujinx.HLE.HOS.Services.Time.Clock { diff --git a/src/Ryujinx.HLE/HOS/Services/Time/Clock/Types/ClockSnapshot.cs b/src/Ryujinx.HLE/HOS/Services/Time/Clock/Types/ClockSnapshot.cs index d0a74a935..4383fc823 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/Clock/Types/ClockSnapshot.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/Clock/Types/ClockSnapshot.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Time.TimeZone; +using Ryujinx.HLE.HOS.Services.Time.TimeZone; using System; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Time/Clock/Types/ContinuousAdjustmentTimePoint.cs b/src/Ryujinx.HLE/HOS/Services/Time/Clock/Types/ContinuousAdjustmentTimePoint.cs index b57dfaa06..df7ee823c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/Clock/Types/ContinuousAdjustmentTimePoint.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/Clock/Types/ContinuousAdjustmentTimePoint.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Time.Clock.Types { diff --git a/src/Ryujinx.HLE/HOS/Services/Time/Clock/Types/SteadyClockTimePoint.cs b/src/Ryujinx.HLE/HOS/Services/Time/Clock/Types/SteadyClockTimePoint.cs index 2bc99ff81..e4878483d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/Clock/Types/SteadyClockTimePoint.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/Clock/Types/SteadyClockTimePoint.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Time/Clock/Types/SystemClockContext.cs b/src/Ryujinx.HLE/HOS/Services/Time/Clock/Types/SystemClockContext.cs index fc47e775f..cb5f05e4f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/Clock/Types/SystemClockContext.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/Clock/Types/SystemClockContext.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Time.Clock { diff --git a/src/Ryujinx.HLE/HOS/Services/Time/Clock/Types/TimeSpanType.cs b/src/Ryujinx.HLE/HOS/Services/Time/Clock/Types/TimeSpanType.cs index a7ef81150..c0b4ad292 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/Clock/Types/TimeSpanType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/Clock/Types/TimeSpanType.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Time.Clock diff --git a/src/Ryujinx.HLE/HOS/Services/Time/IAlarmService.cs b/src/Ryujinx.HLE/HOS/Services/Time/IAlarmService.cs index 46b58408a..38cd3eb8c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/IAlarmService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/IAlarmService.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Time +namespace Ryujinx.HLE.HOS.Services.Time { [Service("time:al")] // 9.0.0+ class IAlarmService : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Time/IPowerStateRequestHandler.cs b/src/Ryujinx.HLE/HOS/Services/Time/IPowerStateRequestHandler.cs index 64b7e69c6..2f67918bf 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/IPowerStateRequestHandler.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/IPowerStateRequestHandler.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Time +namespace Ryujinx.HLE.HOS.Services.Time { [Service("time:p")] // 9.0.0+ class IPowerStateRequestHandler : IpcService diff --git a/src/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForGlue.cs b/src/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForGlue.cs index 32aed90cb..eaddf9cff 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForGlue.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForGlue.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.HLE.HOS.Services.Pcv.Bpc; using Ryujinx.HLE.HOS.Services.Settings; using Ryujinx.HLE.HOS.Services.Time.Clock; diff --git a/src/Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs b/src/Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs index b690b708f..1648aa3e1 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Cpu; using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Ipc; diff --git a/src/Ryujinx.HLE/HOS/Services/Time/ResultCode.cs b/src/Ryujinx.HLE/HOS/Services/Time/ResultCode.cs index 66ae67517..74a57f20b 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/ResultCode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/ResultCode.cs @@ -1,4 +1,4 @@ -using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.CodeAnalysis; namespace Ryujinx.HLE.HOS.Services.Time { diff --git a/src/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForPsc.cs b/src/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForPsc.cs index b3a87b8a6..b18a4f76c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForPsc.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForPsc.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Time.Clock; using Ryujinx.HLE.HOS.Services.Time.TimeZone; diff --git a/src/Ryujinx.HLE/HOS/Services/Time/TimeManager.cs b/src/Ryujinx.HLE/HOS/Services/Time/TimeManager.cs index 53c052e45..f8e36bcd7 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/TimeManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/TimeManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Cpu; +using Ryujinx.Cpu; using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Kernel.Memory; using Ryujinx.HLE.HOS.Services.Time.Clock; diff --git a/src/Ryujinx.HLE/HOS/Services/Time/TimeSharedMemory.cs b/src/Ryujinx.HLE/HOS/Services/Time/TimeSharedMemory.cs index 75479a173..346487030 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/TimeSharedMemory.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/TimeSharedMemory.cs @@ -1,4 +1,4 @@ -using Ryujinx.Cpu; +using Ryujinx.Cpu; using Ryujinx.HLE.HOS.Kernel.Memory; using Ryujinx.HLE.HOS.Services.Time.Clock; using Ryujinx.HLE.HOS.Services.Time.Clock.Types; diff --git a/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZone.cs b/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZone.cs index 58ae1cd8c..cdd11b58d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZone.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZone.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Common.Memory; using Ryujinx.Common.Utilities; using Ryujinx.HLE.Utilities; diff --git a/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs b/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs index 67cb286ae..abf3cd7d6 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs @@ -1,4 +1,4 @@ -using LibHac; +using LibHac; using LibHac.Common; using LibHac.Fs; using LibHac.Fs.Fsa; diff --git a/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneManager.cs b/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneManager.cs index 219b1d9fb..3b57b1805 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.HLE.HOS.Services.Time.Clock; using System; using System.IO; diff --git a/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/CalendarAdditionalInfo.cs b/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/CalendarAdditionalInfo.cs index 8e7dc6d52..331690cc0 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/CalendarAdditionalInfo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/CalendarAdditionalInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Time.TimeZone diff --git a/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/CalendarInfo.cs b/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/CalendarInfo.cs index 7fc6f7a09..c4c1ca00d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/CalendarInfo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/CalendarInfo.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Time.TimeZone { diff --git a/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/CalendarTime.cs b/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/CalendarTime.cs index fa082bde5..16769ebfa 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/CalendarTime.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/CalendarTime.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Time.TimeZone { diff --git a/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/TimeTypeInfo.cs b/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/TimeTypeInfo.cs index 47620f563..4ec58a680 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/TimeTypeInfo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/TimeTypeInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Time.TimeZone diff --git a/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/TimeZoneRule.cs b/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/TimeZoneRule.cs index b8dd2382a..9f5c34100 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/TimeZoneRule.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/TimeZoneRule.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/TzifHeader.cs b/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/TzifHeader.cs index 1d05ee246..33dca6050 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/TzifHeader.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/TzifHeader.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Time.TimeZone diff --git a/src/Ryujinx.HLE/HOS/Services/Time/Types/SteadyClockContext.cs b/src/Ryujinx.HLE/HOS/Services/Time/Types/SteadyClockContext.cs index 2b80604ac..580b6476c 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/Types/SteadyClockContext.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/Types/SteadyClockContext.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Time.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Time/Types/TimePermissions.cs b/src/Ryujinx.HLE/HOS/Services/Time/Types/TimePermissions.cs index 34749c425..7591c3e98 100644 --- a/src/Ryujinx.HLE/HOS/Services/Time/Types/TimePermissions.cs +++ b/src/Ryujinx.HLE/HOS/Services/Time/Types/TimePermissions.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Time { diff --git a/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/AndroidSurfaceComposerClient.cs b/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/AndroidSurfaceComposerClient.cs index 782bb7d7e..c45030984 100644 --- a/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/AndroidSurfaceComposerClient.cs +++ b/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/AndroidSurfaceComposerClient.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService +namespace Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService { class AndroidSurfaceComposerClient { diff --git a/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/Types/DestinationScalingMode.cs b/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/Types/DestinationScalingMode.cs index c712bb1d3..066b9ccfc 100644 --- a/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/Types/DestinationScalingMode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/Types/DestinationScalingMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService +namespace Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService { enum DestinationScalingMode { diff --git a/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/Types/DisplayInfo.cs b/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/Types/DisplayInfo.cs index eae8a8001..a32316925 100644 --- a/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/Types/DisplayInfo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/Types/DisplayInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService.Types diff --git a/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/Types/SourceScalingMode.cs b/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/Types/SourceScalingMode.cs index 536c0d46f..e950d74b6 100644 --- a/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/Types/SourceScalingMode.cs +++ b/src/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/Types/SourceScalingMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService +namespace Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService { enum SourceScalingMode { diff --git a/src/Ryujinx.HLE/HOS/Services/Vi/Types/ViServiceType.cs b/src/Ryujinx.HLE/HOS/Services/Vi/Types/ViServiceType.cs index 41c8bbfaf..3e6e7c249 100644 --- a/src/Ryujinx.HLE/HOS/Services/Vi/Types/ViServiceType.cs +++ b/src/Ryujinx.HLE/HOS/Services/Vi/Types/ViServiceType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Vi.Types +namespace Ryujinx.HLE.HOS.Services.Vi.Types { enum ViServiceType { diff --git a/src/Ryujinx.HLE/HOS/SystemState/TitleLanguage.cs b/src/Ryujinx.HLE/HOS/SystemState/TitleLanguage.cs index 5a0b9f8c2..e3bfb9165 100644 --- a/src/Ryujinx.HLE/HOS/SystemState/TitleLanguage.cs +++ b/src/Ryujinx.HLE/HOS/SystemState/TitleLanguage.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.SystemState +namespace Ryujinx.HLE.HOS.SystemState { public enum TitleLanguage { diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/Arithmetic.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/Arithmetic.cs index c51630d64..5b296def0 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/Arithmetic.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/Arithmetic.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.Exceptions; +using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Tamper.Operations; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/BeginConditionalBlock.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/BeginConditionalBlock.cs index 5439821c5..c8aa4e0eb 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/BeginConditionalBlock.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/BeginConditionalBlock.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters +namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters { /// /// Marks the begin of a conditional block (started by Code Type 1, Code Type 8 or Code Type C0). diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/DebugLog.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/DebugLog.cs index 533b362a6..d74a998f4 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/DebugLog.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/DebugLog.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.Exceptions; +using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Tamper.Operations; namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/EndConditionalBlock.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/EndConditionalBlock.cs index 63625a556..fc7edd62b 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/EndConditionalBlock.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/EndConditionalBlock.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.Exceptions; +using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Tamper.Conditions; using Ryujinx.HLE.HOS.Tamper.Operations; using System.Collections.Generic; diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/KeyPressConditional.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/KeyPressConditional.cs index a17586652..2b0e2c813 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/KeyPressConditional.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/KeyPressConditional.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Tamper.Conditions; +using Ryujinx.HLE.HOS.Tamper.Conditions; namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters { diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LegacyArithmetic.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LegacyArithmetic.cs index 1c389cd7c..3f222864f 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LegacyArithmetic.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LegacyArithmetic.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.Exceptions; +using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Tamper.Operations; using System; diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LoadRegisterWithConstant.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LoadRegisterWithConstant.cs index 16500cf9e..501936b89 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LoadRegisterWithConstant.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LoadRegisterWithConstant.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Tamper.Operations; +using Ryujinx.HLE.HOS.Tamper.Operations; namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters { diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LoadRegisterWithMemory.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LoadRegisterWithMemory.cs index 87b37a1ee..3440efcec 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LoadRegisterWithMemory.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LoadRegisterWithMemory.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.Exceptions; +using Ryujinx.HLE.Exceptions; namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters { diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/MemoryConditional.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/MemoryConditional.cs index 272cf3d05..72b6e6cd3 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/MemoryConditional.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/MemoryConditional.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Tamper.Conditions; +using Ryujinx.HLE.HOS.Tamper.Conditions; namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters { diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/PauseProcess.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/PauseProcess.cs index 14f993947..8bf91ef55 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/PauseProcess.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/PauseProcess.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Tamper.Operations; +using Ryujinx.HLE.HOS.Tamper.Operations; namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters { diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/ReadOrWriteStaticRegister.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/ReadOrWriteStaticRegister.cs index 67775df7f..73fbbde40 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/ReadOrWriteStaticRegister.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/ReadOrWriteStaticRegister.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Tamper.Operations; +using Ryujinx.HLE.HOS.Tamper.Operations; namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters { diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/RegisterConditional.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/RegisterConditional.cs index fcd3a9eb7..4e4d70b05 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/RegisterConditional.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/RegisterConditional.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.Exceptions; +using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Tamper.Conditions; using Ryujinx.HLE.HOS.Tamper.Operations; diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/ResumeProcess.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/ResumeProcess.cs index 7af327d3e..b052d8104 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/ResumeProcess.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/ResumeProcess.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Tamper.Operations; +using Ryujinx.HLE.HOS.Tamper.Operations; namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters { diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/SaveOrRestoreRegister.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/SaveOrRestoreRegister.cs index d2e13311d..59cbdb003 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/SaveOrRestoreRegister.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/SaveOrRestoreRegister.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.Exceptions; +using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Tamper.Operations; namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/SaveOrRestoreRegisterWithMask.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/SaveOrRestoreRegisterWithMask.cs index 2264e9d17..6d1c3b3bd 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/SaveOrRestoreRegisterWithMask.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/SaveOrRestoreRegisterWithMask.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters +namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters { /// /// Code type 0xC2 performs saving or restoring of multiple registers using a bitmask. diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StartEndLoop.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StartEndLoop.cs index 51fc8f35c..22b13ead7 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StartEndLoop.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StartEndLoop.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.Exceptions; +using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Tamper.Operations; namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToAddress.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToAddress.cs index a2a62015a..537166798 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToAddress.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToAddress.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters +namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters { /// /// Code type 0 allows writing a static value to a memory address. diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToMemory.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToMemory.cs index d53b7a26f..27a99bb63 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToMemory.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToMemory.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.Exceptions; +using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Tamper.Operations; namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreRegisterToMemory.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreRegisterToMemory.cs index 422ff2989..d7f3045bc 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreRegisterToMemory.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreRegisterToMemory.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.Exceptions; +using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Tamper.Operations; namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters diff --git a/src/Ryujinx.HLE/HOS/Tamper/CodeType.cs b/src/Ryujinx.HLE/HOS/Tamper/CodeType.cs index d65f8a2f6..704233da7 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CodeType.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CodeType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Tamper +namespace Ryujinx.HLE.HOS.Tamper { /// /// The opcodes specified for the Atmosphere Cheat VM. diff --git a/src/Ryujinx.HLE/HOS/Tamper/Comparison.cs b/src/Ryujinx.HLE/HOS/Tamper/Comparison.cs index dc0f02649..656a62c3e 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/Comparison.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/Comparison.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Tamper +namespace Ryujinx.HLE.HOS.Tamper { /// /// The comparisons used by conditional operations. diff --git a/src/Ryujinx.HLE/HOS/Tamper/CompilationContext.cs b/src/Ryujinx.HLE/HOS/Tamper/CompilationContext.cs index 922e568a3..2a8810ad4 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/CompilationContext.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/CompilationContext.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Tamper.Operations; +using Ryujinx.HLE.HOS.Tamper.Operations; using System.Collections.Generic; namespace Ryujinx.HLE.HOS.Tamper diff --git a/src/Ryujinx.HLE/HOS/Tamper/InstructionHelper.cs b/src/Ryujinx.HLE/HOS/Tamper/InstructionHelper.cs index 76ffefb66..759ba5f90 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/InstructionHelper.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/InstructionHelper.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.Exceptions; +using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Tamper.Conditions; using Ryujinx.HLE.HOS.Tamper.Operations; using System; diff --git a/src/Ryujinx.HLE/HOS/Tamper/MemoryHelper.cs b/src/Ryujinx.HLE/HOS/Tamper/MemoryHelper.cs index 52e12bfe5..b9e649cfc 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/MemoryHelper.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/MemoryHelper.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.Exceptions; +using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Tamper.Operations; namespace Ryujinx.HLE.HOS.Tamper diff --git a/src/Ryujinx.HLE/HOS/Tamper/MemoryRegion.cs b/src/Ryujinx.HLE/HOS/Tamper/MemoryRegion.cs index 766e3eedb..b6e4ed0a3 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/MemoryRegion.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/MemoryRegion.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Tamper +namespace Ryujinx.HLE.HOS.Tamper { /// /// The regions in the virtual address space of the process that are used as base address of memory operations. diff --git a/src/Ryujinx.HLE/HOS/Tamper/OperationBlock.cs b/src/Ryujinx.HLE/HOS/Tamper/OperationBlock.cs index c16c2812a..5a0bccc5d 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/OperationBlock.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/OperationBlock.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Tamper.Operations; +using Ryujinx.HLE.HOS.Tamper.Operations; using System.Collections.Generic; namespace Ryujinx.HLE.HOS.Tamper diff --git a/src/Ryujinx.HLE/HOS/Tamper/TamperedKProcess.cs b/src/Ryujinx.HLE/HOS/Tamper/TamperedKProcess.cs index c8768e88a..422e4ef0e 100644 --- a/src/Ryujinx.HLE/HOS/Tamper/TamperedKProcess.cs +++ b/src/Ryujinx.HLE/HOS/Tamper/TamperedKProcess.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Kernel.Process; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.HLE/HOS/UserChannelPersistence.cs b/src/Ryujinx.HLE/HOS/UserChannelPersistence.cs index 7c7448ba7..64e5ee4b9 100644 --- a/src/Ryujinx.HLE/HOS/UserChannelPersistence.cs +++ b/src/Ryujinx.HLE/HOS/UserChannelPersistence.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.Types; +using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.Types; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.HLE/Loaders/Elf/ElfSymbol32.cs b/src/Ryujinx.HLE/Loaders/Elf/ElfSymbol32.cs index 945b0c8b2..8d4df8942 100644 --- a/src/Ryujinx.HLE/Loaders/Elf/ElfSymbol32.cs +++ b/src/Ryujinx.HLE/Loaders/Elf/ElfSymbol32.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.Loaders.Elf +namespace Ryujinx.HLE.Loaders.Elf { struct ElfSymbol32 { diff --git a/src/Ryujinx.HLE/Loaders/Elf/ElfSymbol64.cs b/src/Ryujinx.HLE/Loaders/Elf/ElfSymbol64.cs index 3a73ca4ed..45a753615 100644 --- a/src/Ryujinx.HLE/Loaders/Elf/ElfSymbol64.cs +++ b/src/Ryujinx.HLE/Loaders/Elf/ElfSymbol64.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.Loaders.Elf +namespace Ryujinx.HLE.Loaders.Elf { struct ElfSymbol64 { diff --git a/src/Ryujinx.HLE/Loaders/Npdm/FsAccessControl.cs b/src/Ryujinx.HLE/Loaders/Npdm/FsAccessControl.cs index e533f513c..f17ca348b 100644 --- a/src/Ryujinx.HLE/Loaders/Npdm/FsAccessControl.cs +++ b/src/Ryujinx.HLE/Loaders/Npdm/FsAccessControl.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; namespace Ryujinx.HLE.Loaders.Npdm { diff --git a/src/Ryujinx.HLE/Loaders/Npdm/FsAccessHeader.cs b/src/Ryujinx.HLE/Loaders/Npdm/FsAccessHeader.cs index 7336464f5..5987be0ef 100644 --- a/src/Ryujinx.HLE/Loaders/Npdm/FsAccessHeader.cs +++ b/src/Ryujinx.HLE/Loaders/Npdm/FsAccessHeader.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.Exceptions; +using Ryujinx.HLE.Exceptions; using System; using System.IO; diff --git a/src/Ryujinx.HLE/Loaders/Npdm/KernelAccessControl.cs b/src/Ryujinx.HLE/Loaders/Npdm/KernelAccessControl.cs index bc8bdbaaa..171243799 100644 --- a/src/Ryujinx.HLE/Loaders/Npdm/KernelAccessControl.cs +++ b/src/Ryujinx.HLE/Loaders/Npdm/KernelAccessControl.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; namespace Ryujinx.HLE.Loaders.Npdm { diff --git a/src/Ryujinx.HLE/Loaders/Npdm/ServiceAccessControl.cs b/src/Ryujinx.HLE/Loaders/Npdm/ServiceAccessControl.cs index 53c864346..bb6df27fa 100644 --- a/src/Ryujinx.HLE/Loaders/Npdm/ServiceAccessControl.cs +++ b/src/Ryujinx.HLE/Loaders/Npdm/ServiceAccessControl.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Text; diff --git a/src/Ryujinx.HLE/Loaders/Processes/Extensions/FileSystemExtensions.cs b/src/Ryujinx.HLE/Loaders/Processes/Extensions/FileSystemExtensions.cs index 07bbaf12b..3904d660e 100644 --- a/src/Ryujinx.HLE/Loaders/Processes/Extensions/FileSystemExtensions.cs +++ b/src/Ryujinx.HLE/Loaders/Processes/Extensions/FileSystemExtensions.cs @@ -1,4 +1,4 @@ -using LibHac.Common; +using LibHac.Common; using LibHac.Fs; using LibHac.Fs.Fsa; using LibHac.Loader; @@ -34,7 +34,7 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions return metaLoader; } - public static ProcessResult Load(this IFileSystem exeFs, Switch device, BlitStruct nacpData, MetaLoader metaLoader, bool isHomebrew = false) + public static ProcessResult Load(this IFileSystem exeFs, Switch device, BlitStruct nacpData, MetaLoader metaLoader, byte programIndex, bool isHomebrew = false) { ulong programId = metaLoader.GetProgramId(); @@ -119,6 +119,7 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions true, programName, metaLoader.GetProgramId(), + programIndex, null, nsoExecutables); diff --git a/src/Ryujinx.HLE/Loaders/Processes/Extensions/LocalFileSystemExtensions.cs b/src/Ryujinx.HLE/Loaders/Processes/Extensions/LocalFileSystemExtensions.cs index 2b7e84734..6c2415e46 100644 --- a/src/Ryujinx.HLE/Loaders/Processes/Extensions/LocalFileSystemExtensions.cs +++ b/src/Ryujinx.HLE/Loaders/Processes/Extensions/LocalFileSystemExtensions.cs @@ -1,4 +1,4 @@ -using LibHac.Common; +using LibHac.Common; using LibHac.FsSystem; using LibHac.Loader; using LibHac.Ncm; @@ -16,17 +16,14 @@ namespace Ryujinx.HLE.Loaders.Processes var nacpData = new BlitStruct(1); ulong programId = metaLoader.GetProgramId(); - device.Configuration.VirtualFileSystem.ModLoader.CollectMods( - new[] { programId }, - ModLoader.GetModsBasePath(), - ModLoader.GetSdModsBasePath()); + device.Configuration.VirtualFileSystem.ModLoader.CollectMods(new[] { programId }); if (programId != 0) { ProcessLoaderHelper.EnsureSaveData(device, new ApplicationId(programId), nacpData); } - ProcessResult processResult = exeFs.Load(device, nacpData, metaLoader); + ProcessResult processResult = exeFs.Load(device, nacpData, metaLoader, 0); // Load RomFS. if (!string.IsNullOrEmpty(romFsPath)) diff --git a/src/Ryujinx.HLE/Loaders/Processes/Extensions/MetaLoaderExtensions.cs b/src/Ryujinx.HLE/Loaders/Processes/Extensions/MetaLoaderExtensions.cs index 88f437591..92e71cb5a 100644 --- a/src/Ryujinx.HLE/Loaders/Processes/Extensions/MetaLoaderExtensions.cs +++ b/src/Ryujinx.HLE/Loaders/Processes/Extensions/MetaLoaderExtensions.cs @@ -1,4 +1,4 @@ -using LibHac.Common; +using LibHac.Common; using LibHac.Fs; using LibHac.Fs.Fsa; using LibHac.Loader; diff --git a/src/Ryujinx.HLE/Loaders/Processes/Extensions/NcaExtensions.cs b/src/Ryujinx.HLE/Loaders/Processes/Extensions/NcaExtensions.cs index 4568b44da..e70fcb6fc 100644 --- a/src/Ryujinx.HLE/Loaders/Processes/Extensions/NcaExtensions.cs +++ b/src/Ryujinx.HLE/Loaders/Processes/Extensions/NcaExtensions.cs @@ -1,4 +1,4 @@ -using LibHac; +using LibHac; using LibHac.Common; using LibHac.Fs; using LibHac.Fs.Fsa; @@ -61,7 +61,7 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions */ - ProcessResult processResult = exeFs.Load(device, nacpData, metaLoader); + ProcessResult processResult = exeFs.Load(device, nacpData, metaLoader, (byte)nca.GetProgramIndex()); // Load RomFS. if (romFs == null) diff --git a/src/Ryujinx.HLE/Loaders/Processes/Extensions/PartitionFileSystemExtensions.cs b/src/Ryujinx.HLE/Loaders/Processes/Extensions/PartitionFileSystemExtensions.cs index 50f7d5853..e95b1b059 100644 --- a/src/Ryujinx.HLE/Loaders/Processes/Extensions/PartitionFileSystemExtensions.cs +++ b/src/Ryujinx.HLE/Loaders/Processes/Extensions/PartitionFileSystemExtensions.cs @@ -1,4 +1,4 @@ -using LibHac.Common; +using LibHac.Common; using LibHac.Fs; using LibHac.Fs.Fsa; using LibHac.FsSystem; diff --git a/src/Ryujinx.HLE/Loaders/Processes/ProcessConst.cs b/src/Ryujinx.HLE/Loaders/Processes/ProcessConst.cs index 9fbf9134b..778f9ce68 100644 --- a/src/Ryujinx.HLE/Loaders/Processes/ProcessConst.cs +++ b/src/Ryujinx.HLE/Loaders/Processes/ProcessConst.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.Loaders.Processes +namespace Ryujinx.HLE.Loaders.Processes { static class ProcessConst { diff --git a/src/Ryujinx.HLE/Loaders/Processes/ProcessLoader.cs b/src/Ryujinx.HLE/Loaders/Processes/ProcessLoader.cs index 220b868db..e5056c89a 100644 --- a/src/Ryujinx.HLE/Loaders/Processes/ProcessLoader.cs +++ b/src/Ryujinx.HLE/Loaders/Processes/ProcessLoader.cs @@ -1,4 +1,4 @@ -using LibHac.Common; +using LibHac.Common; using LibHac.Fs; using LibHac.Fs.Fsa; using LibHac.FsSystem; @@ -77,7 +77,7 @@ namespace Ryujinx.HLE.Loaders.Processes if (processResult.ProcessId == 0) { // This is not a normal NSP, it's actually a ExeFS as a NSP - processResult = partitionFileSystem.Load(_device, new BlitStruct(1), partitionFileSystem.GetNpdm(), true); + processResult = partitionFileSystem.Load(_device, new BlitStruct(1), partitionFileSystem.GetNpdm(), 0, true); } if (processResult.ProcessId != 0 && _processesByPid.TryAdd(processResult.ProcessId, processResult)) @@ -198,7 +198,7 @@ namespace Ryujinx.HLE.Loaders.Processes } else { - programName = System.IO.Path.GetFileNameWithoutExtension(path); + programName = Path.GetFileNameWithoutExtension(path); executable = new NsoExecutable(new LocalStorage(path, FileAccess.Read), programName); } @@ -215,6 +215,7 @@ namespace Ryujinx.HLE.Loaders.Processes allowCodeMemoryForJit: true, programName, programId, + 0, null, executable); diff --git a/src/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs b/src/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs index c229b1742..fe2aaac6d 100644 --- a/src/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs +++ b/src/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs @@ -1,4 +1,4 @@ -using LibHac.Account; +using LibHac.Account; using LibHac.Common; using LibHac.Fs; using LibHac.Fs.Fsa; @@ -19,6 +19,7 @@ using Ryujinx.HLE.HOS.Kernel.Process; using Ryujinx.HLE.Loaders.Executables; using Ryujinx.HLE.Loaders.Processes.Extensions; using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Sdk.Arp; using System; using System.Linq; using System.Runtime.InteropServices; @@ -229,6 +230,7 @@ namespace Ryujinx.HLE.Loaders.Processes bool allowCodeMemoryForJit, string name, ulong programId, + byte programIndex, byte[] arguments = null, params IExecutable[] executables) { @@ -356,11 +358,22 @@ namespace Ryujinx.HLE.Loaders.Processes return ProcessResult.Failed; } + string displayVersion; + + if (metaLoader.GetProgramId() > 0x0100000000007FFF) + { + displayVersion = applicationControlProperties.Value.DisplayVersionString.ToString(); + } + else + { + displayVersion = device.System.ContentManager.GetCurrentFirmwareVersion()?.VersionString ?? string.Empty; + } + var processContextFactory = new ArmProcessContextFactory( context.Device.System.TickSource, context.Device.Gpu, $"{programId:x16}", - applicationControlProperties.Value.DisplayVersionString.ToString(), + displayVersion, diskCacheEnabled, codeStart, codeSize); @@ -410,7 +423,7 @@ namespace Ryujinx.HLE.Loaders.Processes // Once everything is loaded, we can load cheats. device.Configuration.VirtualFileSystem.ModLoader.LoadCheats(programId, tamperInfo, device.TamperMachine); - return new ProcessResult( + ProcessResult processResult = new( metaLoader, applicationControlProperties, diskCacheEnabled, @@ -420,6 +433,25 @@ namespace Ryujinx.HLE.Loaders.Processes meta.MainThreadPriority, meta.MainThreadStackSize, device.System.State.DesiredTitleLanguage); + + // Register everything in arp service. + device.System.ServiceTable.ArpWriter.AcquireRegistrar(out IRegistrar registrar); + registrar.SetApplicationControlProperty(MemoryMarshal.Cast(applicationControlProperties.ByteSpan)[0]); + // TODO: Handle Version and StorageId when it will be needed. + registrar.SetApplicationLaunchProperty(new ApplicationLaunchProperty() + { + ApplicationId = new Horizon.Sdk.Ncm.ApplicationId(programId), + Version = 0x00, + Storage = Horizon.Sdk.Ncm.StorageId.BuiltInUser, + PatchStorage = Horizon.Sdk.Ncm.StorageId.None, + ApplicationKind = ApplicationKind.Application, + }); + + device.System.ServiceTable.ArpReader.GetApplicationInstanceId(out ulong applicationInstanceId, process.Pid); + device.System.ServiceTable.ArpWriter.AcquireApplicationProcessPropertyUpdater(out IUpdater updater, applicationInstanceId); + updater.SetApplicationProcessProperty(process.Pid, new ApplicationProcessProperty() { ProgramIndex = programIndex }); + + return processResult; } public static Result LoadIntoMemory(KProcess process, IExecutable image, ulong baseAddress) diff --git a/src/Ryujinx.HLE/Loaders/Processes/ProcessResult.cs b/src/Ryujinx.HLE/Loaders/Processes/ProcessResult.cs index 9a7b3cd0e..1804d045c 100644 --- a/src/Ryujinx.HLE/Loaders/Processes/ProcessResult.cs +++ b/src/Ryujinx.HLE/Loaders/Processes/ProcessResult.cs @@ -1,4 +1,4 @@ -using LibHac.Common; +using LibHac.Common; using LibHac.Loader; using LibHac.Ns; using Ryujinx.Common.Logging; diff --git a/src/Ryujinx.HLE/PerformanceStatistics.cs b/src/Ryujinx.HLE/PerformanceStatistics.cs index e7270db30..3767a7fb4 100644 --- a/src/Ryujinx.HLE/PerformanceStatistics.cs +++ b/src/Ryujinx.HLE/PerformanceStatistics.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using System.Timers; namespace Ryujinx.HLE diff --git a/src/Ryujinx.HLE/Ryujinx.HLE.csproj b/src/Ryujinx.HLE/Ryujinx.HLE.csproj index 370933ccf..dbcb82212 100644 --- a/src/Ryujinx.HLE/Ryujinx.HLE.csproj +++ b/src/Ryujinx.HLE/Ryujinx.HLE.csproj @@ -23,10 +23,10 @@ + - diff --git a/src/Ryujinx.HLE/Ui/IHostUiTheme.cs b/src/Ryujinx.HLE/Ui/IHostUiTheme.cs index 6404c80c9..11d82361a 100644 --- a/src/Ryujinx.HLE/Ui/IHostUiTheme.cs +++ b/src/Ryujinx.HLE/Ui/IHostUiTheme.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.Ui +namespace Ryujinx.HLE.Ui { public interface IHostUiTheme { diff --git a/src/Ryujinx.HLE/Ui/Input/NpadButtonHandler.cs b/src/Ryujinx.HLE/Ui/Input/NpadButtonHandler.cs index cd41f5c8b..2d1c1c491 100644 --- a/src/Ryujinx.HLE/Ui/Input/NpadButtonHandler.cs +++ b/src/Ryujinx.HLE/Ui/Input/NpadButtonHandler.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad; namespace Ryujinx.HLE.Ui.Input { diff --git a/src/Ryujinx.HLE/Ui/Input/NpadReader.cs b/src/Ryujinx.HLE/Ui/Input/NpadReader.cs index c4ef5da50..8fc95dc94 100644 --- a/src/Ryujinx.HLE/Ui/Input/NpadReader.cs +++ b/src/Ryujinx.HLE/Ui/Input/NpadReader.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad; namespace Ryujinx.HLE.Ui.Input diff --git a/src/Ryujinx.HLE/Ui/RenderingSurfaceInfo.cs b/src/Ryujinx.HLE/Ui/RenderingSurfaceInfo.cs index 10da74ef3..0b3d0a909 100644 --- a/src/Ryujinx.HLE/Ui/RenderingSurfaceInfo.cs +++ b/src/Ryujinx.HLE/Ui/RenderingSurfaceInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.HOS.Services.SurfaceFlinger; +using Ryujinx.HLE.HOS.Services.SurfaceFlinger; using System; namespace Ryujinx.HLE.Ui diff --git a/src/Ryujinx.HLE/Ui/ThemeColor.cs b/src/Ryujinx.HLE/Ui/ThemeColor.cs index c594c370b..23657ed2b 100644 --- a/src/Ryujinx.HLE/Ui/ThemeColor.cs +++ b/src/Ryujinx.HLE/Ui/ThemeColor.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.Ui +namespace Ryujinx.HLE.Ui { public readonly struct ThemeColor { diff --git a/src/Ryujinx.HLE/Utilities/StringUtils.cs b/src/Ryujinx.HLE/Utilities/StringUtils.cs index 9b3479eec..55fb06e48 100644 --- a/src/Ryujinx.HLE/Utilities/StringUtils.cs +++ b/src/Ryujinx.HLE/Utilities/StringUtils.cs @@ -1,4 +1,4 @@ -using LibHac.Common; +using LibHac.Common; using Microsoft.IO; using Ryujinx.Common.Memory; using Ryujinx.HLE.HOS; diff --git a/src/Ryujinx.Headless.SDL2/HeadlessHostUiTheme.cs b/src/Ryujinx.Headless.SDL2/HeadlessHostUiTheme.cs index 361ef0900..a2df6f3ee 100644 --- a/src/Ryujinx.Headless.SDL2/HeadlessHostUiTheme.cs +++ b/src/Ryujinx.Headless.SDL2/HeadlessHostUiTheme.cs @@ -1,4 +1,4 @@ -using Ryujinx.HLE.Ui; +using Ryujinx.HLE.Ui; namespace Ryujinx.Headless.SDL2 { diff --git a/src/Ryujinx.Headless.SDL2/OpenGL/OpenGLWindow.cs b/src/Ryujinx.Headless.SDL2/OpenGL/OpenGLWindow.cs index 245aba778..3fb93a0ec 100644 --- a/src/Ryujinx.Headless.SDL2/OpenGL/OpenGLWindow.cs +++ b/src/Ryujinx.Headless.SDL2/OpenGL/OpenGLWindow.cs @@ -1,4 +1,4 @@ -using OpenTK; +using OpenTK; using OpenTK.Graphics.OpenGL; using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; diff --git a/src/Ryujinx.Headless.SDL2/Options.cs b/src/Ryujinx.Headless.SDL2/Options.cs index a1adcd024..ea2063758 100644 --- a/src/Ryujinx.Headless.SDL2/Options.cs +++ b/src/Ryujinx.Headless.SDL2/Options.cs @@ -1,4 +1,4 @@ -using CommandLine; +using CommandLine; using Ryujinx.Common.Configuration; using Ryujinx.HLE.HOS.SystemState; diff --git a/src/Ryujinx.Headless.SDL2/Program.cs b/src/Ryujinx.Headless.SDL2/Program.cs index 86d3e841d..c23002757 100644 --- a/src/Ryujinx.Headless.SDL2/Program.cs +++ b/src/Ryujinx.Headless.SDL2/Program.cs @@ -1,4 +1,3 @@ -using ARMeilleure.Translation; using CommandLine; using LibHac.Tools.FsSystem; using Ryujinx.Audio.Backends.SDL2; @@ -62,7 +61,7 @@ namespace Ryujinx.Headless.SDL2 static void Main(string[] args) { - Version = ReleaseInformation.GetVersion(); + Version = ReleaseInformation.Version; // Make process DPI aware for proper window sizing on high-res screens. ForceDpiAware.Windows(); @@ -428,11 +427,26 @@ namespace Ryujinx.Headless.SDL2 if (!option.DisableFileLog) { - Logger.AddTarget(new AsyncLogTargetWrapper( - new FileLogTarget(ReleaseInformation.GetBaseApplicationDirectory(), "file"), - 1000, - AsyncLogTargetOverflowAction.Block - )); + FileStream logFile = FileLogTarget.PrepareLogFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs")); + + if (logFile == null) + { + logFile = FileLogTarget.PrepareLogFile(Path.Combine(AppDataManager.BaseDirPath, "Logs")); + + if (logFile == null) + { + Logger.Error?.Print(LogClass.Application, "No writable log directory available. Make sure either the application directory or the Ryujinx directory is writable."); + } + } + + if (logFile != null) + { + Logger.AddTarget(new AsyncLogTargetWrapper( + new FileLogTarget("file", logFile), + 1000, + AsyncLogTargetOverflowAction.Block + )); + } } // Setup graphics configuration @@ -710,9 +724,6 @@ namespace Ryujinx.Headless.SDL2 } SetupProgressHandler(); - - Translator.IsReadyForTranslation.Reset(); - ExecutionEntrypoint(); return true; diff --git a/src/Ryujinx.Headless.SDL2/SDL2Mouse.cs b/src/Ryujinx.Headless.SDL2/SDL2Mouse.cs index 684433688..de64b4f8f 100644 --- a/src/Ryujinx.Headless.SDL2/SDL2Mouse.cs +++ b/src/Ryujinx.Headless.SDL2/SDL2Mouse.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Configuration.Hid; +using Ryujinx.Common.Configuration.Hid; using Ryujinx.Input; using System; using System.Drawing; diff --git a/src/Ryujinx.Headless.SDL2/StatusUpdatedEventArgs.cs b/src/Ryujinx.Headless.SDL2/StatusUpdatedEventArgs.cs index 62e161dfd..0b199d128 100644 --- a/src/Ryujinx.Headless.SDL2/StatusUpdatedEventArgs.cs +++ b/src/Ryujinx.Headless.SDL2/StatusUpdatedEventArgs.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Headless.SDL2 { diff --git a/src/Ryujinx.Headless.SDL2/Vulkan/VulkanWindow.cs b/src/Ryujinx.Headless.SDL2/Vulkan/VulkanWindow.cs index 4a04b10a3..e5572c936 100644 --- a/src/Ryujinx.Headless.SDL2/Vulkan/VulkanWindow.cs +++ b/src/Ryujinx.Headless.SDL2/Vulkan/VulkanWindow.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Configuration; +using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Input.HLE; using Ryujinx.SDL2.Common; diff --git a/src/Ryujinx.Headless.SDL2/WindowBase.cs b/src/Ryujinx.Headless.SDL2/WindowBase.cs index 1b9556057..b1f43dc22 100644 --- a/src/Ryujinx.Headless.SDL2/WindowBase.cs +++ b/src/Ryujinx.Headless.SDL2/WindowBase.cs @@ -1,4 +1,3 @@ -using ARMeilleure.Translation; using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Logging; @@ -81,7 +80,7 @@ namespace Ryujinx.Headless.SDL2 private bool _isStopped; private uint _windowId; - private string _gpuVendorName; + private string _gpuDriverName; private readonly AspectRatio _aspectRatio; private readonly bool _enableMouse; @@ -242,9 +241,9 @@ namespace Ryujinx.Headless.SDL2 public abstract SDL_WindowFlags GetWindowFlags(); - private string GetGpuVendorName() + private string GetGpuDriverName() { - return Renderer.GetHardwareInfo().GpuVendor; + return Renderer.GetHardwareInfo().GpuDriver; } private void SetAntiAliasing() @@ -270,13 +269,12 @@ namespace Ryujinx.Headless.SDL2 SetScalingFilter(); - _gpuVendorName = GetGpuVendorName(); + _gpuDriverName = GetGpuDriverName(); Device.Gpu.Renderer.RunLoop(() => { Device.Gpu.SetGpuThread(); Device.Gpu.InitializeShaderCache(_gpuCancellationTokenSource.Token); - Translator.IsReadyForTranslation.Set(); while (_isActive) { @@ -316,7 +314,7 @@ namespace Ryujinx.Headless.SDL2 Device.Configuration.AspectRatio.ToText(), $"Game: {Device.Statistics.GetGameFrameRate():00.00} FPS ({Device.Statistics.GetGameFrameTime():00.00} ms)", $"FIFO: {Device.Statistics.GetFifoPercent():0.00} %", - $"GPU: {_gpuVendorName}")); + $"GPU: {_gpuDriverName}")); _ticks = Math.Min(_ticks - _ticksPerFrame, _ticksPerFrame); } diff --git a/src/Ryujinx.Horizon.Common/ISyscallApi.cs b/src/Ryujinx.Horizon.Common/ISyscallApi.cs index 8fa276b52..20277f344 100644 --- a/src/Ryujinx.Horizon.Common/ISyscallApi.cs +++ b/src/Ryujinx.Horizon.Common/ISyscallApi.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Horizon.Common { diff --git a/src/Ryujinx.Horizon.Common/IThreadContext.cs b/src/Ryujinx.Horizon.Common/IThreadContext.cs index 47aea1a38..6a2b71b67 100644 --- a/src/Ryujinx.Horizon.Common/IThreadContext.cs +++ b/src/Ryujinx.Horizon.Common/IThreadContext.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Common +namespace Ryujinx.Horizon.Common { public interface IThreadContext { diff --git a/src/Ryujinx.Horizon.Common/InvalidResultException.cs b/src/Ryujinx.Horizon.Common/InvalidResultException.cs index cf38b6403..80621f45f 100644 --- a/src/Ryujinx.Horizon.Common/InvalidResultException.cs +++ b/src/Ryujinx.Horizon.Common/InvalidResultException.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Horizon.Common { diff --git a/src/Ryujinx.Horizon.Common/KernelResult.cs b/src/Ryujinx.Horizon.Common/KernelResult.cs index ff367ac46..37d9fb0a9 100644 --- a/src/Ryujinx.Horizon.Common/KernelResult.cs +++ b/src/Ryujinx.Horizon.Common/KernelResult.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Common +namespace Ryujinx.Horizon.Common { public static class KernelResult { diff --git a/src/Ryujinx.Horizon.Common/OnScopeExit.cs b/src/Ryujinx.Horizon.Common/OnScopeExit.cs index deba7bbad..aebaf3ba1 100644 --- a/src/Ryujinx.Horizon.Common/OnScopeExit.cs +++ b/src/Ryujinx.Horizon.Common/OnScopeExit.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Horizon.Common { diff --git a/src/Ryujinx.Horizon.Common/Result.cs b/src/Ryujinx.Horizon.Common/Result.cs index 8e458475d..d313554e3 100644 --- a/src/Ryujinx.Horizon.Common/Result.cs +++ b/src/Ryujinx.Horizon.Common/Result.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Horizon.Common { diff --git a/src/Ryujinx.Horizon.Generators/CodeGenerator.cs b/src/Ryujinx.Horizon.Generators/CodeGenerator.cs index 59052499e..9d117f550 100644 --- a/src/Ryujinx.Horizon.Generators/CodeGenerator.cs +++ b/src/Ryujinx.Horizon.Generators/CodeGenerator.cs @@ -1,4 +1,4 @@ -using System.Text; +using System.Text; namespace Ryujinx.Horizon.Generators { diff --git a/src/Ryujinx.Horizon.Generators/Hipc/CommandArgType.cs b/src/Ryujinx.Horizon.Generators/Hipc/CommandArgType.cs index a5e6ec4a0..f26eeec17 100644 --- a/src/Ryujinx.Horizon.Generators/Hipc/CommandArgType.cs +++ b/src/Ryujinx.Horizon.Generators/Hipc/CommandArgType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Generators.Hipc +namespace Ryujinx.Horizon.Generators.Hipc { enum CommandArgType : byte { diff --git a/src/Ryujinx.Horizon.Generators/Hipc/CommandInterface.cs b/src/Ryujinx.Horizon.Generators/Hipc/CommandInterface.cs index 2ee192820..2dcdfe5a2 100644 --- a/src/Ryujinx.Horizon.Generators/Hipc/CommandInterface.cs +++ b/src/Ryujinx.Horizon.Generators/Hipc/CommandInterface.cs @@ -1,4 +1,4 @@ -using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.CSharp.Syntax; using System.Collections.Generic; namespace Ryujinx.Horizon.Generators.Hipc diff --git a/src/Ryujinx.Horizon.Generators/Hipc/HipcGenerator.cs b/src/Ryujinx.Horizon.Generators/Hipc/HipcGenerator.cs index 4e14f47e9..a65ec3abd 100644 --- a/src/Ryujinx.Horizon.Generators/Hipc/HipcGenerator.cs +++ b/src/Ryujinx.Horizon.Generators/Hipc/HipcGenerator.cs @@ -1,4 +1,4 @@ -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using System.Collections.Generic; diff --git a/src/Ryujinx.Horizon.Generators/Hipc/HipcSyntaxReceiver.cs b/src/Ryujinx.Horizon.Generators/Hipc/HipcSyntaxReceiver.cs index 4b998dbe2..9b3421076 100644 --- a/src/Ryujinx.Horizon.Generators/Hipc/HipcSyntaxReceiver.cs +++ b/src/Ryujinx.Horizon.Generators/Hipc/HipcSyntaxReceiver.cs @@ -1,4 +1,4 @@ -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using System.Collections.Generic; diff --git a/src/Ryujinx.Horizon.Kernel.Generators/CodeGenerator.cs b/src/Ryujinx.Horizon.Kernel.Generators/CodeGenerator.cs index 121b6dd58..393a36c36 100644 --- a/src/Ryujinx.Horizon.Kernel.Generators/CodeGenerator.cs +++ b/src/Ryujinx.Horizon.Kernel.Generators/CodeGenerator.cs @@ -1,4 +1,4 @@ -using System.Text; +using System.Text; namespace Ryujinx.Horizon.Kernel.Generators { diff --git a/src/Ryujinx.Horizon.Kernel.Generators/SyscallGenerator.cs b/src/Ryujinx.Horizon.Kernel.Generators/SyscallGenerator.cs index 638b2ea8f..7419a839a 100644 --- a/src/Ryujinx.Horizon.Kernel.Generators/SyscallGenerator.cs +++ b/src/Ryujinx.Horizon.Kernel.Generators/SyscallGenerator.cs @@ -1,4 +1,4 @@ -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using System; diff --git a/src/Ryujinx.Horizon.Kernel.Generators/SyscallSyntaxReceiver.cs b/src/Ryujinx.Horizon.Kernel.Generators/SyscallSyntaxReceiver.cs index f586ee682..1542fed6a 100644 --- a/src/Ryujinx.Horizon.Kernel.Generators/SyscallSyntaxReceiver.cs +++ b/src/Ryujinx.Horizon.Kernel.Generators/SyscallSyntaxReceiver.cs @@ -1,4 +1,4 @@ -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using System.Collections.Generic; using System.Linq; diff --git a/src/Ryujinx.Horizon/Arp/ArpIpcServer.cs b/src/Ryujinx.Horizon/Arp/ArpIpcServer.cs new file mode 100644 index 000000000..6080b4750 --- /dev/null +++ b/src/Ryujinx.Horizon/Arp/ArpIpcServer.cs @@ -0,0 +1,61 @@ +using Ryujinx.Horizon.Arp.Ipc; +using Ryujinx.Horizon.Sdk.Arp; +using Ryujinx.Horizon.Sdk.Arp.Detail; +using Ryujinx.Horizon.Sdk.Sf.Hipc; +using Ryujinx.Horizon.Sdk.Sm; + +namespace Ryujinx.Horizon.Arp +{ + class ArpIpcServer + { + private const int ArpRMaxSessionsCount = 16; + private const int ArpWMaxSessionsCount = 8; + private const int MaxSessionsCount = ArpRMaxSessionsCount + ArpWMaxSessionsCount; + + private const int PointerBufferSize = 0x1000; + private const int MaxDomains = 24; + private const int MaxDomainObjects = 32; + private const int MaxPortsCount = 2; + + private static readonly ManagerOptions _managerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false); + + private SmApi _sm; + private ServerManager _serverManager; + private ApplicationInstanceManager _applicationInstanceManager; + + public IReader Reader { get; private set; } + public IWriter Writer { get; private set; } + + public void Initialize() + { + HeapAllocator allocator = new(); + + _sm = new SmApi(); + _sm.Initialize().AbortOnFailure(); + + _serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _managerOptions, MaxSessionsCount); + + _applicationInstanceManager = new ApplicationInstanceManager(); + + Reader reader = new(_applicationInstanceManager); + Reader = reader; + + Writer writer = new(_applicationInstanceManager); + Writer = writer; + + _serverManager.RegisterObjectForServer(reader, ServiceName.Encode("arp:r"), ArpRMaxSessionsCount); + _serverManager.RegisterObjectForServer(writer, ServiceName.Encode("arp:w"), ArpWMaxSessionsCount); + } + + public void ServiceRequests() + { + _serverManager.ServiceRequests(); + } + + public void Shutdown() + { + _applicationInstanceManager.Dispose(); + _serverManager.Dispose(); + } + } +} diff --git a/src/Ryujinx.Horizon/Arp/ArpMain.cs b/src/Ryujinx.Horizon/Arp/ArpMain.cs new file mode 100644 index 000000000..a28baa71a --- /dev/null +++ b/src/Ryujinx.Horizon/Arp/ArpMain.cs @@ -0,0 +1,20 @@ +namespace Ryujinx.Horizon.Arp +{ + class ArpMain : IService + { + public static void Main(ServiceTable serviceTable) + { + ArpIpcServer arpIpcServer = new(); + + arpIpcServer.Initialize(); + + serviceTable.ArpReader = arpIpcServer.Reader; + serviceTable.ArpWriter = arpIpcServer.Writer; + + serviceTable.SignalServiceReady(); + + arpIpcServer.ServiceRequests(); + arpIpcServer.Shutdown(); + } + } +} diff --git a/src/Ryujinx.Horizon/Arp/Ipc/Reader.cs b/src/Ryujinx.Horizon/Arp/Ipc/Reader.cs new file mode 100644 index 000000000..de99c2ade --- /dev/null +++ b/src/Ryujinx.Horizon/Arp/Ipc/Reader.cs @@ -0,0 +1,135 @@ +using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Sdk.Arp; +using Ryujinx.Horizon.Sdk.Arp.Detail; +using Ryujinx.Horizon.Sdk.Ns; +using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf.Hipc; +using System; + +namespace Ryujinx.Horizon.Arp.Ipc +{ + partial class Reader : IReader, IServiceObject + { + private readonly ApplicationInstanceManager _applicationInstanceManager; + + public Reader(ApplicationInstanceManager applicationInstanceManager) + { + _applicationInstanceManager = applicationInstanceManager; + } + + [CmifCommand(0)] + public Result GetApplicationLaunchProperty(out ApplicationLaunchProperty applicationLaunchProperty, ulong applicationInstanceId) + { + if (_applicationInstanceManager.Entries[applicationInstanceId] == null || !_applicationInstanceManager.Entries[applicationInstanceId].LaunchProperty.HasValue) + { + applicationLaunchProperty = default; + + return ArpResult.InvalidInstanceId; + } + + applicationLaunchProperty = _applicationInstanceManager.Entries[applicationInstanceId].LaunchProperty.Value; + + return Result.Success; + } + + [CmifCommand(1)] + public Result GetApplicationControlProperty([Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias, 0x4000)] out ApplicationControlProperty applicationControlProperty, ulong applicationInstanceId) + { + if (_applicationInstanceManager.Entries[applicationInstanceId] == null || !_applicationInstanceManager.Entries[applicationInstanceId].ControlProperty.HasValue) + { + applicationControlProperty = default; + + return ArpResult.InvalidInstanceId; + } + + applicationControlProperty = _applicationInstanceManager.Entries[applicationInstanceId].ControlProperty.Value; + + return Result.Success; + } + + [CmifCommand(2)] + public Result GetApplicationProcessProperty(out ApplicationProcessProperty applicationProcessProperty, ulong applicationInstanceId) + { + if (_applicationInstanceManager.Entries[applicationInstanceId] == null || !_applicationInstanceManager.Entries[applicationInstanceId].ProcessProperty.HasValue) + { + applicationProcessProperty = default; + + return ArpResult.InvalidInstanceId; + } + + applicationProcessProperty = _applicationInstanceManager.Entries[applicationInstanceId].ProcessProperty.Value; + + return Result.Success; + } + + [CmifCommand(3)] + public Result GetApplicationInstanceId(out ulong applicationInstanceId, ulong pid) + { + applicationInstanceId = 0; + + if (pid == 0) + { + return ArpResult.InvalidPid; + } + + for (int i = 0; i < _applicationInstanceManager.Entries.Length; i++) + { + if (_applicationInstanceManager.Entries[i] != null && _applicationInstanceManager.Entries[i].Pid == pid) + { + applicationInstanceId = (ulong)i; + + return Result.Success; + } + } + + return ArpResult.InvalidPid; + } + + [CmifCommand(4)] + public Result GetApplicationInstanceUnregistrationNotifier(out IUnregistrationNotifier unregistrationNotifier) + { + unregistrationNotifier = new UnregistrationNotifier(_applicationInstanceManager); + + return Result.Success; + } + + [CmifCommand(5)] + public Result ListApplicationInstanceId(out int count, [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span applicationInstanceIdList) + { + count = 0; + + if (_applicationInstanceManager.Entries[0] != null) + { + applicationInstanceIdList[count++] = 0; + } + + if (_applicationInstanceManager.Entries[1] != null) + { + applicationInstanceIdList[count++] = 1; + } + + return Result.Success; + } + + [CmifCommand(6)] + public Result GetMicroApplicationInstanceId(out ulong microApplicationInstanceId, [ClientProcessId] ulong pid) + { + return GetApplicationInstanceId(out microApplicationInstanceId, pid); + } + + [CmifCommand(7)] + public Result GetApplicationCertificate([Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias | HipcBufferFlags.FixedSize, 0x528)] out ApplicationCertificate applicationCertificate, ulong applicationInstanceId) + { + if (_applicationInstanceManager.Entries[applicationInstanceId] == null) + { + applicationCertificate = default; + + return ArpResult.InvalidInstanceId; + } + + applicationCertificate = _applicationInstanceManager.Entries[applicationInstanceId].Certificate.Value; + + return Result.Success; + } + } +} diff --git a/src/Ryujinx.Horizon/Arp/Ipc/Registrar.cs b/src/Ryujinx.Horizon/Arp/Ipc/Registrar.cs new file mode 100644 index 000000000..841ab7601 --- /dev/null +++ b/src/Ryujinx.Horizon/Arp/Ipc/Registrar.cs @@ -0,0 +1,52 @@ +using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Sdk.Arp; +using Ryujinx.Horizon.Sdk.Arp.Detail; +using Ryujinx.Horizon.Sdk.Ns; +using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf.Hipc; +using System; + +namespace Ryujinx.Horizon.Arp.Ipc +{ + partial class Registrar : IRegistrar, IServiceObject + { + private readonly ApplicationInstance _applicationInstance; + + public Registrar(ApplicationInstance applicationInstance) + { + _applicationInstance = applicationInstance; + } + + [CmifCommand(0)] + public Result Issue(out ulong applicationInstanceId) + { + throw new NotImplementedException(); + } + + [CmifCommand(1)] + public Result SetApplicationLaunchProperty(ApplicationLaunchProperty applicationLaunchProperty) + { + if (_applicationInstance.LaunchProperty != null) + { + return ArpResult.DataAlreadyBound; + } + + _applicationInstance.LaunchProperty = applicationLaunchProperty; + + return Result.Success; + } + + [CmifCommand(2)] + public Result SetApplicationControlProperty([Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias | HipcBufferFlags.FixedSize, 0x4000)] in ApplicationControlProperty applicationControlProperty) + { + if (_applicationInstance.ControlProperty != null) + { + return ArpResult.DataAlreadyBound; + } + + _applicationInstance.ControlProperty = applicationControlProperty; + + return Result.Success; + } + } +} diff --git a/src/Ryujinx.Horizon/Arp/Ipc/UnregistrationNotifier.cs b/src/Ryujinx.Horizon/Arp/Ipc/UnregistrationNotifier.cs new file mode 100644 index 000000000..49f2b1cce --- /dev/null +++ b/src/Ryujinx.Horizon/Arp/Ipc/UnregistrationNotifier.cs @@ -0,0 +1,25 @@ +using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Sdk.Arp; +using Ryujinx.Horizon.Sdk.Arp.Detail; +using Ryujinx.Horizon.Sdk.Sf; + +namespace Ryujinx.Horizon.Arp.Ipc +{ + partial class UnregistrationNotifier : IUnregistrationNotifier, IServiceObject + { + private readonly ApplicationInstanceManager _applicationInstanceManager; + + public UnregistrationNotifier(ApplicationInstanceManager applicationInstanceManager) + { + _applicationInstanceManager = applicationInstanceManager; + } + + [CmifCommand(0)] + public Result GetReadableHandle([CopyHandle] out int readableHandle) + { + readableHandle = _applicationInstanceManager.EventHandle; + + return Result.Success; + } + } +} diff --git a/src/Ryujinx.Horizon/Arp/Ipc/Updater.cs b/src/Ryujinx.Horizon/Arp/Ipc/Updater.cs new file mode 100644 index 000000000..f7531d712 --- /dev/null +++ b/src/Ryujinx.Horizon/Arp/Ipc/Updater.cs @@ -0,0 +1,74 @@ +using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Sdk.Arp; +using Ryujinx.Horizon.Sdk.Arp.Detail; +using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf.Hipc; +using System; + +namespace Ryujinx.Horizon.Arp.Ipc +{ + partial class Updater : IUpdater, IServiceObject + { + private readonly ApplicationInstanceManager _applicationInstanceManager; + private readonly ulong _applicationInstanceId; + private readonly bool _forCertificate; + + public Updater(ApplicationInstanceManager applicationInstanceManager, ulong applicationInstanceId, bool forCertificate) + { + _applicationInstanceManager = applicationInstanceManager; + _applicationInstanceId = applicationInstanceId; + _forCertificate = forCertificate; + } + + [CmifCommand(0)] + public Result Issue() + { + throw new NotImplementedException(); + } + + [CmifCommand(1)] + public Result SetApplicationProcessProperty(ulong pid, ApplicationProcessProperty applicationProcessProperty) + { + if (_forCertificate) + { + return ArpResult.DataAlreadyBound; + } + + if (pid == 0) + { + return ArpResult.InvalidPid; + } + + _applicationInstanceManager.Entries[_applicationInstanceId].Pid = pid; + _applicationInstanceManager.Entries[_applicationInstanceId].ProcessProperty = applicationProcessProperty; + + return Result.Success; + } + + [CmifCommand(2)] + public Result DeleteApplicationProcessProperty() + { + if (_forCertificate) + { + return ArpResult.DataAlreadyBound; + } + + _applicationInstanceManager.Entries[_applicationInstanceId].ProcessProperty = new ApplicationProcessProperty(); + + return Result.Success; + } + + [CmifCommand(3)] + public Result SetApplicationCertificate([Buffer(HipcBufferFlags.In | HipcBufferFlags.AutoSelect)] ApplicationCertificate applicationCertificate) + { + if (!_forCertificate) + { + return ArpResult.DataAlreadyBound; + } + + _applicationInstanceManager.Entries[_applicationInstanceId].Certificate = applicationCertificate; + + return Result.Success; + } + } +} diff --git a/src/Ryujinx.Horizon/Arp/Ipc/Writer.cs b/src/Ryujinx.Horizon/Arp/Ipc/Writer.cs new file mode 100644 index 000000000..29c98b779 --- /dev/null +++ b/src/Ryujinx.Horizon/Arp/Ipc/Writer.cs @@ -0,0 +1,75 @@ +using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Sdk.Arp; +using Ryujinx.Horizon.Sdk.Arp.Detail; +using Ryujinx.Horizon.Sdk.OsTypes; +using Ryujinx.Horizon.Sdk.Sf; + +namespace Ryujinx.Horizon.Arp.Ipc +{ + partial class Writer : IWriter, IServiceObject + { + private readonly ApplicationInstanceManager _applicationInstanceManager; + + public Writer(ApplicationInstanceManager applicationInstanceManager) + { + _applicationInstanceManager = applicationInstanceManager; + } + + [CmifCommand(0)] + public Result AcquireRegistrar(out IRegistrar registrar) + { + if (_applicationInstanceManager.Entries[0] != null) + { + if (_applicationInstanceManager.Entries[1] != null) + { + registrar = null; + + return ArpResult.NoFreeInstance; + } + else + { + _applicationInstanceManager.Entries[1] = new ApplicationInstance(); + + registrar = new Registrar(_applicationInstanceManager.Entries[1]); + } + } + else + { + _applicationInstanceManager.Entries[0] = new ApplicationInstance(); + + registrar = new Registrar(_applicationInstanceManager.Entries[0]); + } + + return Result.Success; + } + + [CmifCommand(1)] + public Result UnregisterApplicationInstance(ulong applicationInstanceId) + { + if (_applicationInstanceManager.Entries[applicationInstanceId] != null) + { + _applicationInstanceManager.Entries[applicationInstanceId] = null; + } + + Os.SignalSystemEvent(ref _applicationInstanceManager.SystemEvent); + + return Result.Success; + } + + [CmifCommand(2)] + public Result AcquireApplicationProcessPropertyUpdater(out IUpdater updater, ulong applicationInstanceId) + { + updater = new Updater(_applicationInstanceManager, applicationInstanceId, false); + + return Result.Success; + } + + [CmifCommand(3)] + public Result AcquireApplicationCertificateUpdater(out IUpdater updater, ulong applicationInstanceId) + { + updater = new Updater(_applicationInstanceManager, applicationInstanceId, true); + + return Result.Success; + } + } +} diff --git a/src/Ryujinx.Horizon/Bcat/BcatIpcServer.cs b/src/Ryujinx.Horizon/Bcat/BcatIpcServer.cs index 5d01cd9de..dd4e5b53a 100644 --- a/src/Ryujinx.Horizon/Bcat/BcatIpcServer.cs +++ b/src/Ryujinx.Horizon/Bcat/BcatIpcServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Bcat.Types; +using Ryujinx.Horizon.Bcat.Types; using Ryujinx.Horizon.Sdk.Sf.Hipc; using Ryujinx.Horizon.Sdk.Sm; diff --git a/src/Ryujinx.Horizon/Bcat/BcatMain.cs b/src/Ryujinx.Horizon/Bcat/BcatMain.cs index f347e2166..ac10d235e 100644 --- a/src/Ryujinx.Horizon/Bcat/BcatMain.cs +++ b/src/Ryujinx.Horizon/Bcat/BcatMain.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Bcat +namespace Ryujinx.Horizon.Bcat { internal class BcatMain : IService { diff --git a/src/Ryujinx.Horizon/Bcat/BcatServerManager.cs b/src/Ryujinx.Horizon/Bcat/BcatServerManager.cs index 0431bd9a9..31ac967b4 100644 --- a/src/Ryujinx.Horizon/Bcat/BcatServerManager.cs +++ b/src/Ryujinx.Horizon/Bcat/BcatServerManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Bcat.Ipc; +using Ryujinx.Horizon.Bcat.Ipc; using Ryujinx.Horizon.Bcat.Types; using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf.Hipc; diff --git a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator.cs b/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator.cs index 7dfa419d6..78114c51f 100644 --- a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator.cs +++ b/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator.cs @@ -1,4 +1,4 @@ -using LibHac.Common; +using LibHac.Common; using Ryujinx.Horizon.Bcat.Types; using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Bcat; diff --git a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/BcatService.cs b/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/BcatService.cs index 9ea2dc11c..91beec20d 100644 --- a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/BcatService.cs +++ b/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/BcatService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Bcat.Types; +using Ryujinx.Horizon.Bcat.Types; using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Bcat; using Ryujinx.Horizon.Sdk.Sf; diff --git a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheDirectoryService.cs b/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheDirectoryService.cs index c8b38c28f..1559c833c 100644 --- a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheDirectoryService.cs +++ b/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheDirectoryService.cs @@ -1,4 +1,4 @@ -using LibHac.Bcat; +using LibHac.Bcat; using LibHac.Common; using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Bcat; diff --git a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheFileService.cs b/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheFileService.cs index a26c3258f..bd5c418d9 100644 --- a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheFileService.cs +++ b/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheFileService.cs @@ -1,4 +1,4 @@ -using LibHac.Bcat; +using LibHac.Bcat; using LibHac.Common; using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Bcat; diff --git a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheProgressService.cs b/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheProgressService.cs index 578c18f43..a21d140e8 100644 --- a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheProgressService.cs +++ b/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheProgressService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Horizon.Bcat.Ipc.Types; using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Bcat; diff --git a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheStorageService.cs b/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheStorageService.cs index 9507a8a0e..ecbc4bdb7 100644 --- a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheStorageService.cs +++ b/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheStorageService.cs @@ -1,4 +1,4 @@ -using LibHac.Bcat; +using LibHac.Bcat; using LibHac.Common; using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Bcat; diff --git a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/Types/DeliveryCacheProgressImpl.cs b/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/Types/DeliveryCacheProgressImpl.cs index 9e5274a61..dcd86cbfc 100644 --- a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/Types/DeliveryCacheProgressImpl.cs +++ b/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/Types/DeliveryCacheProgressImpl.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Ryujinx.Horizon.Bcat.Ipc.Types { diff --git a/src/Ryujinx.Horizon/Bcat/Types/BcatPortIndex.cs b/src/Ryujinx.Horizon/Bcat/Types/BcatPortIndex.cs index 958517892..942cacdf4 100644 --- a/src/Ryujinx.Horizon/Bcat/Types/BcatPortIndex.cs +++ b/src/Ryujinx.Horizon/Bcat/Types/BcatPortIndex.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Bcat.Types +namespace Ryujinx.Horizon.Bcat.Types { enum BcatPortIndex { diff --git a/src/Ryujinx.Horizon/Bcat/Types/BcatServicePermissionLevel.cs b/src/Ryujinx.Horizon/Bcat/Types/BcatServicePermissionLevel.cs index 6bf4b4cc0..e45f986ac 100644 --- a/src/Ryujinx.Horizon/Bcat/Types/BcatServicePermissionLevel.cs +++ b/src/Ryujinx.Horizon/Bcat/Types/BcatServicePermissionLevel.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Bcat.Types +namespace Ryujinx.Horizon.Bcat.Types { enum BcatServicePermissionLevel { diff --git a/src/Ryujinx.Horizon/Friends/FriendsIpcServer.cs b/src/Ryujinx.Horizon/Friends/FriendsIpcServer.cs new file mode 100644 index 000000000..523c617a8 --- /dev/null +++ b/src/Ryujinx.Horizon/Friends/FriendsIpcServer.cs @@ -0,0 +1,49 @@ +using Ryujinx.Horizon.Sdk.Sf.Hipc; +using Ryujinx.Horizon.Sdk.Sm; + +namespace Ryujinx.Horizon.Friends +{ + class FriendsIpcServer + { + private const int MaxSessionsCount = 8; + private const int TotalMaxSessionsCount = MaxSessionsCount * 5; + + private const int PointerBufferSize = 0xA00; + private const int MaxDomains = 64; + private const int MaxDomainObjects = 16; + private const int MaxPortsCount = 5; + + private static readonly ManagerOptions _managerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false); + + private SmApi _sm; + private FriendsServerManager _serverManager; + + public void Initialize() + { + HeapAllocator allocator = new(); + + _sm = new SmApi(); + _sm.Initialize().AbortOnFailure(); + + _serverManager = new FriendsServerManager(allocator, _sm, MaxPortsCount, _managerOptions, TotalMaxSessionsCount); + +#pragma warning disable IDE0055 // Disable formatting + _serverManager.RegisterServer((int)FriendsPortIndex.Admin, ServiceName.Encode("friend:a"), MaxSessionsCount); + _serverManager.RegisterServer((int)FriendsPortIndex.User, ServiceName.Encode("friend:u"), MaxSessionsCount); + _serverManager.RegisterServer((int)FriendsPortIndex.Viewer, ServiceName.Encode("friend:v"), MaxSessionsCount); + _serverManager.RegisterServer((int)FriendsPortIndex.Manager, ServiceName.Encode("friend:m"), MaxSessionsCount); + _serverManager.RegisterServer((int)FriendsPortIndex.System, ServiceName.Encode("friend:s"), MaxSessionsCount); +#pragma warning restore IDE0055 + } + + public void ServiceRequests() + { + _serverManager.ServiceRequests(); + } + + public void Shutdown() + { + _serverManager.Dispose(); + } + } +} diff --git a/src/Ryujinx.Horizon/Friends/FriendsMain.cs b/src/Ryujinx.Horizon/Friends/FriendsMain.cs new file mode 100644 index 000000000..0f119cf01 --- /dev/null +++ b/src/Ryujinx.Horizon/Friends/FriendsMain.cs @@ -0,0 +1,17 @@ +namespace Ryujinx.Horizon.Friends +{ + class FriendsMain : IService + { + public static void Main(ServiceTable serviceTable) + { + FriendsIpcServer ipcServer = new(); + + ipcServer.Initialize(); + + serviceTable.SignalServiceReady(); + + ipcServer.ServiceRequests(); + ipcServer.Shutdown(); + } + } +} diff --git a/src/Ryujinx.Horizon/Friends/FriendsPortIndex.cs b/src/Ryujinx.Horizon/Friends/FriendsPortIndex.cs new file mode 100644 index 000000000..f567db302 --- /dev/null +++ b/src/Ryujinx.Horizon/Friends/FriendsPortIndex.cs @@ -0,0 +1,11 @@ +namespace Ryujinx.Horizon.Friends +{ + enum FriendsPortIndex + { + Admin, + User, + Viewer, + Manager, + System, + } +} diff --git a/src/Ryujinx.Horizon/Friends/FriendsServerManager.cs b/src/Ryujinx.Horizon/Friends/FriendsServerManager.cs new file mode 100644 index 000000000..5026206b7 --- /dev/null +++ b/src/Ryujinx.Horizon/Friends/FriendsServerManager.cs @@ -0,0 +1,36 @@ +using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Sdk.Account; +using Ryujinx.Horizon.Sdk.Friends.Detail.Ipc; +using Ryujinx.Horizon.Sdk.Sf.Hipc; +using Ryujinx.Horizon.Sdk.Sm; +using System; + +namespace Ryujinx.Horizon.Friends +{ + class FriendsServerManager : ServerManager + { + private readonly IEmulatorAccountManager _accountManager; + private readonly NotificationEventHandler _notificationEventHandler; + + public FriendsServerManager(HeapAllocator allocator, SmApi sm, int maxPorts, ManagerOptions options, int maxSessions) : base(allocator, sm, maxPorts, options, maxSessions) + { + _accountManager = HorizonStatic.Options.AccountManager; + _notificationEventHandler = new(); + } + + protected override Result OnNeedsToAccept(int portIndex, Server server) + { + return (FriendsPortIndex)portIndex switch + { +#pragma warning disable IDE0055 // Disable formatting + FriendsPortIndex.Admin => AcceptImpl(server, new ServiceCreator(_accountManager, _notificationEventHandler, FriendsServicePermissionLevel.Admin)), + FriendsPortIndex.User => AcceptImpl(server, new ServiceCreator(_accountManager, _notificationEventHandler, FriendsServicePermissionLevel.User)), + FriendsPortIndex.Viewer => AcceptImpl(server, new ServiceCreator(_accountManager, _notificationEventHandler, FriendsServicePermissionLevel.Viewer)), + FriendsPortIndex.Manager => AcceptImpl(server, new ServiceCreator(_accountManager, _notificationEventHandler, FriendsServicePermissionLevel.Manager)), + FriendsPortIndex.System => AcceptImpl(server, new ServiceCreator(_accountManager, _notificationEventHandler, FriendsServicePermissionLevel.System)), + _ => throw new ArgumentOutOfRangeException(nameof(portIndex)), +#pragma warning restore IDE0055 + }; + } + } +} diff --git a/src/Ryujinx.Horizon/HorizonOptions.cs b/src/Ryujinx.Horizon/HorizonOptions.cs index e3c862da4..794620569 100644 --- a/src/Ryujinx.Horizon/HorizonOptions.cs +++ b/src/Ryujinx.Horizon/HorizonOptions.cs @@ -1,4 +1,5 @@ using LibHac; +using Ryujinx.Horizon.Sdk.Account; using Ryujinx.Horizon.Sdk.Fs; namespace Ryujinx.Horizon @@ -10,13 +11,15 @@ namespace Ryujinx.Horizon public HorizonClient BcatClient { get; } public IFsClient FsClient { get; } + public IEmulatorAccountManager AccountManager { get; } - public HorizonOptions(bool ignoreMissingServices, HorizonClient bcatClient, IFsClient fsClient) + public HorizonOptions(bool ignoreMissingServices, HorizonClient bcatClient, IFsClient fsClient, IEmulatorAccountManager accountManager) { IgnoreMissingServices = ignoreMissingServices; ThrowOnInvalidCommandIds = true; BcatClient = bcatClient; FsClient = fsClient; + AccountManager = accountManager; } } } diff --git a/src/Ryujinx.Horizon/HorizonStatic.cs b/src/Ryujinx.Horizon/HorizonStatic.cs index 3e992eadb..305d54bd1 100644 --- a/src/Ryujinx.Horizon/HorizonStatic.cs +++ b/src/Ryujinx.Horizon/HorizonStatic.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Memory; using System; diff --git a/src/Ryujinx.Horizon/Hshl/HshlIpcServer.cs b/src/Ryujinx.Horizon/Hshl/HshlIpcServer.cs index 7182725cb..d7d89e24b 100644 --- a/src/Ryujinx.Horizon/Hshl/HshlIpcServer.cs +++ b/src/Ryujinx.Horizon/Hshl/HshlIpcServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Hshl.Ipc; +using Ryujinx.Horizon.Hshl.Ipc; using Ryujinx.Horizon.Sdk.Sf.Hipc; using Ryujinx.Horizon.Sdk.Sm; diff --git a/src/Ryujinx.Horizon/Hshl/HshlMain.cs b/src/Ryujinx.Horizon/Hshl/HshlMain.cs index 4e894b6f6..9c65f1ffd 100644 --- a/src/Ryujinx.Horizon/Hshl/HshlMain.cs +++ b/src/Ryujinx.Horizon/Hshl/HshlMain.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Hshl +namespace Ryujinx.Horizon.Hshl { class HshlMain : IService { diff --git a/src/Ryujinx.Horizon/Hshl/Ipc/Manager.cs b/src/Ryujinx.Horizon/Hshl/Ipc/Manager.cs index 29d9069ac..26e901c42 100644 --- a/src/Ryujinx.Horizon/Hshl/Ipc/Manager.cs +++ b/src/Ryujinx.Horizon/Hshl/Ipc/Manager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Hshl; +using Ryujinx.Horizon.Sdk.Hshl; namespace Ryujinx.Horizon.Hshl.Ipc { diff --git a/src/Ryujinx.Horizon/Hshl/Ipc/SetterManager.cs b/src/Ryujinx.Horizon/Hshl/Ipc/SetterManager.cs index ac1006f0f..d85a70647 100644 --- a/src/Ryujinx.Horizon/Hshl/Ipc/SetterManager.cs +++ b/src/Ryujinx.Horizon/Hshl/Ipc/SetterManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Hshl; +using Ryujinx.Horizon.Sdk.Hshl; namespace Ryujinx.Horizon.Hshl.Ipc { diff --git a/src/Ryujinx.Horizon/IService.cs b/src/Ryujinx.Horizon/IService.cs index c0bc0bcb7..2bc15b120 100644 --- a/src/Ryujinx.Horizon/IService.cs +++ b/src/Ryujinx.Horizon/IService.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon +namespace Ryujinx.Horizon { interface IService { diff --git a/src/Ryujinx.Horizon/Ins/InsIpcServer.cs b/src/Ryujinx.Horizon/Ins/InsIpcServer.cs index 68698bf6a..bb2749d5f 100644 --- a/src/Ryujinx.Horizon/Ins/InsIpcServer.cs +++ b/src/Ryujinx.Horizon/Ins/InsIpcServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Ins.Ipc; +using Ryujinx.Horizon.Ins.Ipc; using Ryujinx.Horizon.Sdk.Sf.Hipc; using Ryujinx.Horizon.Sdk.Sm; diff --git a/src/Ryujinx.Horizon/Ins/InsMain.cs b/src/Ryujinx.Horizon/Ins/InsMain.cs index e428d090a..101bf9b0b 100644 --- a/src/Ryujinx.Horizon/Ins/InsMain.cs +++ b/src/Ryujinx.Horizon/Ins/InsMain.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Ins +namespace Ryujinx.Horizon.Ins { class InsMain : IService { diff --git a/src/Ryujinx.Horizon/Ins/Ipc/ReceiverManager.cs b/src/Ryujinx.Horizon/Ins/Ipc/ReceiverManager.cs index 6e9b29a99..b5f44801a 100644 --- a/src/Ryujinx.Horizon/Ins/Ipc/ReceiverManager.cs +++ b/src/Ryujinx.Horizon/Ins/Ipc/ReceiverManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Ins; +using Ryujinx.Horizon.Sdk.Ins; namespace Ryujinx.Horizon.Ins.Ipc { diff --git a/src/Ryujinx.Horizon/Ins/Ipc/SenderManager.cs b/src/Ryujinx.Horizon/Ins/Ipc/SenderManager.cs index e133014e1..7407ada7d 100644 --- a/src/Ryujinx.Horizon/Ins/Ipc/SenderManager.cs +++ b/src/Ryujinx.Horizon/Ins/Ipc/SenderManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Ins; +using Ryujinx.Horizon.Sdk.Ins; namespace Ryujinx.Horizon.Ins.Ipc { diff --git a/src/Ryujinx.Horizon/Lbl/Ipc/LblController.cs b/src/Ryujinx.Horizon/Lbl/Ipc/LblController.cs index 0a27d5efa..2c97476c8 100644 --- a/src/Ryujinx.Horizon/Lbl/Ipc/LblController.cs +++ b/src/Ryujinx.Horizon/Lbl/Ipc/LblController.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Lbl; using Ryujinx.Horizon.Sdk.Sf; diff --git a/src/Ryujinx.Horizon/Lbl/LblIpcServer.cs b/src/Ryujinx.Horizon/Lbl/LblIpcServer.cs index 53e74d515..6b5421653 100644 --- a/src/Ryujinx.Horizon/Lbl/LblIpcServer.cs +++ b/src/Ryujinx.Horizon/Lbl/LblIpcServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Lbl.Ipc; +using Ryujinx.Horizon.Lbl.Ipc; using Ryujinx.Horizon.Sdk.Sf.Hipc; using Ryujinx.Horizon.Sdk.Sm; diff --git a/src/Ryujinx.Horizon/Lbl/LblMain.cs b/src/Ryujinx.Horizon/Lbl/LblMain.cs index f471f31b7..ab1e67ac6 100644 --- a/src/Ryujinx.Horizon/Lbl/LblMain.cs +++ b/src/Ryujinx.Horizon/Lbl/LblMain.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Lbl +namespace Ryujinx.Horizon.Lbl { class LblMain : IService { diff --git a/src/Ryujinx.Horizon/LibHacResultExtensions.cs b/src/Ryujinx.Horizon/LibHacResultExtensions.cs index 8c994f149..2abed197d 100644 --- a/src/Ryujinx.Horizon/LibHacResultExtensions.cs +++ b/src/Ryujinx.Horizon/LibHacResultExtensions.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; namespace Ryujinx.Horizon { diff --git a/src/Ryujinx.Horizon/LogManager/Ipc/LogService.cs b/src/Ryujinx.Horizon/LogManager/Ipc/LogService.cs index c266d0e94..8ed5d99d0 100644 --- a/src/Ryujinx.Horizon/LogManager/Ipc/LogService.cs +++ b/src/Ryujinx.Horizon/LogManager/Ipc/LogService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Lm; using Ryujinx.Horizon.Sdk.Sf; diff --git a/src/Ryujinx.Horizon/LogManager/LmIpcServer.cs b/src/Ryujinx.Horizon/LogManager/LmIpcServer.cs index 6bdc3c429..d023ff927 100644 --- a/src/Ryujinx.Horizon/LogManager/LmIpcServer.cs +++ b/src/Ryujinx.Horizon/LogManager/LmIpcServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.LogManager.Ipc; +using Ryujinx.Horizon.LogManager.Ipc; using Ryujinx.Horizon.Sdk.Sf.Hipc; using Ryujinx.Horizon.Sdk.Sm; diff --git a/src/Ryujinx.Horizon/LogManager/LmMain.cs b/src/Ryujinx.Horizon/LogManager/LmMain.cs index c229de597..ac3cd4bb9 100644 --- a/src/Ryujinx.Horizon/LogManager/LmMain.cs +++ b/src/Ryujinx.Horizon/LogManager/LmMain.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.LogManager +namespace Ryujinx.Horizon.LogManager { class LmMain : IService { diff --git a/src/Ryujinx.Horizon/LogManager/Types/LogPacket.cs b/src/Ryujinx.Horizon/LogManager/Types/LogPacket.cs index 57a389be9..b4294d66a 100644 --- a/src/Ryujinx.Horizon/LogManager/Types/LogPacket.cs +++ b/src/Ryujinx.Horizon/LogManager/Types/LogPacket.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Diag; +using Ryujinx.Horizon.Sdk.Diag; using System.Text; namespace Ryujinx.Horizon.LogManager.Types diff --git a/src/Ryujinx.Horizon/MmNv/Ipc/Request.cs b/src/Ryujinx.Horizon/MmNv/Ipc/Request.cs index 9a24c75e8..c53ca1866 100644 --- a/src/Ryujinx.Horizon/MmNv/Ipc/Request.cs +++ b/src/Ryujinx.Horizon/MmNv/Ipc/Request.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.MmNv; using Ryujinx.Horizon.Sdk.Sf; diff --git a/src/Ryujinx.Horizon/MmNv/MmNvIpcServer.cs b/src/Ryujinx.Horizon/MmNv/MmNvIpcServer.cs index b6615d2cd..c52a294f5 100644 --- a/src/Ryujinx.Horizon/MmNv/MmNvIpcServer.cs +++ b/src/Ryujinx.Horizon/MmNv/MmNvIpcServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.MmNv.Ipc; +using Ryujinx.Horizon.MmNv.Ipc; using Ryujinx.Horizon.Sdk.Sf.Hipc; using Ryujinx.Horizon.Sdk.Sm; diff --git a/src/Ryujinx.Horizon/MmNv/MmNvMain.cs b/src/Ryujinx.Horizon/MmNv/MmNvMain.cs index ac5eff1a9..a5a7b6309 100644 --- a/src/Ryujinx.Horizon/MmNv/MmNvMain.cs +++ b/src/Ryujinx.Horizon/MmNv/MmNvMain.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.MmNv +namespace Ryujinx.Horizon.MmNv { class MmNvMain : IService { diff --git a/src/Ryujinx.Horizon/Ovln/Ipc/ReceiverService.cs b/src/Ryujinx.Horizon/Ovln/Ipc/ReceiverService.cs index 6cc448e8a..b74d3cd2b 100644 --- a/src/Ryujinx.Horizon/Ovln/Ipc/ReceiverService.cs +++ b/src/Ryujinx.Horizon/Ovln/Ipc/ReceiverService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Ovln; +using Ryujinx.Horizon.Sdk.Ovln; namespace Ryujinx.Horizon.Ovln.Ipc { diff --git a/src/Ryujinx.Horizon/Ovln/Ipc/SenderService.cs b/src/Ryujinx.Horizon/Ovln/Ipc/SenderService.cs index cab123ecf..04ef5d4b1 100644 --- a/src/Ryujinx.Horizon/Ovln/Ipc/SenderService.cs +++ b/src/Ryujinx.Horizon/Ovln/Ipc/SenderService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Ovln; +using Ryujinx.Horizon.Sdk.Ovln; namespace Ryujinx.Horizon.Ovln.Ipc { diff --git a/src/Ryujinx.Horizon/Ovln/OvlnIpcServer.cs b/src/Ryujinx.Horizon/Ovln/OvlnIpcServer.cs index 2c00107fb..c4580a861 100644 --- a/src/Ryujinx.Horizon/Ovln/OvlnIpcServer.cs +++ b/src/Ryujinx.Horizon/Ovln/OvlnIpcServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Ovln.Ipc; +using Ryujinx.Horizon.Ovln.Ipc; using Ryujinx.Horizon.Sdk.Sf.Hipc; using Ryujinx.Horizon.Sdk.Sm; diff --git a/src/Ryujinx.Horizon/Ovln/OvlnMain.cs b/src/Ryujinx.Horizon/Ovln/OvlnMain.cs index 8c6cf84e7..79afad20e 100644 --- a/src/Ryujinx.Horizon/Ovln/OvlnMain.cs +++ b/src/Ryujinx.Horizon/Ovln/OvlnMain.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Ovln +namespace Ryujinx.Horizon.Ovln { class OvlnMain : IService { diff --git a/src/Ryujinx.Horizon/Prepo/Ipc/PrepoService.cs b/src/Ryujinx.Horizon/Prepo/Ipc/PrepoService.cs index f424b17e2..4ed7dd48e 100644 --- a/src/Ryujinx.Horizon/Prepo/Ipc/PrepoService.cs +++ b/src/Ryujinx.Horizon/Prepo/Ipc/PrepoService.cs @@ -1,10 +1,11 @@ -using MsgPack; +using MsgPack; using MsgPack.Serialization; using Ryujinx.Common.Logging; using Ryujinx.Common.Utilities; using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Prepo.Types; using Ryujinx.Horizon.Sdk.Account; +using Ryujinx.Horizon.Sdk.Arp; using Ryujinx.Horizon.Sdk.Prepo; using Ryujinx.Horizon.Sdk.Sf; using Ryujinx.Horizon.Sdk.Sf.Hipc; @@ -22,14 +23,16 @@ namespace Ryujinx.Horizon.Prepo.Ipc System, } + private readonly ArpApi _arp; private readonly PrepoServicePermissionLevel _permissionLevel; private ulong _systemSessionId; private bool _immediateTransmissionEnabled; private bool _userAgreementCheckEnabled = true; - public PrepoService(PrepoServicePermissionLevel permissionLevel) + public PrepoService(ArpApi arp, PrepoServicePermissionLevel permissionLevel) { + _arp = arp; _permissionLevel = permissionLevel; } @@ -165,7 +168,7 @@ namespace Ryujinx.Horizon.Prepo.Ipc return PrepoResult.PermissionDenied; } - private static Result ProcessPlayReport(PlayReportKind playReportKind, ReadOnlySpan gameRoomBuffer, ReadOnlySpan reportBuffer, ulong pid, Uid userId, bool withUserId = false, ApplicationId applicationId = default) + private Result ProcessPlayReport(PlayReportKind playReportKind, ReadOnlySpan gameRoomBuffer, ReadOnlySpan reportBuffer, ulong pid, Uid userId, bool withUserId = false, ApplicationId applicationId = default) { if (withUserId) { @@ -199,8 +202,8 @@ namespace Ryujinx.Horizon.Prepo.Ipc builder.AppendLine("PlayReport log:"); builder.AppendLine($" Kind: {playReportKind}"); - // NOTE: The service calls arp:r using the pid to get the application id, if it fails PrepoResult.InvalidPid is returned. - // Reports are stored internally and an event is signaled to transmit them. + // NOTE: Reports are stored internally and an event is signaled to transmit them. + if (pid != 0) { builder.AppendLine($" Pid: {pid}"); @@ -210,6 +213,16 @@ namespace Ryujinx.Horizon.Prepo.Ipc builder.AppendLine($" ApplicationId: {applicationId}"); } + Result result = _arp.GetApplicationInstanceId(out ulong applicationInstanceId, pid); + if (result.IsFailure) + { + return PrepoResult.InvalidPid; + } + + _arp.GetApplicationLaunchProperty(out ApplicationLaunchProperty applicationLaunchProperty, applicationInstanceId).AbortOnFailure(); + + builder.AppendLine($" ApplicationVersion: {applicationLaunchProperty.Version}"); + if (!userId.IsNull) { builder.AppendLine($" UserId: {userId}"); diff --git a/src/Ryujinx.Horizon/Prepo/PrepoIpcServer.cs b/src/Ryujinx.Horizon/Prepo/PrepoIpcServer.cs index 410f997e7..1902cde23 100644 --- a/src/Ryujinx.Horizon/Prepo/PrepoIpcServer.cs +++ b/src/Ryujinx.Horizon/Prepo/PrepoIpcServer.cs @@ -1,4 +1,5 @@ -using Ryujinx.Horizon.Prepo.Types; +using Ryujinx.Horizon.Prepo.Types; +using Ryujinx.Horizon.Sdk.Arp; using Ryujinx.Horizon.Sdk.Sf.Hipc; using Ryujinx.Horizon.Sdk.Sm; @@ -17,16 +18,19 @@ namespace Ryujinx.Horizon.Prepo private static readonly ManagerOptions _managerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false); private SmApi _sm; + private ArpApi _arp; private PrepoServerManager _serverManager; public void Initialize() { HeapAllocator allocator = new(); + _arp = new ArpApi(allocator); + _sm = new SmApi(); _sm.Initialize().AbortOnFailure(); - _serverManager = new PrepoServerManager(allocator, _sm, MaxPortsCount, _managerOptions, TotalMaxSessionsCount); + _serverManager = new PrepoServerManager(allocator, _sm, _arp, MaxPortsCount, _managerOptions, TotalMaxSessionsCount); #pragma warning disable IDE0055 // Disable formatting _serverManager.RegisterServer((int)PrepoPortIndex.Admin, ServiceName.Encode("prepo:a"), MaxSessionsCount); // 1.0.0-5.1.0 @@ -45,6 +49,7 @@ namespace Ryujinx.Horizon.Prepo public void Shutdown() { + _arp.Dispose(); _serverManager.Dispose(); } } diff --git a/src/Ryujinx.Horizon/Prepo/PrepoMain.cs b/src/Ryujinx.Horizon/Prepo/PrepoMain.cs index c311d619f..8d54af9d5 100644 --- a/src/Ryujinx.Horizon/Prepo/PrepoMain.cs +++ b/src/Ryujinx.Horizon/Prepo/PrepoMain.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Prepo +namespace Ryujinx.Horizon.Prepo { class PrepoMain : IService { diff --git a/src/Ryujinx.Horizon/Prepo/PrepoResult.cs b/src/Ryujinx.Horizon/Prepo/PrepoResult.cs index 4c6bc7a45..24e46d0c7 100644 --- a/src/Ryujinx.Horizon/Prepo/PrepoResult.cs +++ b/src/Ryujinx.Horizon/Prepo/PrepoResult.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; namespace Ryujinx.Horizon.Prepo { diff --git a/src/Ryujinx.Horizon/Prepo/PrepoServerManager.cs b/src/Ryujinx.Horizon/Prepo/PrepoServerManager.cs index a79360953..8cac44c8f 100644 --- a/src/Ryujinx.Horizon/Prepo/PrepoServerManager.cs +++ b/src/Ryujinx.Horizon/Prepo/PrepoServerManager.cs @@ -1,6 +1,7 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Prepo.Ipc; using Ryujinx.Horizon.Prepo.Types; +using Ryujinx.Horizon.Sdk.Arp; using Ryujinx.Horizon.Sdk.Sf.Hipc; using Ryujinx.Horizon.Sdk.Sm; using System; @@ -9,8 +10,11 @@ namespace Ryujinx.Horizon.Prepo { class PrepoServerManager : ServerManager { - public PrepoServerManager(HeapAllocator allocator, SmApi sm, int maxPorts, ManagerOptions options, int maxSessions) : base(allocator, sm, maxPorts, options, maxSessions) + private readonly ArpApi _arp; + + public PrepoServerManager(HeapAllocator allocator, SmApi sm, ArpApi arp, int maxPorts, ManagerOptions options, int maxSessions) : base(allocator, sm, maxPorts, options, maxSessions) { + _arp = arp; } protected override Result OnNeedsToAccept(int portIndex, Server server) @@ -18,12 +22,12 @@ namespace Ryujinx.Horizon.Prepo return (PrepoPortIndex)portIndex switch { #pragma warning disable IDE0055 // Disable formatting - PrepoPortIndex.Admin => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.Admin)), - PrepoPortIndex.Admin2 => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.Admin)), - PrepoPortIndex.Manager => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.Manager)), - PrepoPortIndex.User => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.User)), - PrepoPortIndex.System => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.System)), - PrepoPortIndex.Debug => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.Debug)), + PrepoPortIndex.Admin => AcceptImpl(server, new PrepoService(_arp, PrepoServicePermissionLevel.Admin)), + PrepoPortIndex.Admin2 => AcceptImpl(server, new PrepoService(_arp, PrepoServicePermissionLevel.Admin)), + PrepoPortIndex.Manager => AcceptImpl(server, new PrepoService(_arp, PrepoServicePermissionLevel.Manager)), + PrepoPortIndex.User => AcceptImpl(server, new PrepoService(_arp, PrepoServicePermissionLevel.User)), + PrepoPortIndex.System => AcceptImpl(server, new PrepoService(_arp, PrepoServicePermissionLevel.System)), + PrepoPortIndex.Debug => AcceptImpl(server, new PrepoService(_arp, PrepoServicePermissionLevel.Debug)), _ => throw new ArgumentOutOfRangeException(nameof(portIndex)), #pragma warning restore IDE0055 }; diff --git a/src/Ryujinx.Horizon/Prepo/Types/PrepoPortIndex.cs b/src/Ryujinx.Horizon/Prepo/Types/PrepoPortIndex.cs index 31c5b02d0..b8242baea 100644 --- a/src/Ryujinx.Horizon/Prepo/Types/PrepoPortIndex.cs +++ b/src/Ryujinx.Horizon/Prepo/Types/PrepoPortIndex.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Prepo.Types +namespace Ryujinx.Horizon.Prepo.Types { enum PrepoPortIndex { diff --git a/src/Ryujinx.Horizon/Prepo/Types/PrepoServicePermissionLevel.cs b/src/Ryujinx.Horizon/Prepo/Types/PrepoServicePermissionLevel.cs index 759c5018d..7a8073549 100644 --- a/src/Ryujinx.Horizon/Prepo/Types/PrepoServicePermissionLevel.cs +++ b/src/Ryujinx.Horizon/Prepo/Types/PrepoServicePermissionLevel.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Prepo.Types +namespace Ryujinx.Horizon.Prepo.Types { enum PrepoServicePermissionLevel { diff --git a/src/Ryujinx.Horizon/Psc/Ipc/PmControl.cs b/src/Ryujinx.Horizon/Psc/Ipc/PmControl.cs index 671472e4e..112a702f4 100644 --- a/src/Ryujinx.Horizon/Psc/Ipc/PmControl.cs +++ b/src/Ryujinx.Horizon/Psc/Ipc/PmControl.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Psc; +using Ryujinx.Horizon.Sdk.Psc; namespace Ryujinx.Horizon.Psc.Ipc { diff --git a/src/Ryujinx.Horizon/Psc/Ipc/PmService.cs b/src/Ryujinx.Horizon/Psc/Ipc/PmService.cs index c38da8581..cb2ea8d40 100644 --- a/src/Ryujinx.Horizon/Psc/Ipc/PmService.cs +++ b/src/Ryujinx.Horizon/Psc/Ipc/PmService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Psc; +using Ryujinx.Horizon.Sdk.Psc; namespace Ryujinx.Horizon.Psc.Ipc { diff --git a/src/Ryujinx.Horizon/Psc/Ipc/PmStateLock.cs b/src/Ryujinx.Horizon/Psc/Ipc/PmStateLock.cs index cef68ac54..5c7961806 100644 --- a/src/Ryujinx.Horizon/Psc/Ipc/PmStateLock.cs +++ b/src/Ryujinx.Horizon/Psc/Ipc/PmStateLock.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Psc; +using Ryujinx.Horizon.Sdk.Psc; namespace Ryujinx.Horizon.Psc.Ipc { diff --git a/src/Ryujinx.Horizon/Psc/PscIpcServer.cs b/src/Ryujinx.Horizon/Psc/PscIpcServer.cs index f8da56724..d6ac65685 100644 --- a/src/Ryujinx.Horizon/Psc/PscIpcServer.cs +++ b/src/Ryujinx.Horizon/Psc/PscIpcServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Psc.Ipc; +using Ryujinx.Horizon.Psc.Ipc; using Ryujinx.Horizon.Sdk.Sf.Hipc; using Ryujinx.Horizon.Sdk.Sm; diff --git a/src/Ryujinx.Horizon/Psc/PscMain.cs b/src/Ryujinx.Horizon/Psc/PscMain.cs index facb6bc08..0b5316672 100644 --- a/src/Ryujinx.Horizon/Psc/PscMain.cs +++ b/src/Ryujinx.Horizon/Psc/PscMain.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Psc +namespace Ryujinx.Horizon.Psc { class PscMain : IService { diff --git a/src/Ryujinx.Horizon/Sdk/Account/IEmulatorAccountManager.cs b/src/Ryujinx.Horizon/Sdk/Account/IEmulatorAccountManager.cs new file mode 100644 index 000000000..af02cc8eb --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Account/IEmulatorAccountManager.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.Horizon.Sdk.Account +{ + public interface IEmulatorAccountManager + { + void OpenUserOnlinePlay(Uid userId); + void CloseUserOnlinePlay(Uid userId); + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Account/NetworkServiceAccountId.cs b/src/Ryujinx.Horizon/Sdk/Account/NetworkServiceAccountId.cs new file mode 100644 index 000000000..2512975e3 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Account/NetworkServiceAccountId.cs @@ -0,0 +1,20 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Account +{ + [StructLayout(LayoutKind.Sequential, Size = 0x8, Pack = 0x8)] + readonly record struct NetworkServiceAccountId + { + public readonly ulong Id; + + public NetworkServiceAccountId(ulong id) + { + Id = id; + } + + public override readonly string ToString() + { + return Id.ToString("x16"); + } + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Account/Nickname.cs b/src/Ryujinx.Horizon/Sdk/Account/Nickname.cs new file mode 100644 index 000000000..1f351ee3a --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Account/Nickname.cs @@ -0,0 +1,29 @@ +using Ryujinx.Common.Memory; +using System; +using System.Runtime.InteropServices; +using System.Text; + +namespace Ryujinx.Horizon.Sdk.Account +{ + [StructLayout(LayoutKind.Sequential, Size = 0x21, Pack = 0x1)] + readonly struct Nickname + { + public readonly Array33 Name; + + public Nickname(in Array33 name) + { + Name = name; + } + + public override string ToString() + { + int length = ((ReadOnlySpan)Name.AsSpan()).IndexOf((byte)0); + if (length < 0) + { + length = 33; + } + + return Encoding.UTF8.GetString(Name.AsSpan()[..length]); + } + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Account/Uid.cs b/src/Ryujinx.Horizon/Sdk/Account/Uid.cs index 0175d393c..ada2c02ba 100644 --- a/src/Ryujinx.Horizon/Sdk/Account/Uid.cs +++ b/src/Ryujinx.Horizon/Sdk/Account/Uid.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Linq; using System.Runtime.InteropServices; @@ -6,16 +6,16 @@ using System.Runtime.InteropServices; namespace Ryujinx.Horizon.Sdk.Account { [StructLayout(LayoutKind.Sequential)] - readonly record struct Uid + public readonly record struct Uid { - public readonly long High; - public readonly long Low; + public readonly ulong High; + public readonly ulong Low; public bool IsNull => (Low | High) == 0; public static Uid Null => new(0, 0); - public Uid(long low, long high) + public Uid(ulong low, ulong high) { Low = low; High = high; @@ -23,8 +23,8 @@ namespace Ryujinx.Horizon.Sdk.Account public Uid(byte[] bytes) { - High = BitConverter.ToInt64(bytes, 0); - Low = BitConverter.ToInt64(bytes, 8); + High = BitConverter.ToUInt64(bytes, 0); + Low = BitConverter.ToUInt64(bytes, 8); } public Uid(string hex) @@ -34,8 +34,8 @@ namespace Ryujinx.Horizon.Sdk.Account throw new ArgumentException("Invalid Hex value!", nameof(hex)); } - Low = Convert.ToInt64(hex[16..], 16); - High = Convert.ToInt64(hex[..16], 16); + Low = Convert.ToUInt64(hex[16..], 16); + High = Convert.ToUInt64(hex[..16], 16); } public void Write(BinaryWriter binaryWriter) diff --git a/src/Ryujinx.Horizon/Sdk/Arp/ApplicationCertificate.cs b/src/Ryujinx.Horizon/Sdk/Arp/ApplicationCertificate.cs new file mode 100644 index 000000000..d60d337d3 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Arp/ApplicationCertificate.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Arp +{ + [StructLayout(LayoutKind.Sequential, Size = 0x528)] + public struct ApplicationCertificate + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Arp/ApplicationKind.cs b/src/Ryujinx.Horizon/Sdk/Arp/ApplicationKind.cs new file mode 100644 index 000000000..586e6a98a --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Arp/ApplicationKind.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.Horizon.Sdk.Arp +{ + public enum ApplicationKind : byte + { + Application, + MicroApplication, + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Arp/ApplicationLaunchProperty.cs b/src/Ryujinx.Horizon/Sdk/Arp/ApplicationLaunchProperty.cs new file mode 100644 index 000000000..00b818321 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Arp/ApplicationLaunchProperty.cs @@ -0,0 +1,14 @@ +using Ryujinx.Horizon.Sdk.Ncm; + +namespace Ryujinx.Horizon.Sdk.Arp +{ + public struct ApplicationLaunchProperty + { + public ApplicationId ApplicationId; + public uint Version; + public StorageId Storage; + public StorageId PatchStorage; + public ApplicationKind ApplicationKind; + public byte Padding; + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Arp/ApplicationProcessProperty.cs b/src/Ryujinx.Horizon/Sdk/Arp/ApplicationProcessProperty.cs new file mode 100644 index 000000000..13d222a12 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Arp/ApplicationProcessProperty.cs @@ -0,0 +1,10 @@ +using Ryujinx.Common.Memory; + +namespace Ryujinx.Horizon.Sdk.Arp +{ + public struct ApplicationProcessProperty + { + public byte ProgramIndex; + public Array15 Unknown; + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Arp/ArpApi.cs b/src/Ryujinx.Horizon/Sdk/Arp/ArpApi.cs new file mode 100644 index 000000000..b0acc0062 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Arp/ArpApi.cs @@ -0,0 +1,130 @@ +using Ryujinx.Common.Memory; +using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Sdk.Ns; +using Ryujinx.Horizon.Sdk.Sf.Cmif; +using Ryujinx.Horizon.Sdk.Sf.Hipc; +using Ryujinx.Horizon.Sdk.Sm; +using System; +using System.Runtime.CompilerServices; + +namespace Ryujinx.Horizon.Sdk.Arp +{ + class ArpApi : IDisposable + { + private const string ArpRName = "arp:r"; + + private readonly HeapAllocator _allocator; + private int _sessionHandle; + + public ArpApi(HeapAllocator allocator) + { + _allocator = allocator; + } + + private void InitializeArpRService() + { + if (_sessionHandle == 0) + { + using var smApi = new SmApi(); + + smApi.Initialize(); + smApi.GetServiceHandle(out _sessionHandle, ServiceName.Encode(ArpRName)).AbortOnFailure(); + } + } + + public Result GetApplicationInstanceId(out ulong applicationInstanceId, ulong applicationPid) + { + Span data = stackalloc byte[8]; + SpanWriter writer = new(data); + + writer.Write(applicationPid); + + InitializeArpRService(); + + Result result = ServiceUtil.SendRequest(out CmifResponse response, _sessionHandle, 3, sendPid: false, data); + if (result.IsFailure) + { + applicationInstanceId = 0; + + return result; + } + + SpanReader reader = new(response.Data); + + applicationInstanceId = reader.Read(); + + return Result.Success; + } + + public Result GetApplicationLaunchProperty(out ApplicationLaunchProperty applicationLaunchProperty, ulong applicationInstanceId) + { + applicationLaunchProperty = default; + + Span data = stackalloc byte[8]; + SpanWriter writer = new(data); + + writer.Write(applicationInstanceId); + + InitializeArpRService(); + + Result result = ServiceUtil.SendRequest(out CmifResponse response, _sessionHandle, 0, sendPid: false, data); + if (result.IsFailure) + { + return result; + } + + SpanReader reader = new(response.Data); + + applicationLaunchProperty = reader.Read(); + + return Result.Success; + } + + public Result GetApplicationControlProperty(out ApplicationControlProperty applicationControlProperty, ulong applicationInstanceId) + { + applicationControlProperty = default; + + Span data = stackalloc byte[8]; + SpanWriter writer = new(data); + + writer.Write(applicationInstanceId); + + ulong bufferSize = (ulong)Unsafe.SizeOf(); + ulong bufferAddress = _allocator.Allocate(bufferSize); + + InitializeArpRService(); + + Result result = ServiceUtil.SendRequest( + out CmifResponse response, + _sessionHandle, + 1, + sendPid: false, + data, + stackalloc[] { HipcBufferFlags.Out | HipcBufferFlags.MapAlias | HipcBufferFlags.FixedSize }, + stackalloc[] { new PointerAndSize(bufferAddress, bufferSize) }); + + if (result.IsFailure) + { + return result; + } + + applicationControlProperty = HorizonStatic.AddressSpace.Read(bufferAddress); + + _allocator.Free(bufferAddress, bufferSize); + + return Result.Success; + } + + public void Dispose() + { + if (_sessionHandle != 0) + { + HorizonStatic.Syscall.CloseHandle(_sessionHandle); + + _sessionHandle = 0; + } + + GC.SuppressFinalize(this); + } + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Arp/ArpResult.cs b/src/Ryujinx.Horizon/Sdk/Arp/ArpResult.cs new file mode 100644 index 000000000..5de07871d --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Arp/ArpResult.cs @@ -0,0 +1,17 @@ +using Ryujinx.Horizon.Common; + +namespace Ryujinx.Horizon.Sdk.Arp +{ + static class ArpResult + { + private const int ModuleId = 157; + + public static Result InvalidArgument => new(ModuleId, 30); + public static Result InvalidPid => new(ModuleId, 31); + public static Result InvalidPointer => new(ModuleId, 32); + public static Result DataAlreadyBound => new(ModuleId, 42); + public static Result AllocationFailed => new(ModuleId, 63); + public static Result NoFreeInstance => new(ModuleId, 101); + public static Result InvalidInstanceId => new(ModuleId, 102); + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Arp/Detail/ApplicationInstance.cs b/src/Ryujinx.Horizon/Sdk/Arp/Detail/ApplicationInstance.cs new file mode 100644 index 000000000..5eb0ab184 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Arp/Detail/ApplicationInstance.cs @@ -0,0 +1,13 @@ +using Ryujinx.Horizon.Sdk.Ns; + +namespace Ryujinx.Horizon.Sdk.Arp.Detail +{ + class ApplicationInstance + { + public ulong Pid { get; set; } + public ApplicationLaunchProperty? LaunchProperty { get; set; } + public ApplicationProcessProperty? ProcessProperty { get; set; } + public ApplicationControlProperty? ControlProperty { get; set; } + public ApplicationCertificate? Certificate { get; set; } + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Arp/Detail/ApplicationInstanceManager.cs b/src/Ryujinx.Horizon/Sdk/Arp/Detail/ApplicationInstanceManager.cs new file mode 100644 index 000000000..18c993ce4 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Arp/Detail/ApplicationInstanceManager.cs @@ -0,0 +1,31 @@ +using Ryujinx.Horizon.Sdk.OsTypes; +using System; +using System.Threading; + +namespace Ryujinx.Horizon.Sdk.Arp.Detail +{ + class ApplicationInstanceManager : IDisposable + { + private int _disposalState; + + public SystemEventType SystemEvent; + public int EventHandle; + + public readonly ApplicationInstance[] Entries = new ApplicationInstance[2]; + + public ApplicationInstanceManager() + { + Os.CreateSystemEvent(out SystemEvent, EventClearMode.ManualClear, true).AbortOnFailure(); + + EventHandle = Os.GetReadableHandleOfSystemEvent(ref SystemEvent); + } + + public void Dispose() + { + if (EventHandle != 0 && Interlocked.Exchange(ref _disposalState, 1) == 0) + { + Os.DestroySystemEvent(ref SystemEvent); + } + } + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Arp/IReader.cs b/src/Ryujinx.Horizon/Sdk/Arp/IReader.cs new file mode 100644 index 000000000..ef78f7fd6 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Arp/IReader.cs @@ -0,0 +1,18 @@ +using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Sdk.Ns; +using System; + +namespace Ryujinx.Horizon.Sdk.Arp +{ + public interface IReader + { + public Result GetApplicationLaunchProperty(out ApplicationLaunchProperty applicationLaunchProperty, ulong applicationInstanceId); + public Result GetApplicationControlProperty(out ApplicationControlProperty applicationControlProperty, ulong applicationInstanceId); + public Result GetApplicationProcessProperty(out ApplicationProcessProperty applicationControlProperty, ulong applicationInstanceId); + public Result GetApplicationInstanceId(out ulong applicationInstanceId, ulong pid); + public Result GetApplicationInstanceUnregistrationNotifier(out IUnregistrationNotifier unregistrationNotifier); + public Result ListApplicationInstanceId(out int count, Span applicationInstanceIdList); + public Result GetMicroApplicationInstanceId(out ulong MicroApplicationInstanceId, ulong pid); + public Result GetApplicationCertificate(out ApplicationCertificate applicationCertificate, ulong applicationInstanceId); + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Arp/IRegistrar.cs b/src/Ryujinx.Horizon/Sdk/Arp/IRegistrar.cs new file mode 100644 index 000000000..467f3dbd3 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Arp/IRegistrar.cs @@ -0,0 +1,12 @@ +using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Sdk.Ns; + +namespace Ryujinx.Horizon.Sdk.Arp +{ + public interface IRegistrar + { + public Result Issue(out ulong applicationInstanceId); + public Result SetApplicationLaunchProperty(ApplicationLaunchProperty applicationLaunchProperty); + public Result SetApplicationControlProperty(in ApplicationControlProperty applicationControlProperty); + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Arp/IUnregistrationNotifier.cs b/src/Ryujinx.Horizon/Sdk/Arp/IUnregistrationNotifier.cs new file mode 100644 index 000000000..24b9807d8 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Arp/IUnregistrationNotifier.cs @@ -0,0 +1,9 @@ +using Ryujinx.Horizon.Common; + +namespace Ryujinx.Horizon.Sdk.Arp +{ + public interface IUnregistrationNotifier + { + public Result GetReadableHandle(out int readableHandle); + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Arp/IUpdater.cs b/src/Ryujinx.Horizon/Sdk/Arp/IUpdater.cs new file mode 100644 index 000000000..f9beeb690 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Arp/IUpdater.cs @@ -0,0 +1,12 @@ +using Ryujinx.Horizon.Common; + +namespace Ryujinx.Horizon.Sdk.Arp +{ + public interface IUpdater + { + public Result Issue(); + public Result SetApplicationProcessProperty(ulong pid, ApplicationProcessProperty applicationProcessProperty); + public Result DeleteApplicationProcessProperty(); + public Result SetApplicationCertificate(ApplicationCertificate applicationCertificate); + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Arp/IWriter.cs b/src/Ryujinx.Horizon/Sdk/Arp/IWriter.cs new file mode 100644 index 000000000..b3e000e1e --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Arp/IWriter.cs @@ -0,0 +1,12 @@ +using Ryujinx.Horizon.Common; + +namespace Ryujinx.Horizon.Sdk.Arp +{ + public interface IWriter + { + public Result AcquireRegistrar(out IRegistrar registrar); + public Result UnregisterApplicationInstance(ulong applicationInstanceId); + public Result AcquireApplicationProcessPropertyUpdater(out IUpdater updater, ulong applicationInstanceId); + public Result AcquireApplicationCertificateUpdater(out IUpdater updater, ulong applicationInstanceId); + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Bcat/IBcatService.cs b/src/Ryujinx.Horizon/Sdk/Bcat/IBcatService.cs index f6c8e6dd3..9201c4b26 100644 --- a/src/Ryujinx.Horizon/Sdk/Bcat/IBcatService.cs +++ b/src/Ryujinx.Horizon/Sdk/Bcat/IBcatService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Bcat diff --git a/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheDirectoryService.cs b/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheDirectoryService.cs index 23a740c35..f2f6c5b54 100644 --- a/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheDirectoryService.cs +++ b/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheDirectoryService.cs @@ -1,4 +1,4 @@ -using LibHac.Bcat; +using LibHac.Bcat; using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf; using System; diff --git a/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheFileService.cs b/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheFileService.cs index a1e5d43ba..1cba63ced 100644 --- a/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheFileService.cs +++ b/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheFileService.cs @@ -1,4 +1,4 @@ -using LibHac.Bcat; +using LibHac.Bcat; using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf; using System; diff --git a/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheProgressService.cs b/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheProgressService.cs index 07a796f88..bafcb9e15 100644 --- a/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheProgressService.cs +++ b/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheProgressService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Bcat.Ipc.Types; +using Ryujinx.Horizon.Bcat.Ipc.Types; using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf; diff --git a/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheStorageService.cs b/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheStorageService.cs index 5638f074c..f83114d91 100644 --- a/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheStorageService.cs +++ b/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheStorageService.cs @@ -1,4 +1,4 @@ -using LibHac.Bcat; +using LibHac.Bcat; using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf; using System; diff --git a/src/Ryujinx.Horizon/Sdk/Bcat/IServiceCreator.cs b/src/Ryujinx.Horizon/Sdk/Bcat/IServiceCreator.cs index 04f25259f..f31ff3e94 100644 --- a/src/Ryujinx.Horizon/Sdk/Bcat/IServiceCreator.cs +++ b/src/Ryujinx.Horizon/Sdk/Bcat/IServiceCreator.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Ncm; using Ryujinx.Horizon.Sdk.Sf; diff --git a/src/Ryujinx.Horizon/Sdk/DebugUtil.cs b/src/Ryujinx.Horizon/Sdk/DebugUtil.cs index f56a50ec5..a88c99a76 100644 --- a/src/Ryujinx.Horizon/Sdk/DebugUtil.cs +++ b/src/Ryujinx.Horizon/Sdk/DebugUtil.cs @@ -1,4 +1,4 @@ -using System.Diagnostics; +using System.Diagnostics; namespace Ryujinx.Horizon.Sdk { diff --git a/src/Ryujinx.Horizon/Sdk/Friends/ApplicationInfo.cs b/src/Ryujinx.Horizon/Sdk/Friends/ApplicationInfo.cs new file mode 100644 index 000000000..23bad3d13 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/ApplicationInfo.cs @@ -0,0 +1,12 @@ +using Ryujinx.Horizon.Sdk.Ncm; +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends +{ + [StructLayout(LayoutKind.Sequential, Size = 0x10, Pack = 0x8)] + struct ApplicationInfo + { + public ApplicationId ApplicationId; + public ulong PresenceGroupId; + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/BlockedUserImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/BlockedUserImpl.cs new file mode 100644 index 000000000..d5f8a0313 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/BlockedUserImpl.cs @@ -0,0 +1,8 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail +{ + struct BlockedUserImpl + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendCandidateImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendCandidateImpl.cs new file mode 100644 index 000000000..21e99c754 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendCandidateImpl.cs @@ -0,0 +1,8 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail +{ + struct FriendCandidateImpl + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendDetailedInfoImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendDetailedInfoImpl.cs new file mode 100644 index 000000000..1b46dccd5 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendDetailedInfoImpl.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail +{ + [StructLayout(LayoutKind.Sequential, Size = 0x800)] + struct FriendDetailedInfoImpl + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendImpl.cs new file mode 100644 index 000000000..d22ca4b90 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendImpl.cs @@ -0,0 +1,19 @@ +using Ryujinx.Common.Memory; +using Ryujinx.Horizon.Sdk.Account; +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail +{ + [StructLayout(LayoutKind.Sequential, Size = 0x200, Pack = 0x8)] + struct FriendImpl + { + public Uid UserId; + public NetworkServiceAccountId NetworkUserId; + public Nickname Nickname; + public UserPresenceImpl Presence; + public bool IsFavourite; + public bool IsNew; + public Array6 Unknown; + public bool IsValid; + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendInvitationForViewerImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendInvitationForViewerImpl.cs new file mode 100644 index 000000000..416ba3655 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendInvitationForViewerImpl.cs @@ -0,0 +1,8 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail +{ + struct FriendInvitationForViewerImpl + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendInvitationGroupImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendInvitationGroupImpl.cs new file mode 100644 index 000000000..ef9238347 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendInvitationGroupImpl.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail +{ + [StructLayout(LayoutKind.Sequential, Size = 0x1400)] + struct FriendInvitationGroupImpl + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendRequestImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendRequestImpl.cs new file mode 100644 index 000000000..ba5671692 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendRequestImpl.cs @@ -0,0 +1,8 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail +{ + struct FriendRequestImpl + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendSettingImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendSettingImpl.cs new file mode 100644 index 000000000..f711d31fd --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendSettingImpl.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail +{ + [StructLayout(LayoutKind.Sequential, Size = 0x40)] + struct FriendSettingImpl + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/DaemonSuspendSessionService.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/DaemonSuspendSessionService.cs new file mode 100644 index 000000000..aaf88ed03 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/DaemonSuspendSessionService.cs @@ -0,0 +1,7 @@ +namespace Ryujinx.Horizon.Sdk.Friends.Detail.Ipc +{ + partial class DaemonSuspendSessionService : IDaemonSuspendSessionService + { + // NOTE: This service has no commands. + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/FriendService.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/FriendService.cs new file mode 100644 index 000000000..1b4c8c309 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/FriendService.cs @@ -0,0 +1,1015 @@ +using Ryujinx.Common.Logging; +using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Sdk.Account; +using Ryujinx.Horizon.Sdk.OsTypes; +using Ryujinx.Horizon.Sdk.Settings; +using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf.Hipc; +using System; +using System.Runtime.InteropServices; +using System.Text; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail.Ipc +{ + partial class FriendService : IFriendService, IDisposable + { + private readonly IEmulatorAccountManager _accountManager; + private SystemEventType _completionEvent; + + public FriendService(IEmulatorAccountManager accountManager, FriendsServicePermissionLevel permissionLevel) + { + _accountManager = accountManager; + + Os.CreateSystemEvent(out _completionEvent, EventClearMode.ManualClear, interProcess: true).AbortOnFailure(); + Os.SignalSystemEvent(ref _completionEvent); // TODO: Figure out where we are supposed to signal this. + } + + [CmifCommand(0)] + public Result GetCompletionEvent([CopyHandle] out int completionEventHandle) + { + completionEventHandle = Os.GetReadableHandleOfSystemEvent(ref _completionEvent); + + return Result.Success; + } + + [CmifCommand(1)] + public Result Cancel() + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend); + + return Result.Success; + } + + [CmifCommand(10100)] + public Result GetFriendListIds( + out int count, + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.Pointer)] Span friendIds, + Uid userId, + int offset, + SizedFriendFilter filter, + ulong pidPlaceholder, + [ClientProcessId] ulong pid) + { + count = 0; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, offset, filter, pidPlaceholder, pid }); + + if (userId.IsNull) + { + return FriendResult.InvalidArgument; + } + + return Result.Success; + } + + [CmifCommand(10101)] + public Result GetFriendList( + out int count, + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span friendList, + Uid userId, + int offset, + SizedFriendFilter filter, + ulong pidPlaceholder, + [ClientProcessId] ulong pid) + { + count = 0; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, offset, filter, pidPlaceholder, pid }); + + if (userId.IsNull) + { + return FriendResult.InvalidArgument; + } + + return Result.Success; + } + + [CmifCommand(10102)] + public Result UpdateFriendInfo( + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span info, + Uid userId, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan friendIds, + ulong pidPlaceholder, + [ClientProcessId] ulong pid) + { + string friendIdList = string.Join(", ", friendIds.ToArray()); + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendIdList, pidPlaceholder, pid }); + + return Result.Success; + } + + [CmifCommand(10110)] + public Result GetFriendProfileImage( + out int size, + Uid userId, + NetworkServiceAccountId friendId, + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span profileImage) + { + size = 0; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendId }); + + return Result.Success; + } + + [CmifCommand(10120)] + public Result CheckFriendListAvailability(out bool listAvailable, Uid userId) + { + listAvailable = true; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(10121)] + public Result EnsureFriendListAvailable(Uid userId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(10200)] + public Result SendFriendRequestForApplication( + Uid userId, + NetworkServiceAccountId friendId, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer, 0x48)] in InAppScreenName arg2, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer, 0x48)] in InAppScreenName arg3, + ulong pidPlaceholder, + [ClientProcessId] ulong pid) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendId, arg2, arg3, pidPlaceholder, pid }); + + return Result.Success; + } + + [CmifCommand(10211)] + public Result AddFacedFriendRequestForApplication( + Uid userId, + FacedFriendRequestRegistrationKey key, + Nickname nickname, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan arg3, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer, 0x48)] in InAppScreenName arg4, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer, 0x48)] in InAppScreenName arg5, + ulong pidPlaceholder, + [ClientProcessId] ulong pid) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, key, nickname, arg4, arg5, pidPlaceholder, pid }); + + return Result.Success; + } + + [CmifCommand(10400)] + public Result GetBlockedUserListIds( + out int count, + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.Pointer)] Span blockedIds, + Uid userId, + int offset) + { + count = 0; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, offset }); + + return Result.Success; + } + + [CmifCommand(10420)] + public Result CheckBlockedUserListAvailability(out bool listAvailable, Uid userId) + { + listAvailable = true; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(10421)] + public Result EnsureBlockedUserListAvailable(Uid userId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(10500)] + public Result GetProfileList( + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span profileList, + Uid userId, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan friendIds) + { + string friendIdList = string.Join(", ", friendIds.ToArray()); + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendIdList }); + + return Result.Success; + } + + [CmifCommand(10600)] + public Result DeclareOpenOnlinePlaySession(Uid userId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + if (userId.IsNull) + { + return FriendResult.InvalidArgument; + } + + _accountManager.OpenUserOnlinePlay(userId); + + return Result.Success; + } + + [CmifCommand(10601)] + public Result DeclareCloseOnlinePlaySession(Uid userId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + if (userId.IsNull) + { + return FriendResult.InvalidArgument; + } + + _accountManager.CloseUserOnlinePlay(userId); + + return Result.Success; + } + + [CmifCommand(10610)] + public Result UpdateUserPresence( + Uid userId, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer, 0xE0)] in UserPresenceImpl userPresence, + ulong pidPlaceholder, + [ClientProcessId] ulong pid) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, userPresence, pidPlaceholder, pid }); + + return Result.Success; + } + + [CmifCommand(10700)] + public Result GetPlayHistoryRegistrationKey( + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.Pointer, 0x40)] out PlayHistoryRegistrationKey registrationKey, + Uid userId, + bool arg2) + { + if (userId.IsNull) + { + registrationKey = default; + + return FriendResult.InvalidArgument; + } + + // NOTE: Calls nn::friends::detail::service::core::PlayHistoryManager::GetInstance and stores the instance. + + // NOTE: Calls nn::friends::detail::service::core::UuidManager::GetInstance and stores the instance. + // Then calls nn::friends::detail::service::core::AccountStorageManager::GetInstance and stores the instance. + // Then it checks if an Uuid is already stored for the UserId, if not it generates a random Uuid, + // and stores it in the savedata 8000000000000080 in the friends:/uid.bin file. + + /* + + NOTE: The service uses the KeyIndex to get a random key from a keys buffer (since the key index is stored in the returned buffer). + We currently don't support play history and online services so we can use a blank key for now. + Code for reference: + + byte[] hmacKey = new byte[0x20]; + + HMACSHA256 hmacSha256 = new HMACSHA256(hmacKey); + byte[] hmacHash = hmacSha256.ComputeHash(playHistoryRegistrationKeyBuffer); + + */ + + Uid randomGuid = new(); + + Guid.NewGuid().TryWriteBytes(MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref randomGuid, 1))); + + registrationKey = new() + { + Type = 0x101, + KeyIndex = (byte)(Random.Shared.Next() & 7), + UserIdBool = 0, // TODO: Find it. + UnknownBool = (byte)(arg2 ? 1 : 0), // TODO: Find it. + Reserved = new(), + Uuid = randomGuid, + HmacHash = new(), + }; + + return Result.Success; + } + + [CmifCommand(10701)] + public Result GetPlayHistoryRegistrationKeyWithNetworkServiceAccountId( + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.Pointer, 0x40)] out PlayHistoryRegistrationKey registrationKey, + NetworkServiceAccountId friendId, + bool arg2) + { + registrationKey = default; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { friendId, arg2 }); + + return Result.Success; + } + + [CmifCommand(10702)] + public Result AddPlayHistory( + Uid userId, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer, 0x40)] in PlayHistoryRegistrationKey registrationKey, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer, 0x48)] in InAppScreenName arg2, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer, 0x48)] in InAppScreenName arg3, + ulong pidPlaceholder, + [ClientProcessId] ulong pid) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, registrationKey, arg2, arg3, pidPlaceholder, pid }); + + return Result.Success; + } + + [CmifCommand(11000)] + public Result GetProfileImageUrl(out Url imageUrl, Url url, int arg2) + { + imageUrl = default; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { url, arg2 }); + + return Result.Success; + } + + [CmifCommand(20100)] + public Result GetFriendCount(out int count, Uid userId, SizedFriendFilter filter, ulong pidPlaceholder, [ClientProcessId] ulong pid) + { + count = 0; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, filter, pidPlaceholder, pid }); + + return Result.Success; + } + + [CmifCommand(20101)] + public Result GetNewlyFriendCount(out int count, Uid userId) + { + count = 0; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(20102)] + public Result GetFriendDetailedInfo( + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.Pointer, 0x800)] out FriendDetailedInfoImpl detailedInfo, + Uid userId, + NetworkServiceAccountId friendId) + { + detailedInfo = default; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendId }); + + return Result.Success; + } + + [CmifCommand(20103)] + public Result SyncFriendList(Uid userId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(20104)] + public Result RequestSyncFriendList(Uid userId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(20110)] + public Result LoadFriendSetting( + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.Pointer, 0x40)] out FriendSettingImpl friendSetting, + Uid userId, + NetworkServiceAccountId friendId) + { + friendSetting = default; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendId }); + + return Result.Success; + } + + [CmifCommand(20200)] + public Result GetReceivedFriendRequestCount(out int count, out int count2, Uid userId) + { + count = 0; + count2 = 0; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(20201)] + public Result GetFriendRequestList( + out int count, + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span requestList, + Uid userId, + int arg3, + int arg4) + { + count = 0; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, arg3, arg4 }); + + return Result.Success; + } + + [CmifCommand(20300)] + public Result GetFriendCandidateList( + out int count, + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span candidateList, + Uid userId, + int arg3) + { + count = 0; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, arg3 }); + + return Result.Success; + } + + [CmifCommand(20301)] + public Result GetNintendoNetworkIdInfo( + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.Pointer, 0x38)] out NintendoNetworkIdUserInfo networkIdInfo, + out int arg1, + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span friendInfo, + Uid userId, + int arg4) + { + networkIdInfo = default; + arg1 = 0; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, arg4 }); + + return Result.Success; + } + + [CmifCommand(20302)] + public Result GetSnsAccountLinkage(out SnsAccountLinkage accountLinkage, Uid userId) + { + accountLinkage = default; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(20303)] + public Result GetSnsAccountProfile( + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.Pointer, 0x380)] out SnsAccountProfile accountProfile, + Uid userId, + NetworkServiceAccountId friendId, + int arg3) + { + accountProfile = default; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendId, arg3 }); + + return Result.Success; + } + + [CmifCommand(20304)] + public Result GetSnsAccountFriendList( + out int count, + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span friendList, + Uid userId, + int arg3) + { + count = 0; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, arg3 }); + + return Result.Success; + } + + [CmifCommand(20400)] + public Result GetBlockedUserList( + out int count, + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span blockedUsers, + Uid userId, + int arg3) + { + count = 0; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, arg3 }); + + return Result.Success; + } + + [CmifCommand(20401)] + public Result SyncBlockedUserList(Uid userId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(20500)] + public Result GetProfileExtraList( + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span extraList, + Uid userId, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan friendIds) + { + string friendIdList = string.Join(", ", friendIds.ToArray()); + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendIdList }); + + return Result.Success; + } + + [CmifCommand(20501)] + public Result GetRelationship(out Relationship relationship, Uid userId, NetworkServiceAccountId friendId) + { + relationship = default; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendId }); + + return Result.Success; + } + + [CmifCommand(20600)] + public Result GetUserPresenceView([Buffer(HipcBufferFlags.Out | HipcBufferFlags.Pointer, 0xE0)] out UserPresenceViewImpl userPresenceView, Uid userId) + { + userPresenceView = default; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(20700)] + public Result GetPlayHistoryList(out int count, [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span playHistoryList, Uid userId, int arg3) + { + count = 0; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, arg3 }); + + return Result.Success; + } + + [CmifCommand(20701)] + public Result GetPlayHistoryStatistics(out PlayHistoryStatistics statistics, Uid userId) + { + statistics = default; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(20800)] + public Result LoadUserSetting([Buffer(HipcBufferFlags.Out | HipcBufferFlags.Pointer, 0x800)] out UserSettingImpl userSetting, Uid userId) + { + userSetting = default; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(20801)] + public Result SyncUserSetting(Uid userId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(20900)] + public Result RequestListSummaryOverlayNotification() + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend); + + return Result.Success; + } + + [CmifCommand(21000)] + public Result GetExternalApplicationCatalog( + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.Pointer, 0x4B8)] out ExternalApplicationCatalog catalog, + ExternalApplicationCatalogId catalogId, + LanguageCode language) + { + catalog = default; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { catalogId, language }); + + return Result.Success; + } + + [CmifCommand(22000)] + public Result GetReceivedFriendInvitationList( + out int count, + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span invitationList, + Uid userId) + { + count = 0; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(22001)] + public Result GetReceivedFriendInvitationDetailedInfo( + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias, 0x1400)] out FriendInvitationGroupImpl invicationGroup, + Uid userId, + FriendInvitationGroupId groupId) + { + invicationGroup = default; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, groupId }); + + return Result.Success; + } + + [CmifCommand(22010)] + public Result GetReceivedFriendInvitationCountCache(out int count, Uid userId) + { + count = 0; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(30100)] + public Result DropFriendNewlyFlags(Uid userId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(30101)] + public Result DeleteFriend(Uid userId, NetworkServiceAccountId friendId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendId }); + + return Result.Success; + } + + [CmifCommand(30110)] + public Result DropFriendNewlyFlag(Uid userId, NetworkServiceAccountId friendId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendId }); + + return Result.Success; + } + + [CmifCommand(30120)] + public Result ChangeFriendFavoriteFlag(Uid userId, NetworkServiceAccountId friendId, bool favoriteFlag) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendId, favoriteFlag }); + + return Result.Success; + } + + [CmifCommand(30121)] + public Result ChangeFriendOnlineNotificationFlag(Uid userId, NetworkServiceAccountId friendId, bool onlineNotificationFlag) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendId, onlineNotificationFlag }); + + return Result.Success; + } + + [CmifCommand(30200)] + public Result SendFriendRequest(Uid userId, NetworkServiceAccountId friendId, int arg2) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendId, arg2 }); + + return Result.Success; + } + + [CmifCommand(30201)] + public Result SendFriendRequestWithApplicationInfo( + Uid userId, + NetworkServiceAccountId friendId, + int arg2, + ApplicationInfo applicationInfo, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer, 0x48)] in InAppScreenName arg4, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer, 0x48)] in InAppScreenName arg5) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendId, arg2, applicationInfo, arg4, arg5 }); + + return Result.Success; + } + + [CmifCommand(30202)] + public Result CancelFriendRequest(Uid userId, RequestId requestId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, requestId }); + + return Result.Success; + } + + [CmifCommand(30203)] + public Result AcceptFriendRequest(Uid userId, RequestId requestId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, requestId }); + + return Result.Success; + } + + [CmifCommand(30204)] + public Result RejectFriendRequest(Uid userId, RequestId requestId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, requestId }); + + return Result.Success; + } + + [CmifCommand(30205)] + public Result ReadFriendRequest(Uid userId, RequestId requestId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, requestId }); + + return Result.Success; + } + + [CmifCommand(30210)] + public Result GetFacedFriendRequestRegistrationKey(out FacedFriendRequestRegistrationKey registrationKey, Uid userId) + { + registrationKey = default; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(30211)] + public Result AddFacedFriendRequest( + Uid userId, + FacedFriendRequestRegistrationKey registrationKey, + Nickname nickname, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan arg3) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, registrationKey, nickname }); + + return Result.Success; + } + + [CmifCommand(30212)] + public Result CancelFacedFriendRequest(Uid userId, NetworkServiceAccountId friendId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendId }); + + return Result.Success; + } + + [CmifCommand(30213)] + public Result GetFacedFriendRequestProfileImage( + out int size, + Uid userId, + NetworkServiceAccountId friendId, + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span profileImage) + { + size = 0; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendId }); + + return Result.Success; + } + + [CmifCommand(30214)] + public Result GetFacedFriendRequestProfileImageFromPath( + out int size, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan path, + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span profileImage) + { + size = 0; + + string pathString = Encoding.UTF8.GetString(path); + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { pathString }); + + return Result.Success; + } + + [CmifCommand(30215)] + public Result SendFriendRequestWithExternalApplicationCatalogId( + Uid userId, + NetworkServiceAccountId friendId, + int arg2, + ExternalApplicationCatalogId catalogId, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer, 0x48)] in InAppScreenName arg4, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer, 0x48)] in InAppScreenName arg5) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendId, arg2, catalogId, arg4, arg5 }); + + return Result.Success; + } + + [CmifCommand(30216)] + public Result ResendFacedFriendRequest(Uid userId, NetworkServiceAccountId friendId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendId }); + + return Result.Success; + } + + [CmifCommand(30217)] + public Result SendFriendRequestWithNintendoNetworkIdInfo( + Uid userId, + NetworkServiceAccountId friendId, + int arg2, + MiiName arg3, + MiiImageUrlParam arg4, + MiiName arg5, + MiiImageUrlParam arg6) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendId, arg2, arg3, arg4, arg5, arg6 }); + + return Result.Success; + } + + [CmifCommand(30300)] + public Result GetSnsAccountLinkPageUrl([Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias, 0x1000)] out WebPageUrl url, Uid userId, int arg2) + { + url = default; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, arg2 }); + + return Result.Success; + } + + [CmifCommand(30301)] + public Result UnlinkSnsAccount(Uid userId, int arg1) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, arg1 }); + + return Result.Success; + } + + [CmifCommand(30400)] + public Result BlockUser(Uid userId, NetworkServiceAccountId friendId, int arg2) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendId, arg2 }); + + return Result.Success; + } + + [CmifCommand(30401)] + public Result BlockUserWithApplicationInfo( + Uid userId, + NetworkServiceAccountId friendId, + int arg2, + ApplicationInfo applicationInfo, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer, 0x48)] in InAppScreenName arg4) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendId, arg2, applicationInfo, arg4 }); + + return Result.Success; + } + + [CmifCommand(30402)] + public Result UnblockUser(Uid userId, NetworkServiceAccountId friendId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendId }); + + return Result.Success; + } + + [CmifCommand(30500)] + public Result GetProfileExtraFromFriendCode( + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.Pointer, 0x400)] out ProfileExtraImpl profileExtra, + Uid userId, + FriendCode friendCode) + { + profileExtra = default; + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendCode }); + + return Result.Success; + } + + [CmifCommand(30700)] + public Result DeletePlayHistory(Uid userId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(30810)] + public Result ChangePresencePermission(Uid userId, int permission) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, permission }); + + return Result.Success; + } + + [CmifCommand(30811)] + public Result ChangeFriendRequestReception(Uid userId, bool reception) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, reception }); + + return Result.Success; + } + + [CmifCommand(30812)] + public Result ChangePlayLogPermission(Uid userId, int permission) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, permission }); + + return Result.Success; + } + + [CmifCommand(30820)] + public Result IssueFriendCode(Uid userId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(30830)] + public Result ClearPlayLog(Uid userId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(30900)] + public Result SendFriendInvitation( + Uid userId, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan friendIds, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias, 0xC00)] in FriendInvitationGameModeDescription description, + ApplicationInfo applicationInfo, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan arg4, + bool arg5) + { + string friendIdList = string.Join(", ", friendIds.ToArray()); + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, friendIdList, description, applicationInfo, arg5 }); + + return Result.Success; + } + + [CmifCommand(30910)] + public Result ReadFriendInvitation(Uid userId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan invitationIds) + { + string invitationIdList = string.Join(", ", invitationIds.ToArray()); + + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId, invitationIdList }); + + return Result.Success; + } + + [CmifCommand(30911)] + public Result ReadAllFriendInvitations(Uid userId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(40100)] + public Result DeleteFriendListCache(Uid userId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(40400)] + public Result DeleteBlockedUserListCache(Uid userId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + [CmifCommand(49900)] + public Result DeleteNetworkServiceAccountCache(Uid userId) + { + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { userId }); + + return Result.Success; + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + Os.DestroySystemEvent(ref _completionEvent); + } + } + + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/Types/FriendServicePermissionLevel.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/FriendsServicePermissionLevel.cs similarity index 64% rename from src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/Types/FriendServicePermissionLevel.cs rename to src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/FriendsServicePermissionLevel.cs index bf7d1bd32..f4bbe100f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/Types/FriendServicePermissionLevel.cs +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/FriendsServicePermissionLevel.cs @@ -1,16 +1,13 @@ -using System; - -namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator +namespace Ryujinx.Horizon.Sdk.Friends.Detail.Ipc { - [Flags] - enum FriendServicePermissionLevel + enum FriendsServicePermissionLevel { UserMask = 1, ViewerMask = 2, ManagerMask = 4, SystemMask = 8, - Administrator = -1, + Admin = -1, User = UserMask, Viewer = UserMask | ViewerMask, Manager = UserMask | ViewerMask | ManagerMask, diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/IDaemonSuspendSessionService.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/IDaemonSuspendSessionService.cs new file mode 100644 index 000000000..2bb0434e8 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/IDaemonSuspendSessionService.cs @@ -0,0 +1,9 @@ +using Ryujinx.Horizon.Sdk.Sf; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail.Ipc +{ + interface IDaemonSuspendSessionService : IServiceObject + { + // NOTE: This service has no commands. + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/IFriendService.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/IFriendService.cs new file mode 100644 index 000000000..c19d0b788 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/IFriendService.cs @@ -0,0 +1,97 @@ +using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Sdk.Account; +using Ryujinx.Horizon.Sdk.Settings; +using Ryujinx.Horizon.Sdk.Sf; +using System; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail.Ipc +{ + interface IFriendService : IServiceObject + { + Result GetCompletionEvent(out int completionEventHandle); + Result Cancel(); + Result GetFriendListIds(out int count, Span friendIds, Uid userId, int offset, SizedFriendFilter filter, ulong pidPlaceholder, ulong pid); + Result GetFriendList(out int count, Span friendList, Uid userId, int offset, SizedFriendFilter filter, ulong pidPlaceholder, ulong pid); + Result UpdateFriendInfo(Span info, Uid userId, ReadOnlySpan friendIds, ulong pidPlaceholder, ulong pid); + Result GetFriendProfileImage(out int size, Uid userId, NetworkServiceAccountId friendId, Span profileImage); + Result CheckFriendListAvailability(out bool listAvailable, Uid userId); + Result EnsureFriendListAvailable(Uid userId); + Result SendFriendRequestForApplication(Uid userId, NetworkServiceAccountId friendId, in InAppScreenName arg2, in InAppScreenName arg3, ulong pidPlaceholder, ulong pid); + Result AddFacedFriendRequestForApplication(Uid userId, FacedFriendRequestRegistrationKey key, Nickname nickname, ReadOnlySpan arg3, in InAppScreenName arg4, in InAppScreenName arg5, ulong pidPlaceholder, ulong pid); + Result GetBlockedUserListIds(out int count, Span blockedIds, Uid userId, int offset); + Result CheckBlockedUserListAvailability(out bool listAvailable, Uid userId); + Result EnsureBlockedUserListAvailable(Uid userId); + Result GetProfileList(Span profileList, Uid userId, ReadOnlySpan friendIds); + Result DeclareOpenOnlinePlaySession(Uid userId); + Result DeclareCloseOnlinePlaySession(Uid userId); + Result UpdateUserPresence(Uid userId, in UserPresenceImpl userPresence, ulong pidPlaceholder, ulong pid); + Result GetPlayHistoryRegistrationKey(out PlayHistoryRegistrationKey registrationKey, Uid userId, bool arg2); + Result GetPlayHistoryRegistrationKeyWithNetworkServiceAccountId(out PlayHistoryRegistrationKey registrationKey, NetworkServiceAccountId friendId, bool arg2); + Result AddPlayHistory(Uid userId, in PlayHistoryRegistrationKey registrationKey, in InAppScreenName arg2, in InAppScreenName arg3, ulong pidPlaceholder, ulong pid); + Result GetProfileImageUrl(out Url imageUrl, Url url, int arg2); + Result GetFriendCount(out int count, Uid userId, SizedFriendFilter filter, ulong pidPlaceholder, ulong pid); + Result GetNewlyFriendCount(out int count, Uid userId); + Result GetFriendDetailedInfo(out FriendDetailedInfoImpl detailedInfo, Uid userId, NetworkServiceAccountId friendId); + Result SyncFriendList(Uid userId); + Result RequestSyncFriendList(Uid userId); + Result LoadFriendSetting(out FriendSettingImpl friendSetting, Uid userId, NetworkServiceAccountId friendId); + Result GetReceivedFriendRequestCount(out int count, out int count2, Uid userId); + Result GetFriendRequestList(out int count, Span requestList, Uid userId, int arg3, int arg4); + Result GetFriendCandidateList(out int count, Span candidateList, Uid userId, int arg3); + Result GetNintendoNetworkIdInfo(out NintendoNetworkIdUserInfo networkIdInfo, out int arg1, Span friendInfo, Uid userId, int arg4); + Result GetSnsAccountLinkage(out SnsAccountLinkage accountLinkage, Uid userId); + Result GetSnsAccountProfile(out SnsAccountProfile accountProfile, Uid userId, NetworkServiceAccountId friendId, int arg3); + Result GetSnsAccountFriendList(out int count, Span friendList, Uid userId, int arg3); + Result GetBlockedUserList(out int count, Span blockedUsers, Uid userId, int arg3); + Result SyncBlockedUserList(Uid userId); + Result GetProfileExtraList(Span extraList, Uid userId, ReadOnlySpan friendIds); + Result GetRelationship(out Relationship relationship, Uid userId, NetworkServiceAccountId friendId); + Result GetUserPresenceView(out UserPresenceViewImpl userPresenceView, Uid userId); + Result GetPlayHistoryList(out int count, Span playHistoryList, Uid userId, int arg3); + Result GetPlayHistoryStatistics(out PlayHistoryStatistics statistics, Uid userId); + Result LoadUserSetting(out UserSettingImpl userSetting, Uid userId); + Result SyncUserSetting(Uid userId); + Result RequestListSummaryOverlayNotification(); + Result GetExternalApplicationCatalog(out ExternalApplicationCatalog catalog, ExternalApplicationCatalogId catalogId, LanguageCode language); + Result GetReceivedFriendInvitationList(out int count, Span invitationList, Uid userId); + Result GetReceivedFriendInvitationDetailedInfo(out FriendInvitationGroupImpl invicationGroup, Uid userId, FriendInvitationGroupId groupId); + Result GetReceivedFriendInvitationCountCache(out int count, Uid userId); + Result DropFriendNewlyFlags(Uid userId); + Result DeleteFriend(Uid userId, NetworkServiceAccountId friendId); + Result DropFriendNewlyFlag(Uid userId, NetworkServiceAccountId friendId); + Result ChangeFriendFavoriteFlag(Uid userId, NetworkServiceAccountId friendId, bool favoriteFlag); + Result ChangeFriendOnlineNotificationFlag(Uid userId, NetworkServiceAccountId friendId, bool onlineNotificationFlag); + Result SendFriendRequest(Uid userId, NetworkServiceAccountId friendId, int arg2); + Result SendFriendRequestWithApplicationInfo(Uid userId, NetworkServiceAccountId friendId, int arg2, ApplicationInfo applicationInfo, in InAppScreenName arg4, in InAppScreenName arg5); + Result CancelFriendRequest(Uid userId, RequestId requestId); + Result AcceptFriendRequest(Uid userId, RequestId requestId); + Result RejectFriendRequest(Uid userId, RequestId requestId); + Result ReadFriendRequest(Uid userId, RequestId requestId); + Result GetFacedFriendRequestRegistrationKey(out FacedFriendRequestRegistrationKey registrationKey, Uid userId); + Result AddFacedFriendRequest(Uid userId, FacedFriendRequestRegistrationKey registrationKey, Nickname nickname, ReadOnlySpan arg3); + Result CancelFacedFriendRequest(Uid userId, NetworkServiceAccountId friendId); + Result GetFacedFriendRequestProfileImage(out int size, Uid userId, NetworkServiceAccountId friendId, Span profileImage); + Result GetFacedFriendRequestProfileImageFromPath(out int size, ReadOnlySpan path, Span profileImage); + Result SendFriendRequestWithExternalApplicationCatalogId(Uid userId, NetworkServiceAccountId friendId, int arg2, ExternalApplicationCatalogId catalogId, in InAppScreenName arg4, in InAppScreenName arg5); + Result ResendFacedFriendRequest(Uid userId, NetworkServiceAccountId friendId); + Result SendFriendRequestWithNintendoNetworkIdInfo(Uid userId, NetworkServiceAccountId friendId, int arg2, MiiName arg3, MiiImageUrlParam arg4, MiiName arg5, MiiImageUrlParam arg6); + Result GetSnsAccountLinkPageUrl(out WebPageUrl url, Uid userId, int arg2); + Result UnlinkSnsAccount(Uid userId, int arg1); + Result BlockUser(Uid userId, NetworkServiceAccountId friendId, int arg2); + Result BlockUserWithApplicationInfo(Uid userId, NetworkServiceAccountId friendId, int arg2, ApplicationInfo applicationInfo, in InAppScreenName arg4); + Result UnblockUser(Uid userId, NetworkServiceAccountId friendId); + Result GetProfileExtraFromFriendCode(out ProfileExtraImpl profileExtra, Uid userId, FriendCode friendCode); + Result DeletePlayHistory(Uid userId); + Result ChangePresencePermission(Uid userId, int permission); + Result ChangeFriendRequestReception(Uid userId, bool reception); + Result ChangePlayLogPermission(Uid userId, int permission); + Result IssueFriendCode(Uid userId); + Result ClearPlayLog(Uid userId); + Result SendFriendInvitation(Uid userId, ReadOnlySpan friendIds, in FriendInvitationGameModeDescription description, ApplicationInfo applicationInfo, ReadOnlySpan arg4, bool arg5); + Result ReadFriendInvitation(Uid userId, ReadOnlySpan invitationIds); + Result ReadAllFriendInvitations(Uid userId); + Result DeleteFriendListCache(Uid userId); + Result DeleteBlockedUserListCache(Uid userId); + Result DeleteNetworkServiceAccountCache(Uid userId); + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/INotificationService.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/INotificationService.cs new file mode 100644 index 000000000..a3a28e8ce --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/INotificationService.cs @@ -0,0 +1,12 @@ +using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Sdk.Sf; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail.Ipc +{ + interface INotificationService : IServiceObject + { + Result GetEvent(out int eventHandle); + Result Clear(); + Result Pop(out SizedNotificationInfo sizedNotificationInfo); + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/IServiceCreator.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/IServiceCreator.cs new file mode 100644 index 000000000..58e2569bb --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/IServiceCreator.cs @@ -0,0 +1,13 @@ +using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Sdk.Account; +using Ryujinx.Horizon.Sdk.Sf; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail.Ipc +{ + interface IServiceCreator : IServiceObject + { + Result CreateFriendService(out IFriendService friendService); + Result CreateNotificationService(out INotificationService notificationService, Uid userId); + Result CreateDaemonSuspendSessionService(out IDaemonSuspendSessionService daemonSuspendSessionService); + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/NotificationEventHandler.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/NotificationEventHandler.cs new file mode 100644 index 000000000..61c692a6e --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/NotificationEventHandler.cs @@ -0,0 +1,58 @@ +using Ryujinx.Horizon.Sdk.Account; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail.Ipc +{ + sealed class NotificationEventHandler + { + private readonly NotificationService[] _registry; + + public NotificationEventHandler() + { + _registry = new NotificationService[0x20]; + } + + public void RegisterNotificationService(NotificationService service) + { + // NOTE: When there's no enough space in the registry array, Nintendo doesn't return any errors. + for (int i = 0; i < _registry.Length; i++) + { + if (_registry[i] == null) + { + _registry[i] = service; + break; + } + } + } + + public void UnregisterNotificationService(NotificationService service) + { + // NOTE: When there's no enough space in the registry array, Nintendo doesn't return any errors. + for (int i = 0; i < _registry.Length; i++) + { + if (_registry[i] == service) + { + _registry[i] = null; + break; + } + } + } + + // TODO: Use this when we have enough things to go online. + public void SignalFriendListUpdate(Uid targetId) + { + for (int i = 0; i < _registry.Length; i++) + { + _registry[i]?.SignalFriendListUpdate(targetId); + } + } + + // TODO: Use this when we have enough things to go online. + public void SignalNewFriendRequest(Uid targetId) + { + for (int i = 0; i < _registry.Length; i++) + { + _registry[i]?.SignalNewFriendRequest(targetId); + } + } + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/NotificationService/Types/NotificationEventType.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/NotificationEventType.cs similarity index 63% rename from src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/NotificationService/Types/NotificationEventType.cs rename to src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/NotificationEventType.cs index d7f3f55d2..e46fc9b7a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/NotificationService/Types/NotificationEventType.cs +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/NotificationEventType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator.NotificationService +namespace Ryujinx.Horizon.Sdk.Friends.Detail.Ipc { enum NotificationEventType : uint { diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/NotificationService.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/NotificationService.cs new file mode 100644 index 000000000..534bf63ed --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/NotificationService.cs @@ -0,0 +1,172 @@ +using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Sdk.Account; +using Ryujinx.Horizon.Sdk.OsTypes; +using Ryujinx.Horizon.Sdk.Sf; +using System; +using System.Collections.Generic; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail.Ipc +{ + partial class NotificationService : INotificationService, IDisposable + { + private readonly NotificationEventHandler _notificationEventHandler; + private readonly Uid _userId; + private readonly FriendsServicePermissionLevel _permissionLevel; + + private readonly object _lock = new(); + + private SystemEventType _notificationEvent; + + private readonly LinkedList _notifications; + + private bool _hasNewFriendRequest; + private bool _hasFriendListUpdate; + + public NotificationService(NotificationEventHandler notificationEventHandler, Uid userId, FriendsServicePermissionLevel permissionLevel) + { + _notificationEventHandler = notificationEventHandler; + _userId = userId; + _permissionLevel = permissionLevel; + _notifications = new LinkedList(); + Os.CreateSystemEvent(out _notificationEvent, EventClearMode.AutoClear, interProcess: true).AbortOnFailure(); + + _hasNewFriendRequest = false; + _hasFriendListUpdate = false; + + notificationEventHandler.RegisterNotificationService(this); + } + + [CmifCommand(0)] + public Result GetEvent([CopyHandle] out int eventHandle) + { + eventHandle = Os.GetReadableHandleOfSystemEvent(ref _notificationEvent); + + return Result.Success; + } + + [CmifCommand(1)] + public Result Clear() + { + lock (_lock) + { + _hasNewFriendRequest = false; + _hasFriendListUpdate = false; + + _notifications.Clear(); + } + + return Result.Success; + } + + [CmifCommand(2)] + public Result Pop(out SizedNotificationInfo sizedNotificationInfo) + { + lock (_lock) + { + if (_notifications.Count >= 1) + { + sizedNotificationInfo = _notifications.First.Value; + _notifications.RemoveFirst(); + + if (sizedNotificationInfo.Type == NotificationEventType.FriendListUpdate) + { + _hasFriendListUpdate = false; + } + else if (sizedNotificationInfo.Type == NotificationEventType.NewFriendRequest) + { + _hasNewFriendRequest = false; + } + + return Result.Success; + } + } + + sizedNotificationInfo = default; + + return FriendResult.NotificationQueueEmpty; + } + + public void SignalFriendListUpdate(Uid targetId) + { + lock (_lock) + { + if (_userId == targetId) + { + if (!_hasFriendListUpdate) + { + SizedNotificationInfo friendListNotification = new(); + + if (_notifications.Count != 0) + { + friendListNotification = _notifications.First.Value; + _notifications.RemoveFirst(); + } + + friendListNotification.Type = NotificationEventType.FriendListUpdate; + _hasFriendListUpdate = true; + + if (_hasNewFriendRequest) + { + SizedNotificationInfo newFriendRequestNotification = new(); + + if (_notifications.Count != 0) + { + newFriendRequestNotification = _notifications.First.Value; + _notifications.RemoveFirst(); + } + + newFriendRequestNotification.Type = NotificationEventType.NewFriendRequest; + _notifications.AddFirst(newFriendRequestNotification); + } + + // We defer this to make sure we are on top of the queue. + _notifications.AddFirst(friendListNotification); + } + + Os.SignalSystemEvent(ref _notificationEvent); + } + } + } + + public void SignalNewFriendRequest(Uid targetId) + { + lock (_lock) + { + if (_permissionLevel.HasFlag(FriendsServicePermissionLevel.ViewerMask) && _userId == targetId) + { + if (!_hasNewFriendRequest) + { + if (_notifications.Count == 100) + { + SignalFriendListUpdate(targetId); + } + + SizedNotificationInfo newFriendRequestNotification = new() + { + Type = NotificationEventType.NewFriendRequest, + }; + + _notifications.AddLast(newFriendRequestNotification); + _hasNewFriendRequest = true; + } + + Os.SignalSystemEvent(ref _notificationEvent); + } + } + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + _notificationEventHandler.UnregisterNotificationService(this); + } + } + + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/FriendService/Types/PresenceStatusFilter.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/PresenceStatusFilter.cs similarity index 63% rename from src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/FriendService/Types/PresenceStatusFilter.cs rename to src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/PresenceStatusFilter.cs index 5949b8f64..3ea105872 100644 --- a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/FriendService/Types/PresenceStatusFilter.cs +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/PresenceStatusFilter.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator.FriendService +namespace Ryujinx.Horizon.Sdk.Friends.Detail.Ipc { enum PresenceStatusFilter : uint { diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/ServiceCreator.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/ServiceCreator.cs new file mode 100644 index 000000000..1be804dfd --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/ServiceCreator.cs @@ -0,0 +1,51 @@ +using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Sdk.Account; +using Ryujinx.Horizon.Sdk.Sf; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail.Ipc +{ + partial class ServiceCreator : IServiceCreator + { + private readonly IEmulatorAccountManager _accountManager; + private readonly NotificationEventHandler _notificationEventHandler; + private readonly FriendsServicePermissionLevel _permissionLevel; + + public ServiceCreator(IEmulatorAccountManager accountManager, NotificationEventHandler notificationEventHandler, FriendsServicePermissionLevel permissionLevel) + { + _accountManager = accountManager; + _notificationEventHandler = notificationEventHandler; + _permissionLevel = permissionLevel; + } + + [CmifCommand(0)] + public Result CreateFriendService(out IFriendService friendService) + { + friendService = new FriendService(_accountManager, _permissionLevel); + + return Result.Success; + } + + [CmifCommand(1)] // 2.0.0+ + public Result CreateNotificationService(out INotificationService notificationService, Uid userId) + { + if (userId.IsNull) + { + notificationService = null; + + return FriendResult.InvalidArgument; + } + + notificationService = new NotificationService(_notificationEventHandler, userId, _permissionLevel); + + return Result.Success; + } + + [CmifCommand(2)] // 4.0.0+ + public Result CreateDaemonSuspendSessionService(out IDaemonSuspendSessionService daemonSuspendSessionService) + { + daemonSuspendSessionService = new DaemonSuspendSessionService(); + + return Result.Success; + } + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/SizedFriendFilter.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/SizedFriendFilter.cs new file mode 100644 index 000000000..d93a2ae29 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/SizedFriendFilter.cs @@ -0,0 +1,25 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail.Ipc +{ + [StructLayout(LayoutKind.Sequential, Size = 0x10, Pack = 0x8)] + struct SizedFriendFilter + { + public PresenceStatusFilter PresenceStatus; + public bool IsFavoriteOnly; + public bool IsSameAppPresenceOnly; + public bool IsSameAppPlayedOnly; + public bool IsArbitraryAppPlayedOnly; + public ulong PresenceGroupId; + + public readonly override string ToString() + { + return $"{{ PresenceStatus: {PresenceStatus}, " + + $"IsFavoriteOnly: {IsFavoriteOnly}, " + + $"IsSameAppPresenceOnly: {IsSameAppPresenceOnly}, " + + $"IsSameAppPlayedOnly: {IsSameAppPlayedOnly}, " + + $"IsArbitraryAppPlayedOnly: {IsArbitraryAppPlayedOnly}, " + + $"PresenceGroupId: {PresenceGroupId} }}"; + } + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/SizedNotificationInfo.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/SizedNotificationInfo.cs new file mode 100644 index 000000000..0da26a1ae --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/Ipc/SizedNotificationInfo.cs @@ -0,0 +1,13 @@ +using Ryujinx.Horizon.Sdk.Account; +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail.Ipc +{ + [StructLayout(LayoutKind.Sequential, Size = 0x10, Pack = 0x8)] + struct SizedNotificationInfo + { + public NotificationEventType Type; + public uint Padding; + public NetworkServiceAccountId NetworkUserIdPlaceholder; + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/NintendoNetworkIdFriendImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/NintendoNetworkIdFriendImpl.cs new file mode 100644 index 000000000..66d61e4c1 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/NintendoNetworkIdFriendImpl.cs @@ -0,0 +1,8 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail +{ + struct NintendoNetworkIdFriendImpl + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/PlayHistoryImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/PlayHistoryImpl.cs new file mode 100644 index 000000000..9f90f0c8f --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/PlayHistoryImpl.cs @@ -0,0 +1,8 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail +{ + struct PlayHistoryImpl + { + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/FriendService/Types/PresenceStatus.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/PresenceStatus.cs similarity index 57% rename from src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/FriendService/Types/PresenceStatus.cs rename to src/Ryujinx.Horizon/Sdk/Friends/Detail/PresenceStatus.cs index 0271e61a4..5ddbe14ea 100644 --- a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/FriendService/Types/PresenceStatus.cs +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/PresenceStatus.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator.FriendService +namespace Ryujinx.Horizon.Sdk.Friends.Detail { enum PresenceStatus : uint { diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/ProfileExtraImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/ProfileExtraImpl.cs new file mode 100644 index 000000000..1548d725f --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/ProfileExtraImpl.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail +{ + [StructLayout(LayoutKind.Sequential, Size = 0x400)] + struct ProfileExtraImpl + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/ProfileImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/ProfileImpl.cs new file mode 100644 index 000000000..f779d93cf --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/ProfileImpl.cs @@ -0,0 +1,8 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail +{ + struct ProfileImpl + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/SnsAccountFriendImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/SnsAccountFriendImpl.cs new file mode 100644 index 000000000..dc6adf03a --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/SnsAccountFriendImpl.cs @@ -0,0 +1,8 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail +{ + struct SnsAccountFriendImpl + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/UserPresenceImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/UserPresenceImpl.cs new file mode 100644 index 000000000..cf4520cf4 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/UserPresenceImpl.cs @@ -0,0 +1,29 @@ +using Ryujinx.Common.Memory; +using Ryujinx.Horizon.Sdk.Account; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail +{ + [StructLayout(LayoutKind.Sequential, Size = 0xE0)] + struct UserPresenceImpl + { + public Uid UserId; + public long LastTimeOnlineTimestamp; + public PresenceStatus Status; + public bool SamePresenceGroupApplication; + public Array3 Unknown; + public AppKeyValueStorageHolder AppKeyValueStorage; + + [InlineArray(0xC0)] + public struct AppKeyValueStorageHolder + { + public byte Value; + } + + public readonly override string ToString() + { + return $"{{ UserId: {UserId}, LastTimeOnlineTimestamp: {LastTimeOnlineTimestamp}, Status: {Status} }}"; + } + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/UserPresenceViewImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/UserPresenceViewImpl.cs new file mode 100644 index 000000000..04c092600 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/UserPresenceViewImpl.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail +{ + [StructLayout(LayoutKind.Sequential, Size = 0xE0)] + struct UserPresenceViewImpl + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/UserSettingImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/UserSettingImpl.cs new file mode 100644 index 000000000..9d057fb1e --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/UserSettingImpl.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends.Detail +{ + [StructLayout(LayoutKind.Sequential, Size = 0x800)] + struct UserSettingImpl + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/ExternalApplicationCatalog.cs b/src/Ryujinx.Horizon/Sdk/Friends/ExternalApplicationCatalog.cs new file mode 100644 index 000000000..0d9c157d3 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/ExternalApplicationCatalog.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends +{ + [StructLayout(LayoutKind.Sequential, Size = 0x4B8)] + struct ExternalApplicationCatalog + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/ExternalApplicationCatalogId.cs b/src/Ryujinx.Horizon/Sdk/Friends/ExternalApplicationCatalogId.cs new file mode 100644 index 000000000..7ed36cd9d --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/ExternalApplicationCatalogId.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends +{ + [StructLayout(LayoutKind.Sequential, Size = 0x10, Pack = 0x8)] + struct ExternalApplicationCatalogId + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/FacedFriendRequestRegistrationKey.cs b/src/Ryujinx.Horizon/Sdk/Friends/FacedFriendRequestRegistrationKey.cs new file mode 100644 index 000000000..6b5812f64 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/FacedFriendRequestRegistrationKey.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends +{ + [StructLayout(LayoutKind.Sequential, Size = 0x40, Pack = 0x1)] + struct FacedFriendRequestRegistrationKey + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/FriendCode.cs b/src/Ryujinx.Horizon/Sdk/Friends/FriendCode.cs new file mode 100644 index 000000000..d78497a18 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/FriendCode.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends +{ + [StructLayout(LayoutKind.Sequential, Size = 0x20, Pack = 0x1)] + struct FriendCode + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/FriendInvitationGameModeDescription.cs b/src/Ryujinx.Horizon/Sdk/Friends/FriendInvitationGameModeDescription.cs new file mode 100644 index 000000000..29b4a0974 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/FriendInvitationGameModeDescription.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends +{ + [StructLayout(LayoutKind.Sequential, Size = 0xC00)] + struct FriendInvitationGameModeDescription + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/FriendInvitationGroupId.cs b/src/Ryujinx.Horizon/Sdk/Friends/FriendInvitationGroupId.cs new file mode 100644 index 000000000..ef53882b3 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/FriendInvitationGroupId.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends +{ + [StructLayout(LayoutKind.Sequential, Size = 0x8, Pack = 0x8)] + struct FriendInvitationGroupId + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/FriendInvitationId.cs b/src/Ryujinx.Horizon/Sdk/Friends/FriendInvitationId.cs new file mode 100644 index 000000000..7be19d574 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/FriendInvitationId.cs @@ -0,0 +1,8 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends +{ + struct FriendInvitationId + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/FriendResult.cs b/src/Ryujinx.Horizon/Sdk/Friends/FriendResult.cs new file mode 100644 index 000000000..5965d508d --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/FriendResult.cs @@ -0,0 +1,13 @@ +using Ryujinx.Horizon.Common; + +namespace Ryujinx.Horizon.Sdk.Friends +{ + static class FriendResult + { + private const int ModuleId = 121; + + public static Result InvalidArgument => new(ModuleId, 2); + public static Result InternetRequestDenied => new(ModuleId, 6); + public static Result NotificationQueueEmpty => new(ModuleId, 15); + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/InAppScreenName.cs b/src/Ryujinx.Horizon/Sdk/Friends/InAppScreenName.cs new file mode 100644 index 000000000..22574a5cc --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/InAppScreenName.cs @@ -0,0 +1,26 @@ +using Ryujinx.Common.Memory; +using Ryujinx.Horizon.Sdk.Settings; +using System; +using System.Runtime.InteropServices; +using System.Text; + +namespace Ryujinx.Horizon.Sdk.Friends +{ + [StructLayout(LayoutKind.Sequential, Size = 0x48)] + struct InAppScreenName + { + public Array64 Name; + public LanguageCode LanguageCode; + + public override readonly string ToString() + { + int length = Name.AsSpan().IndexOf((byte)0); + if (length < 0) + { + length = 64; + } + + return Encoding.UTF8.GetString(Name.AsSpan()[..length]); + } + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/MiiImageUrlParam.cs b/src/Ryujinx.Horizon/Sdk/Friends/MiiImageUrlParam.cs new file mode 100644 index 000000000..8790bb931 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/MiiImageUrlParam.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends +{ + [StructLayout(LayoutKind.Sequential, Size = 0x10, Pack = 0x1)] + struct MiiImageUrlParam + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/MiiName.cs b/src/Ryujinx.Horizon/Sdk/Friends/MiiName.cs new file mode 100644 index 000000000..e73c0d833 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/MiiName.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends +{ + [StructLayout(LayoutKind.Sequential, Size = 0x20, Pack = 0x1)] + struct MiiName + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/NintendoNetworkIdUserInfo.cs b/src/Ryujinx.Horizon/Sdk/Friends/NintendoNetworkIdUserInfo.cs new file mode 100644 index 000000000..a2a9e046f --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/NintendoNetworkIdUserInfo.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends +{ + [StructLayout(LayoutKind.Sequential, Size = 0x38)] + struct NintendoNetworkIdUserInfo + { + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/Types/PlayHistoryRegistrationKey.cs b/src/Ryujinx.Horizon/Sdk/Friends/PlayHistoryRegistrationKey.cs similarity index 53% rename from src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/Types/PlayHistoryRegistrationKey.cs rename to src/Ryujinx.Horizon/Sdk/Friends/PlayHistoryRegistrationKey.cs index aaeef0593..bb672a795 100644 --- a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/Types/PlayHistoryRegistrationKey.cs +++ b/src/Ryujinx.Horizon/Sdk/Friends/PlayHistoryRegistrationKey.cs @@ -1,9 +1,10 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; +using Ryujinx.Horizon.Sdk.Account; using System.Runtime.InteropServices; -namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator +namespace Ryujinx.Horizon.Sdk.Friends { - [StructLayout(LayoutKind.Sequential, Size = 0x20)] + [StructLayout(LayoutKind.Sequential, Size = 0x40)] struct PlayHistoryRegistrationKey { public ushort Type; @@ -11,6 +12,7 @@ namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator public byte UserIdBool; public byte UnknownBool; public Array11 Reserved; - public Array16 Uuid; + public Uid Uuid; + public Array32 HmacHash; } } diff --git a/src/Ryujinx.Horizon/Sdk/Friends/PlayHistoryStatistics.cs b/src/Ryujinx.Horizon/Sdk/Friends/PlayHistoryStatistics.cs new file mode 100644 index 000000000..ea3e3d997 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/PlayHistoryStatistics.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends +{ + [StructLayout(LayoutKind.Sequential, Size = 0x10, Pack = 0x8)] + struct PlayHistoryStatistics + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Relationship.cs b/src/Ryujinx.Horizon/Sdk/Friends/Relationship.cs new file mode 100644 index 000000000..efba09a8f --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Relationship.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends +{ + [StructLayout(LayoutKind.Sequential, Size = 0x8, Pack = 0x1)] + struct Relationship + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/RequestId.cs b/src/Ryujinx.Horizon/Sdk/Friends/RequestId.cs new file mode 100644 index 000000000..3236a1d7d --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/RequestId.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends +{ + [StructLayout(LayoutKind.Sequential, Size = 0x8, Pack = 0x8)] + struct RequestId + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/SnsAccountLinkage.cs b/src/Ryujinx.Horizon/Sdk/Friends/SnsAccountLinkage.cs new file mode 100644 index 000000000..b4660d9e7 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/SnsAccountLinkage.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends +{ + [StructLayout(LayoutKind.Sequential, Size = 0x8, Pack = 0x1)] + struct SnsAccountLinkage + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/SnsAccountProfile.cs b/src/Ryujinx.Horizon/Sdk/Friends/SnsAccountProfile.cs new file mode 100644 index 000000000..d872b3dac --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/SnsAccountProfile.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends +{ + [StructLayout(LayoutKind.Sequential, Size = 0x380)] + struct SnsAccountProfile + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Url.cs b/src/Ryujinx.Horizon/Sdk/Friends/Url.cs new file mode 100644 index 000000000..833ee1230 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/Url.cs @@ -0,0 +1,30 @@ +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; + +namespace Ryujinx.Horizon.Sdk.Friends +{ + [StructLayout(LayoutKind.Sequential, Size = 0xA0, Pack = 0x1)] + struct Url + { + public UrlStorage Path; + + [InlineArray(0xA0)] + public struct UrlStorage + { + public byte Value; + } + + public override readonly string ToString() + { + int length = ((ReadOnlySpan)Path).IndexOf((byte)0); + if (length < 0) + { + length = 33; + } + + return Encoding.UTF8.GetString(((ReadOnlySpan)Path)[..length]); + } + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Friends/WebPageUrl.cs b/src/Ryujinx.Horizon/Sdk/Friends/WebPageUrl.cs new file mode 100644 index 000000000..85488af61 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Friends/WebPageUrl.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Friends +{ + [StructLayout(LayoutKind.Sequential, Size = 0x1000)] + struct WebPageUrl + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Hshl/IManager.cs b/src/Ryujinx.Horizon/Sdk/Hshl/IManager.cs index 13955c692..52695ce68 100644 --- a/src/Ryujinx.Horizon/Sdk/Hshl/IManager.cs +++ b/src/Ryujinx.Horizon/Sdk/Hshl/IManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Hshl { diff --git a/src/Ryujinx.Horizon/Sdk/Hshl/ISetterManager.cs b/src/Ryujinx.Horizon/Sdk/Hshl/ISetterManager.cs index 8a4b93dd1..fc668b05a 100644 --- a/src/Ryujinx.Horizon/Sdk/Hshl/ISetterManager.cs +++ b/src/Ryujinx.Horizon/Sdk/Hshl/ISetterManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Hshl { diff --git a/src/Ryujinx.Horizon/Sdk/Ins/IReceiverManager.cs b/src/Ryujinx.Horizon/Sdk/Ins/IReceiverManager.cs index 28fc757e5..f9fb3a445 100644 --- a/src/Ryujinx.Horizon/Sdk/Ins/IReceiverManager.cs +++ b/src/Ryujinx.Horizon/Sdk/Ins/IReceiverManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Ins { diff --git a/src/Ryujinx.Horizon/Sdk/Ins/ISenderManager.cs b/src/Ryujinx.Horizon/Sdk/Ins/ISenderManager.cs index 878dbfb32..03c22c6dd 100644 --- a/src/Ryujinx.Horizon/Sdk/Ins/ISenderManager.cs +++ b/src/Ryujinx.Horizon/Sdk/Ins/ISenderManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Ins { diff --git a/src/Ryujinx.Horizon/Sdk/Lbl/ILblController.cs b/src/Ryujinx.Horizon/Sdk/Lbl/ILblController.cs index 594722e9c..19a8154e3 100644 --- a/src/Ryujinx.Horizon/Sdk/Lbl/ILblController.cs +++ b/src/Ryujinx.Horizon/Sdk/Lbl/ILblController.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Lbl diff --git a/src/Ryujinx.Horizon/Sdk/Lbl/LblApi.cs b/src/Ryujinx.Horizon/Sdk/Lbl/LblApi.cs index 843a9acd6..a5622d4aa 100644 --- a/src/Ryujinx.Horizon/Sdk/Lbl/LblApi.cs +++ b/src/Ryujinx.Horizon/Sdk/Lbl/LblApi.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sm; using System; diff --git a/src/Ryujinx.Horizon/Sdk/Lm/ILmLogger.cs b/src/Ryujinx.Horizon/Sdk/Lm/ILmLogger.cs index 42165aab3..2b32a7a02 100644 --- a/src/Ryujinx.Horizon/Sdk/Lm/ILmLogger.cs +++ b/src/Ryujinx.Horizon/Sdk/Lm/ILmLogger.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf; using System; diff --git a/src/Ryujinx.Horizon/Sdk/Lm/ILogService.cs b/src/Ryujinx.Horizon/Sdk/Lm/ILogService.cs index b66b91267..ae29267a1 100644 --- a/src/Ryujinx.Horizon/Sdk/Lm/ILogService.cs +++ b/src/Ryujinx.Horizon/Sdk/Lm/ILogService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.LogManager.Ipc; using Ryujinx.Horizon.Sdk.Sf; diff --git a/src/Ryujinx.Horizon/Sdk/MmNv/IRequest.cs b/src/Ryujinx.Horizon/Sdk/MmNv/IRequest.cs index 300b957fd..1c2ce6552 100644 --- a/src/Ryujinx.Horizon/Sdk/MmNv/IRequest.cs +++ b/src/Ryujinx.Horizon/Sdk/MmNv/IRequest.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.MmNv diff --git a/src/Ryujinx.Horizon/Sdk/MmNv/Module.cs b/src/Ryujinx.Horizon/Sdk/MmNv/Module.cs index e029d037b..a2379ee6d 100644 --- a/src/Ryujinx.Horizon/Sdk/MmNv/Module.cs +++ b/src/Ryujinx.Horizon/Sdk/MmNv/Module.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.MmNv +namespace Ryujinx.Horizon.Sdk.MmNv { enum Module : uint { diff --git a/src/Ryujinx.Horizon/Sdk/MmNv/Session.cs b/src/Ryujinx.Horizon/Sdk/MmNv/Session.cs index b91585693..b67a9d226 100644 --- a/src/Ryujinx.Horizon/Sdk/MmNv/Session.cs +++ b/src/Ryujinx.Horizon/Sdk/MmNv/Session.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.MmNv +namespace Ryujinx.Horizon.Sdk.MmNv { class Session { diff --git a/src/Ryujinx.Horizon/Sdk/Ncm/ApplicationId.cs b/src/Ryujinx.Horizon/Sdk/Ncm/ApplicationId.cs index 652589e1a..24b7d9cab 100644 --- a/src/Ryujinx.Horizon/Sdk/Ncm/ApplicationId.cs +++ b/src/Ryujinx.Horizon/Sdk/Ncm/ApplicationId.cs @@ -1,6 +1,6 @@ -namespace Ryujinx.Horizon.Sdk.Ncm +namespace Ryujinx.Horizon.Sdk.Ncm { - readonly struct ApplicationId + public readonly struct ApplicationId { public readonly ulong Id; diff --git a/src/Ryujinx.Horizon/Sdk/Ncm/StorageId.cs b/src/Ryujinx.Horizon/Sdk/Ncm/StorageId.cs new file mode 100644 index 000000000..e2fb32505 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Ncm/StorageId.cs @@ -0,0 +1,13 @@ +namespace Ryujinx.Horizon.Sdk.Ncm +{ + public enum StorageId : byte + { + None, + Host, + GameCard, + BuiltInSystem, + BuiltInUser, + SdCard, + Any, + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/AhoCorasick.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/AhoCorasick.cs index e772427c0..6acb9be97 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/AhoCorasick.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/AhoCorasick.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using System.Text; diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/BinaryReader.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/BinaryReader.cs index 5bad376a5..17bfcabbe 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/BinaryReader.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/BinaryReader.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/BitVector32.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/BitVector32.cs index f54562011..484c1c07b 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/BitVector32.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/BitVector32.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Ngc.Detail +namespace Ryujinx.Horizon.Sdk.Ngc.Detail { class BitVector32 { diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Bp.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Bp.cs index 5a8f3df29..d24fab63a 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Bp.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Bp.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Ngc.Detail +namespace Ryujinx.Horizon.Sdk.Ngc.Detail { class Bp { diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/BpNode.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/BpNode.cs index 6884cddd2..2f502cae6 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/BpNode.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/BpNode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Ngc.Detail +namespace Ryujinx.Horizon.Sdk.Ngc.Detail { class BpNode { diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/CompressedArray.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/CompressedArray.cs index 1200f1def..fc5cd683d 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/CompressedArray.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/CompressedArray.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; namespace Ryujinx.Horizon.Sdk.Ngc.Detail diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/ContentsReader.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/ContentsReader.cs index cb865fa0f..6a0fc4f9e 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/ContentsReader.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/ContentsReader.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Fs; using System; using System.IO; diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchCheckState.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchCheckState.cs index 4c014578e..b1a409eae 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchCheckState.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchCheckState.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Ngc.Detail +namespace Ryujinx.Horizon.Sdk.Ngc.Detail { struct MatchCheckState { diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchDelimitedState.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchDelimitedState.cs index d9b82d422..309658198 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchDelimitedState.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchDelimitedState.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Ngc.Detail +namespace Ryujinx.Horizon.Sdk.Ngc.Detail { struct MatchDelimitedState { diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchRangeList.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchRangeList.cs index ad2ad7a90..91600f981 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchRangeList.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchRangeList.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Horizon.Sdk.Ngc.Detail { diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchRangeListState.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchRangeListState.cs index 44a63449e..1a3851fc9 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchRangeListState.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchRangeListState.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Horizon.Sdk.Ngc.Detail { diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchSimilarFormState.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchSimilarFormState.cs index eab9bf959..b0711f723 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchSimilarFormState.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchSimilarFormState.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Ngc.Detail +namespace Ryujinx.Horizon.Sdk.Ngc.Detail { struct MatchSimilarFormState { diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchState.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchState.cs index 04fc1850f..2a701e05b 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchState.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/MatchState.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Horizon.Sdk.Ngc.Detail { diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/ProfanityFilter.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/ProfanityFilter.cs index 980126a6f..20adf16a1 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/ProfanityFilter.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/ProfanityFilter.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Fs; using System; using System.Buffers.Binary; diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/ProfanityFilterBase.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/ProfanityFilterBase.cs index e45c9f478..acfdd9041 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/ProfanityFilterBase.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/ProfanityFilterBase.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using System; using System.Globalization; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Sbv.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Sbv.cs index d6d0bfd60..7a003744c 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Sbv.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Sbv.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Ngc.Detail +namespace Ryujinx.Horizon.Sdk.Ngc.Detail { class Sbv { diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/SbvRank.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/SbvRank.cs index c541b1f57..4ed450f38 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/SbvRank.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/SbvRank.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Numerics; namespace Ryujinx.Horizon.Sdk.Ngc.Detail diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/SbvSelect.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/SbvSelect.cs index 54c3f8b04..c3a69fdd3 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/SbvSelect.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/SbvSelect.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Numerics; namespace Ryujinx.Horizon.Sdk.Ngc.Detail diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Set.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Set.cs index 559b78515..2627a51b6 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Set.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Set.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Ngc.Detail +namespace Ryujinx.Horizon.Sdk.Ngc.Detail { class Set { diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/SimilarFormTable.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/SimilarFormTable.cs index 7999e6ca1..828d7a249 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/SimilarFormTable.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/SimilarFormTable.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Horizon.Sdk.Ngc.Detail { diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/SparseSet.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/SparseSet.cs index 6690203df..724049081 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/SparseSet.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/SparseSet.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Ngc.Detail +namespace Ryujinx.Horizon.Sdk.Ngc.Detail { class SparseSet { diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Utf8ParseResult.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Utf8ParseResult.cs index bf065f86a..54a7e73ed 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Utf8ParseResult.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Utf8ParseResult.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; namespace Ryujinx.Horizon.Sdk.Ngc.Detail { diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Utf8Text.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Utf8Text.cs index 47f780494..34978fdce 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Utf8Text.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Utf8Text.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text; namespace Ryujinx.Horizon.Sdk.Ngc.Detail diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Utf8Util.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Utf8Util.cs index 1bb543ba1..e2a027086 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Utf8Util.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/Utf8Util.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text; namespace Ryujinx.Horizon.Sdk.Ngc.Detail diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/MaskMode.cs b/src/Ryujinx.Horizon/Sdk/Ngc/MaskMode.cs index da0a4e6f6..f4810ac89 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/MaskMode.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/MaskMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Ngc +namespace Ryujinx.Horizon.Sdk.Ngc { enum MaskMode { diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/ProfanityFilterFlags.cs b/src/Ryujinx.Horizon/Sdk/Ngc/ProfanityFilterFlags.cs index 19542c006..4b5f86b43 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/ProfanityFilterFlags.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/ProfanityFilterFlags.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Horizon.Sdk.Ngc { diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/SkipMode.cs b/src/Ryujinx.Horizon/Sdk/Ngc/SkipMode.cs index 69ab48eb9..c177a5d2a 100644 --- a/src/Ryujinx.Horizon/Sdk/Ngc/SkipMode.cs +++ b/src/Ryujinx.Horizon/Sdk/Ngc/SkipMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Ngc +namespace Ryujinx.Horizon.Sdk.Ngc { enum SkipMode { diff --git a/src/Ryujinx.Horizon/Sdk/Ns/ApplicationControlProperty.cs b/src/Ryujinx.Horizon/Sdk/Ns/ApplicationControlProperty.cs new file mode 100644 index 000000000..12c19168d --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Ns/ApplicationControlProperty.cs @@ -0,0 +1,309 @@ +using Ryujinx.Common.Memory; +using Ryujinx.Horizon.Sdk.Arp.Detail; +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; + +namespace Ryujinx.Horizon.Sdk.Ns +{ + public struct ApplicationControlProperty + { + public Array16 Title; + public Array37 Isbn; + public StartupUserAccountValue StartupUserAccount; + public UserAccountSwitchLockValue UserAccountSwitchLock; + public AddOnContentRegistrationTypeValue AddOnContentRegistrationType; + public AttributeFlagValue AttributeFlag; + public uint SupportedLanguageFlag; + public ParentalControlFlagValue ParentalControlFlag; + public ScreenshotValue Screenshot; + public VideoCaptureValue VideoCapture; + public DataLossConfirmationValue DataLossConfirmation; + public PlayLogPolicyValue PlayLogPolicy; + public ulong PresenceGroupId; + public Array32 RatingAge; + public Array16 DisplayVersion; + public ulong AddOnContentBaseId; + public ulong SaveDataOwnerId; + public long UserAccountSaveDataSize; + public long UserAccountSaveDataJournalSize; + public long DeviceSaveDataSize; + public long DeviceSaveDataJournalSize; + public long BcatDeliveryCacheStorageSize; + public Array8 ApplicationErrorCodeCategory; + public Array8 LocalCommunicationId; + public LogoTypeValue LogoType; + public LogoHandlingValue LogoHandling; + public RuntimeAddOnContentInstallValue RuntimeAddOnContentInstall; + public RuntimeParameterDeliveryValue RuntimeParameterDelivery; + public Array2 Reserved30F4; + public CrashReportValue CrashReport; + public HdcpValue Hdcp; + public ulong SeedForPseudoDeviceId; + public Array65 BcatPassphrase; + public StartupUserAccountOptionFlagValue StartupUserAccountOption; + public Array6 ReservedForUserAccountSaveDataOperation; + public long UserAccountSaveDataSizeMax; + public long UserAccountSaveDataJournalSizeMax; + public long DeviceSaveDataSizeMax; + public long DeviceSaveDataJournalSizeMax; + public long TemporaryStorageSize; + public long CacheStorageSize; + public long CacheStorageJournalSize; + public long CacheStorageDataAndJournalSizeMax; + public ushort CacheStorageIndexMax; + public byte Reserved318A; + public byte RuntimeUpgrade; + public uint SupportingLimitedLicenses; + public Array16 PlayLogQueryableApplicationId; + public PlayLogQueryCapabilityValue PlayLogQueryCapability; + public RepairFlagValue RepairFlag; + public byte ProgramIndex; + public RequiredNetworkServiceLicenseOnLaunchValue RequiredNetworkServiceLicenseOnLaunchFlag; + public Array4 Reserved3214; + public ApplicationNeighborDetectionClientConfiguration NeighborDetectionClientConfiguration; + public ApplicationJitConfiguration JitConfiguration; + public RequiredAddOnContentsSetBinaryDescriptor RequiredAddOnContentsSetBinaryDescriptors; + public PlayReportPermissionValue PlayReportPermission; + public CrashScreenshotForProdValue CrashScreenshotForProd; + public CrashScreenshotForDevValue CrashScreenshotForDev; + public byte ContentsAvailabilityTransitionPolicy; + public Array4 Reserved3404; + public AccessibleLaunchRequiredVersionValue AccessibleLaunchRequiredVersion; + public ByteArray3000 Reserved3448; + + public readonly string IsbnString => Encoding.UTF8.GetString(Isbn.AsSpan()).TrimEnd('\0'); + public readonly string DisplayVersionString => Encoding.UTF8.GetString(DisplayVersion.AsSpan()).TrimEnd('\0'); + public readonly string ApplicationErrorCodeCategoryString => Encoding.UTF8.GetString(ApplicationErrorCodeCategory.AsSpan()).TrimEnd('\0'); + public readonly string BcatPassphraseString => Encoding.UTF8.GetString(BcatPassphrase.AsSpan()).TrimEnd('\0'); + + public struct ApplicationTitle + { + public ByteArray512 Name; + public Array256 Publisher; + + public readonly string NameString => Encoding.UTF8.GetString(Name.AsSpan()).TrimEnd('\0'); + public readonly string PublisherString => Encoding.UTF8.GetString(Publisher.AsSpan()).TrimEnd('\0'); + } + + public struct ApplicationNeighborDetectionClientConfiguration + { + public ApplicationNeighborDetectionGroupConfiguration SendGroupConfiguration; + public Array16 ReceivableGroupConfigurations; + } + + public struct ApplicationNeighborDetectionGroupConfiguration + { + public ulong GroupId; + public Array16 Key; + } + + public struct ApplicationJitConfiguration + { + public JitConfigurationFlag Flags; + public long MemorySize; + } + + public struct RequiredAddOnContentsSetBinaryDescriptor + { + public Array32 Descriptors; + } + + public struct AccessibleLaunchRequiredVersionValue + { + public Array8 ApplicationId; + } + + public enum Language + { + AmericanEnglish = 0, + BritishEnglish = 1, + Japanese = 2, + French = 3, + German = 4, + LatinAmericanSpanish = 5, + Spanish = 6, + Italian = 7, + Dutch = 8, + CanadianFrench = 9, + Portuguese = 10, + Russian = 11, + Korean = 12, + TraditionalChinese = 13, + SimplifiedChinese = 14, + BrazilianPortuguese = 15, + } + + public enum Organization + { + CERO = 0, + GRACGCRB = 1, + GSRMR = 2, + ESRB = 3, + ClassInd = 4, + USK = 5, + PEGI = 6, + PEGIPortugal = 7, + PEGIBBFC = 8, + Russian = 9, + ACB = 10, + OFLC = 11, + IARCGeneric = 12, + } + + public enum StartupUserAccountValue : byte + { + None = 0, + Required = 1, + RequiredWithNetworkServiceAccountAvailable = 2, + } + + public enum UserAccountSwitchLockValue : byte + { + Disable = 0, + Enable = 1, + } + + public enum AddOnContentRegistrationTypeValue : byte + { + AllOnLaunch = 0, + OnDemand = 1, + } + + [Flags] + public enum AttributeFlagValue + { + None = 0, + Demo = 1 << 0, + RetailInteractiveDisplay = 1 << 1, + } + + public enum ParentalControlFlagValue + { + None = 0, + FreeCommunication = 1, + } + + public enum ScreenshotValue : byte + { + Allow = 0, + Deny = 1, + } + + public enum VideoCaptureValue : byte + { + Disable = 0, + Manual = 1, + Enable = 2, + } + + public enum DataLossConfirmationValue : byte + { + None = 0, + Required = 1, + } + + public enum PlayLogPolicyValue : byte + { + Open = 0, + LogOnly = 1, + None = 2, + Closed = 3, + All = Open, + } + + public enum LogoTypeValue : byte + { + LicensedByNintendo = 0, + DistributedByNintendo = 1, + Nintendo = 2, + } + + public enum LogoHandlingValue : byte + { + Auto = 0, + Manual = 1, + } + + public enum RuntimeAddOnContentInstallValue : byte + { + Deny = 0, + AllowAppend = 1, + AllowAppendButDontDownloadWhenUsingNetwork = 2, + } + + public enum RuntimeParameterDeliveryValue : byte + { + Always = 0, + AlwaysIfUserStateMatched = 1, + OnRestart = 2, + } + + public enum CrashReportValue : byte + { + Deny = 0, + Allow = 1, + } + + public enum HdcpValue : byte + { + None = 0, + Required = 1, + } + + [Flags] + public enum StartupUserAccountOptionFlagValue : byte + { + None = 0, + IsOptional = 1 << 0, + } + + public enum PlayLogQueryCapabilityValue : byte + { + None = 0, + WhiteList = 1, + All = 2, + } + + [Flags] + public enum RepairFlagValue : byte + { + None = 0, + SuppressGameCardAccess = 1 << 0, + } + + [Flags] + public enum RequiredNetworkServiceLicenseOnLaunchValue : byte + { + None = 0, + Common = 1 << 0, + } + + [Flags] + public enum JitConfigurationFlag : ulong + { + None = 0, + Enabled = 1 << 0, + } + + [Flags] + public enum PlayReportPermissionValue : byte + { + None = 0, + TargetMarketing = 1 << 0, + } + + public enum CrashScreenshotForProdValue : byte + { + Deny = 0, + Allow = 1, + } + + public enum CrashScreenshotForDevValue : byte + { + Deny = 0, + Allow = 1, + } + } +} diff --git a/src/Ryujinx.Horizon/Sdk/OsTypes/Event.cs b/src/Ryujinx.Horizon/Sdk/OsTypes/Event.cs index 79d7408e3..cad251311 100644 --- a/src/Ryujinx.Horizon/Sdk/OsTypes/Event.cs +++ b/src/Ryujinx.Horizon/Sdk/OsTypes/Event.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; namespace Ryujinx.Horizon.Sdk.OsTypes diff --git a/src/Ryujinx.Horizon/Sdk/OsTypes/EventClearMode.cs b/src/Ryujinx.Horizon/Sdk/OsTypes/EventClearMode.cs index b82518d79..75b1cb80d 100644 --- a/src/Ryujinx.Horizon/Sdk/OsTypes/EventClearMode.cs +++ b/src/Ryujinx.Horizon/Sdk/OsTypes/EventClearMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.OsTypes +namespace Ryujinx.Horizon.Sdk.OsTypes { enum EventClearMode { diff --git a/src/Ryujinx.Horizon/Sdk/OsTypes/EventType.cs b/src/Ryujinx.Horizon/Sdk/OsTypes/EventType.cs index b4b1a275c..573e79b61 100644 --- a/src/Ryujinx.Horizon/Sdk/OsTypes/EventType.cs +++ b/src/Ryujinx.Horizon/Sdk/OsTypes/EventType.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace Ryujinx.Horizon.Sdk.OsTypes { diff --git a/src/Ryujinx.Horizon/Sdk/OsTypes/Impl/InterProcessEvent.cs b/src/Ryujinx.Horizon/Sdk/OsTypes/Impl/InterProcessEvent.cs index 62b5bf066..4da4ee86c 100644 --- a/src/Ryujinx.Horizon/Sdk/OsTypes/Impl/InterProcessEvent.cs +++ b/src/Ryujinx.Horizon/Sdk/OsTypes/Impl/InterProcessEvent.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; namespace Ryujinx.Horizon.Sdk.OsTypes.Impl { diff --git a/src/Ryujinx.Horizon/Sdk/OsTypes/Impl/InterProcessEventImpl.cs b/src/Ryujinx.Horizon/Sdk/OsTypes/Impl/InterProcessEventImpl.cs index a8aeacc92..e15913c06 100644 --- a/src/Ryujinx.Horizon/Sdk/OsTypes/Impl/InterProcessEventImpl.cs +++ b/src/Ryujinx.Horizon/Sdk/OsTypes/Impl/InterProcessEventImpl.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using System; namespace Ryujinx.Horizon.Sdk.OsTypes.Impl diff --git a/src/Ryujinx.Horizon/Sdk/OsTypes/Impl/MultiWaitImpl.cs b/src/Ryujinx.Horizon/Sdk/OsTypes/Impl/MultiWaitImpl.cs index 057aac890..2aefb0db5 100644 --- a/src/Ryujinx.Horizon/Sdk/OsTypes/Impl/MultiWaitImpl.cs +++ b/src/Ryujinx.Horizon/Sdk/OsTypes/Impl/MultiWaitImpl.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Horizon.Common; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.Horizon/Sdk/OsTypes/InterProcessEventType.cs b/src/Ryujinx.Horizon/Sdk/OsTypes/InterProcessEventType.cs index 5f6824fea..39c93e570 100644 --- a/src/Ryujinx.Horizon/Sdk/OsTypes/InterProcessEventType.cs +++ b/src/Ryujinx.Horizon/Sdk/OsTypes/InterProcessEventType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.OsTypes +namespace Ryujinx.Horizon.Sdk.OsTypes { struct InterProcessEventType { diff --git a/src/Ryujinx.Horizon/Sdk/OsTypes/MultiWait.cs b/src/Ryujinx.Horizon/Sdk/OsTypes/MultiWait.cs index 5a91f6c36..0e73e3f88 100644 --- a/src/Ryujinx.Horizon/Sdk/OsTypes/MultiWait.cs +++ b/src/Ryujinx.Horizon/Sdk/OsTypes/MultiWait.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.OsTypes.Impl; +using Ryujinx.Horizon.Sdk.OsTypes.Impl; namespace Ryujinx.Horizon.Sdk.OsTypes { diff --git a/src/Ryujinx.Horizon/Sdk/OsTypes/MultiWaitHolder.cs b/src/Ryujinx.Horizon/Sdk/OsTypes/MultiWaitHolder.cs index a24b19064..e0473ecaf 100644 --- a/src/Ryujinx.Horizon/Sdk/OsTypes/MultiWaitHolder.cs +++ b/src/Ryujinx.Horizon/Sdk/OsTypes/MultiWaitHolder.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.OsTypes +namespace Ryujinx.Horizon.Sdk.OsTypes { class MultiWaitHolder : MultiWaitHolderBase { diff --git a/src/Ryujinx.Horizon/Sdk/OsTypes/MultiWaitHolderBase.cs b/src/Ryujinx.Horizon/Sdk/OsTypes/MultiWaitHolderBase.cs index 018305ba6..4bccba6c2 100644 --- a/src/Ryujinx.Horizon/Sdk/OsTypes/MultiWaitHolderBase.cs +++ b/src/Ryujinx.Horizon/Sdk/OsTypes/MultiWaitHolderBase.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.OsTypes.Impl; +using Ryujinx.Horizon.Sdk.OsTypes.Impl; namespace Ryujinx.Horizon.Sdk.OsTypes { diff --git a/src/Ryujinx.Horizon/Sdk/OsTypes/MultiWaitHolderOfHandle.cs b/src/Ryujinx.Horizon/Sdk/OsTypes/MultiWaitHolderOfHandle.cs index e5839a480..1f5fefde0 100644 --- a/src/Ryujinx.Horizon/Sdk/OsTypes/MultiWaitHolderOfHandle.cs +++ b/src/Ryujinx.Horizon/Sdk/OsTypes/MultiWaitHolderOfHandle.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.OsTypes +namespace Ryujinx.Horizon.Sdk.OsTypes { class MultiWaitHolderOfHandle : MultiWaitHolder { diff --git a/src/Ryujinx.Horizon/Sdk/OsTypes/OsEvent.cs b/src/Ryujinx.Horizon/Sdk/OsTypes/OsEvent.cs index eac5e7c43..8efe614f2 100644 --- a/src/Ryujinx.Horizon/Sdk/OsTypes/OsEvent.cs +++ b/src/Ryujinx.Horizon/Sdk/OsTypes/OsEvent.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Threading; diff --git a/src/Ryujinx.Horizon/Sdk/OsTypes/OsMultiWait.cs b/src/Ryujinx.Horizon/Sdk/OsTypes/OsMultiWait.cs index 827de2313..8e9648de5 100644 --- a/src/Ryujinx.Horizon/Sdk/OsTypes/OsMultiWait.cs +++ b/src/Ryujinx.Horizon/Sdk/OsTypes/OsMultiWait.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.OsTypes +namespace Ryujinx.Horizon.Sdk.OsTypes { static partial class Os { diff --git a/src/Ryujinx.Horizon/Sdk/OsTypes/OsProcessHandle.cs b/src/Ryujinx.Horizon/Sdk/OsTypes/OsProcessHandle.cs index 6a6d9bf23..c835be2c9 100644 --- a/src/Ryujinx.Horizon/Sdk/OsTypes/OsProcessHandle.cs +++ b/src/Ryujinx.Horizon/Sdk/OsTypes/OsProcessHandle.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; namespace Ryujinx.Horizon.Sdk.OsTypes { diff --git a/src/Ryujinx.Horizon/Sdk/OsTypes/OsResult.cs b/src/Ryujinx.Horizon/Sdk/OsTypes/OsResult.cs index 302922f12..77da87fa7 100644 --- a/src/Ryujinx.Horizon/Sdk/OsTypes/OsResult.cs +++ b/src/Ryujinx.Horizon/Sdk/OsTypes/OsResult.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; namespace Ryujinx.Horizon.Sdk.OsTypes { diff --git a/src/Ryujinx.Horizon/Sdk/OsTypes/OsSystemEvent.cs b/src/Ryujinx.Horizon/Sdk/OsTypes/OsSystemEvent.cs index 40723a5cf..8fac94abe 100644 --- a/src/Ryujinx.Horizon/Sdk/OsTypes/OsSystemEvent.cs +++ b/src/Ryujinx.Horizon/Sdk/OsTypes/OsSystemEvent.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.OsTypes.Impl; using System; diff --git a/src/Ryujinx.Horizon/Sdk/OsTypes/OsThreadManager.cs b/src/Ryujinx.Horizon/Sdk/OsTypes/OsThreadManager.cs index 2037cd7fe..d47493eba 100644 --- a/src/Ryujinx.Horizon/Sdk/OsTypes/OsThreadManager.cs +++ b/src/Ryujinx.Horizon/Sdk/OsTypes/OsThreadManager.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.OsTypes +namespace Ryujinx.Horizon.Sdk.OsTypes { static partial class Os { diff --git a/src/Ryujinx.Horizon/Sdk/OsTypes/SystemEventType.cs b/src/Ryujinx.Horizon/Sdk/OsTypes/SystemEventType.cs index dee0fa43a..a838f46c4 100644 --- a/src/Ryujinx.Horizon/Sdk/OsTypes/SystemEventType.cs +++ b/src/Ryujinx.Horizon/Sdk/OsTypes/SystemEventType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.OsTypes +namespace Ryujinx.Horizon.Sdk.OsTypes { struct SystemEventType { diff --git a/src/Ryujinx.Horizon/Sdk/OsTypes/TriBool.cs b/src/Ryujinx.Horizon/Sdk/OsTypes/TriBool.cs index 868d10258..b162db9b7 100644 --- a/src/Ryujinx.Horizon/Sdk/OsTypes/TriBool.cs +++ b/src/Ryujinx.Horizon/Sdk/OsTypes/TriBool.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.OsTypes +namespace Ryujinx.Horizon.Sdk.OsTypes { enum TriBool { diff --git a/src/Ryujinx.Horizon/Sdk/Ovln/IReceiverService.cs b/src/Ryujinx.Horizon/Sdk/Ovln/IReceiverService.cs index f59e8002d..d663ed607 100644 --- a/src/Ryujinx.Horizon/Sdk/Ovln/IReceiverService.cs +++ b/src/Ryujinx.Horizon/Sdk/Ovln/IReceiverService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Ovln { diff --git a/src/Ryujinx.Horizon/Sdk/Ovln/ISenderService.cs b/src/Ryujinx.Horizon/Sdk/Ovln/ISenderService.cs index 93323ba50..b0b9b2f07 100644 --- a/src/Ryujinx.Horizon/Sdk/Ovln/ISenderService.cs +++ b/src/Ryujinx.Horizon/Sdk/Ovln/ISenderService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Ovln { diff --git a/src/Ryujinx.Horizon/Sdk/Prepo/IPrepoService.cs b/src/Ryujinx.Horizon/Sdk/Prepo/IPrepoService.cs index 3f2628205..fd63755e3 100644 --- a/src/Ryujinx.Horizon/Sdk/Prepo/IPrepoService.cs +++ b/src/Ryujinx.Horizon/Sdk/Prepo/IPrepoService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Account; using Ryujinx.Horizon.Sdk.Sf; using System; diff --git a/src/Ryujinx.Horizon/Sdk/Psc/IPmControl.cs b/src/Ryujinx.Horizon/Sdk/Psc/IPmControl.cs index 6a71d6842..679a43537 100644 --- a/src/Ryujinx.Horizon/Sdk/Psc/IPmControl.cs +++ b/src/Ryujinx.Horizon/Sdk/Psc/IPmControl.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Psc { diff --git a/src/Ryujinx.Horizon/Sdk/Psc/IPmService.cs b/src/Ryujinx.Horizon/Sdk/Psc/IPmService.cs index c58665818..53e703f82 100644 --- a/src/Ryujinx.Horizon/Sdk/Psc/IPmService.cs +++ b/src/Ryujinx.Horizon/Sdk/Psc/IPmService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Psc { diff --git a/src/Ryujinx.Horizon/Sdk/Psc/IPmStateLock.cs b/src/Ryujinx.Horizon/Sdk/Psc/IPmStateLock.cs index 41ead492e..2335b8c84 100644 --- a/src/Ryujinx.Horizon/Sdk/Psc/IPmStateLock.cs +++ b/src/Ryujinx.Horizon/Sdk/Psc/IPmStateLock.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Psc { diff --git a/src/Ryujinx.Horizon/Sdk/ServiceUtil.cs b/src/Ryujinx.Horizon/Sdk/ServiceUtil.cs index ccd6c93a6..5527c1e35 100644 --- a/src/Ryujinx.Horizon/Sdk/ServiceUtil.cs +++ b/src/Ryujinx.Horizon/Sdk/ServiceUtil.cs @@ -35,5 +35,254 @@ namespace Ryujinx.Horizon.Sdk return CmifMessage.ParseResponse(out response, HorizonStatic.AddressSpace.GetWritableRegion(tlsAddress, tlsSize).Memory.Span, false, 0); } + + public static Result SendRequest( + out CmifResponse response, + int sessionHandle, + uint requestId, + bool sendPid, + scoped ReadOnlySpan data, + ReadOnlySpan bufferFlags, + ReadOnlySpan buffers) + { + ulong tlsAddress = HorizonStatic.ThreadContext.TlsAddress; + int tlsSize = Api.TlsMessageBufferSize; + + using (var tlsRegion = HorizonStatic.AddressSpace.GetWritableRegion(tlsAddress, tlsSize)) + { + CmifRequestFormat format = new() + { + DataSize = data.Length, + RequestId = requestId, + SendPid = sendPid, + }; + + for (int index = 0; index < bufferFlags.Length; index++) + { + FormatProcessBuffer(ref format, bufferFlags[index]); + } + + CmifRequest request = CmifMessage.CreateRequest(tlsRegion.Memory.Span, format); + + for (int index = 0; index < buffers.Length; index++) + { + RequestProcessBuffer(ref request, buffers[index], bufferFlags[index]); + } + + data.CopyTo(request.Data); + } + + Result result = HorizonStatic.Syscall.SendSyncRequest(sessionHandle); + + if (result.IsFailure) + { + response = default; + + return result; + } + + return CmifMessage.ParseResponse(out response, HorizonStatic.AddressSpace.GetWritableRegion(tlsAddress, tlsSize).Memory.Span, false, 0); + } + + private static void FormatProcessBuffer(ref CmifRequestFormat format, HipcBufferFlags flags) + { + if (flags == 0) + { + return; + } + + bool isIn = flags.HasFlag(HipcBufferFlags.In); + bool isOut = flags.HasFlag(HipcBufferFlags.Out); + + if (flags.HasFlag(HipcBufferFlags.AutoSelect)) + { + if (isIn) + { + format.InAutoBuffersCount++; + } + + if (isOut) + { + format.OutAutoBuffersCount++; + } + } + else if (flags.HasFlag(HipcBufferFlags.Pointer)) + { + if (isIn) + { + format.InPointersCount++; + } + + if (isOut) + { + if (flags.HasFlag(HipcBufferFlags.FixedSize)) + { + format.OutFixedPointersCount++; + } + else + { + format.OutPointersCount++; + } + } + } + else if (flags.HasFlag(HipcBufferFlags.MapAlias)) + { + if (isIn && isOut) + { + format.InOutBuffersCount++; + } + else if (isIn) + { + format.InBuffersCount++; + } + else + { + format.OutBuffersCount++; + } + } + } + + private static void RequestProcessBuffer(ref CmifRequest request, PointerAndSize buffer, HipcBufferFlags flags) + { + if (flags == 0) + { + return; + } + + bool isIn = flags.HasFlag(HipcBufferFlags.In); + bool isOut = flags.HasFlag(HipcBufferFlags.Out); + + if (flags.HasFlag(HipcBufferFlags.AutoSelect)) + { + HipcBufferMode mode = HipcBufferMode.Normal; + + if (flags.HasFlag(HipcBufferFlags.MapTransferAllowsNonSecure)) + { + mode = HipcBufferMode.NonSecure; + } + + if (flags.HasFlag(HipcBufferFlags.MapTransferAllowsNonDevice)) + { + mode = HipcBufferMode.NonDevice; + } + + if (isIn) + { + RequestInAutoBuffer(ref request, buffer.Address, buffer.Size, mode); + } + + if (isOut) + { + RequestOutAutoBuffer(ref request, buffer.Address, buffer.Size, mode); + } + } + else if (flags.HasFlag(HipcBufferFlags.Pointer)) + { + if (isIn) + { + RequestInPointer(ref request, buffer.Address, buffer.Size); + } + + if (isOut) + { + if (flags.HasFlag(HipcBufferFlags.FixedSize)) + { + RequestOutFixedPointer(ref request, buffer.Address, buffer.Size); + } + else + { + RequestOutPointer(ref request, buffer.Address, buffer.Size); + } + } + } + else if (flags.HasFlag(HipcBufferFlags.MapAlias)) + { + HipcBufferMode mode = HipcBufferMode.Normal; + + if (flags.HasFlag(HipcBufferFlags.MapTransferAllowsNonSecure)) + { + mode = HipcBufferMode.NonSecure; + } + + if (flags.HasFlag(HipcBufferFlags.MapTransferAllowsNonDevice)) + { + mode = HipcBufferMode.NonDevice; + } + + if (isIn && isOut) + { + RequestInOutBuffer(ref request, buffer.Address, buffer.Size, mode); + } + else if (isIn) + { + RequestInBuffer(ref request, buffer.Address, buffer.Size, mode); + } + else + { + RequestOutBuffer(ref request, buffer.Address, buffer.Size, mode); + } + } + } + + private static void RequestInAutoBuffer(ref CmifRequest request, ulong bufferAddress, ulong bufferSize, HipcBufferMode mode) + { + if (request.ServerPointerSize != 0 && bufferSize <= (ulong)request.ServerPointerSize) + { + RequestInPointer(ref request, bufferAddress, bufferSize); + RequestInBuffer(ref request, 0UL, 0UL, mode); + } + else + { + RequestInPointer(ref request, 0UL, 0UL); + RequestInBuffer(ref request, bufferAddress, bufferSize, mode); + } + } + + private static void RequestOutAutoBuffer(ref CmifRequest request, ulong bufferAddress, ulong bufferSize, HipcBufferMode mode) + { + if (request.ServerPointerSize != 0 && bufferSize <= (ulong)request.ServerPointerSize) + { + RequestOutPointer(ref request, bufferAddress, bufferSize); + RequestOutBuffer(ref request, 0UL, 0UL, mode); + } + else + { + RequestOutPointer(ref request, 0UL, 0UL); + RequestOutBuffer(ref request, bufferAddress, bufferSize, mode); + } + } + + private static void RequestInBuffer(ref CmifRequest request, ulong bufferAddress, ulong bufferSize, HipcBufferMode mode) + { + request.Hipc.SendBuffers[request.SendBufferIndex++] = new HipcBufferDescriptor(bufferAddress, bufferSize, mode); + } + + private static void RequestOutBuffer(ref CmifRequest request, ulong bufferAddress, ulong bufferSize, HipcBufferMode mode) + { + request.Hipc.ReceiveBuffers[request.RecvBufferIndex++] = new HipcBufferDescriptor(bufferAddress, bufferSize, mode); + } + + private static void RequestInOutBuffer(ref CmifRequest request, ulong bufferAddress, ulong bufferSize, HipcBufferMode mode) + { + request.Hipc.ExchangeBuffers[request.ExchBufferIndex++] = new HipcBufferDescriptor(bufferAddress, bufferSize, mode); + } + + private static void RequestInPointer(ref CmifRequest request, ulong bufferAddress, ulong bufferSize) + { + request.Hipc.SendStatics[request.SendStaticIndex++] = new HipcStaticDescriptor(bufferAddress, (ushort)bufferSize, request.CurrentInPointerId++); + request.ServerPointerSize -= (int)bufferSize; + } + + private static void RequestOutFixedPointer(ref CmifRequest request, ulong bufferAddress, ulong bufferSize) + { + request.Hipc.ReceiveList[request.RecvListIndex++] = new HipcReceiveListEntry(bufferAddress, (ushort)bufferSize); + request.ServerPointerSize -= (int)bufferSize; + } + + private static void RequestOutPointer(ref CmifRequest request, ulong bufferAddress, ulong bufferSize) + { + RequestOutFixedPointer(ref request, bufferAddress, bufferSize); + request.OutPointerSizes[request.OutPointerSizeIndex++] = (ushort)bufferSize; + } } } diff --git a/src/Ryujinx.Horizon/Sdk/Settings/BatteryLot.cs b/src/Ryujinx.Horizon/Sdk/Settings/BatteryLot.cs new file mode 100644 index 000000000..71185fcd0 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/BatteryLot.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings +{ + [StructLayout(LayoutKind.Sequential, Size = 0x18, Pack = 0x1)] + struct BatteryLot + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/AccelerometerOffset.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/AccelerometerOffset.cs new file mode 100644 index 000000000..292a368f1 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/AccelerometerOffset.cs @@ -0,0 +1,12 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x6, Pack = 0x2)] + struct AccelerometerOffset + { + public ushort X; + public ushort Y; + public ushort Z; + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/AccelerometerScale.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/AccelerometerScale.cs new file mode 100644 index 000000000..ef9d17ef9 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/AccelerometerScale.cs @@ -0,0 +1,12 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x6, Pack = 0x2)] + struct AccelerometerScale + { + public ushort X; + public ushort Y; + public ushort Z; + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/AmiiboEcdsaCertificate.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/AmiiboEcdsaCertificate.cs new file mode 100644 index 000000000..7cbab2f09 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/AmiiboEcdsaCertificate.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x74, Pack = 0x4)] + struct AmiiboEcdsaCertificate + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/AmiiboEcqvBlsCertificate.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/AmiiboEcqvBlsCertificate.cs new file mode 100644 index 000000000..8d16b51b1 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/AmiiboEcqvBlsCertificate.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x24, Pack = 0x4)] + struct AmiiboEcqvBlsCertificate + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/AmiiboEcqvBlsKey.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/AmiiboEcqvBlsKey.cs new file mode 100644 index 000000000..da6ca53bc --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/AmiiboEcqvBlsKey.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x48, Pack = 0x4)] + struct AmiiboEcqvBlsKey + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/AmiiboEcqvBlsRootCertificate.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/AmiiboEcqvBlsRootCertificate.cs new file mode 100644 index 000000000..e69e38a1a --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/AmiiboEcqvBlsRootCertificate.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x94, Pack = 0x4)] + struct AmiiboEcqvBlsRootCertificate + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/AmiiboEcqvCertificate.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/AmiiboEcqvCertificate.cs new file mode 100644 index 000000000..43742fbb7 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/AmiiboEcqvCertificate.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x18, Pack = 0x4)] + struct AmiiboEcqvCertificate + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/AmiiboKey.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/AmiiboKey.cs new file mode 100644 index 000000000..43ffccb00 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/AmiiboKey.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x58, Pack = 0x4)] + struct AmiiboKey + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/AnalogStickFactoryCalibration.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/AnalogStickFactoryCalibration.cs new file mode 100644 index 000000000..3fe6f3223 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/AnalogStickFactoryCalibration.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x9, Pack = 0x1)] + struct AnalogStickFactoryCalibration + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/AnalogStickModelParameter.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/AnalogStickModelParameter.cs new file mode 100644 index 000000000..a442032c7 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/AnalogStickModelParameter.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x12, Pack = 0x1)] + struct AnalogStickModelParameter + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/BdAddress.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/BdAddress.cs new file mode 100644 index 000000000..519d72e8f --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/BdAddress.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x6, Pack = 0x1)] + struct BdAddress + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/ConfigurationId1.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/ConfigurationId1.cs new file mode 100644 index 000000000..40565805f --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/ConfigurationId1.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x1E, Pack = 0x1)] + struct ConfigurationId1 + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/ConsoleSixAxisSensorHorizontalOffset.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/ConsoleSixAxisSensorHorizontalOffset.cs new file mode 100644 index 000000000..c5503edc5 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/ConsoleSixAxisSensorHorizontalOffset.cs @@ -0,0 +1,12 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x6, Pack = 0x2)] + struct ConsoleSixAxisSensorHorizontalOffset + { + public ushort X; + public ushort Y; + public ushort Z; + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/CountryCode.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/CountryCode.cs new file mode 100644 index 000000000..daf2ba3b8 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/CountryCode.cs @@ -0,0 +1,8 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + struct CountryCode + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/EccB233DeviceCertificate.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/EccB233DeviceCertificate.cs new file mode 100644 index 000000000..727408ed5 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/EccB233DeviceCertificate.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x180)] + struct EccB233DeviceCertificate + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/EccB233DeviceKey.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/EccB233DeviceKey.cs new file mode 100644 index 000000000..a0481f4dc --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/EccB233DeviceKey.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x58, Pack = 0x4)] + struct EccB233DeviceKey + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/GameCardCertificate.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/GameCardCertificate.cs new file mode 100644 index 000000000..ce3908afe --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/GameCardCertificate.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x400)] + struct GameCardCertificate + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/GameCardKey.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/GameCardKey.cs new file mode 100644 index 000000000..81144ac48 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/GameCardKey.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x138)] + struct GameCardKey + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/GyroscopeOffset.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/GyroscopeOffset.cs new file mode 100644 index 000000000..801d117cb --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/GyroscopeOffset.cs @@ -0,0 +1,12 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x6, Pack = 0x2)] + struct GyroscopeOffset + { + public ushort X; + public ushort Y; + public ushort Z; + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/GyroscopeScale.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/GyroscopeScale.cs new file mode 100644 index 000000000..7812281f8 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/GyroscopeScale.cs @@ -0,0 +1,12 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x6, Pack = 0x2)] + struct GyroscopeScale + { + public ushort X; + public ushort Y; + public ushort Z; + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/MacAddress.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/MacAddress.cs new file mode 100644 index 000000000..65e222ee5 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/MacAddress.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x6, Pack = 0x1)] + struct MacAddress + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/Rsa2048DeviceCertificate.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/Rsa2048DeviceCertificate.cs new file mode 100644 index 000000000..57217059f --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/Rsa2048DeviceCertificate.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x240)] + struct Rsa2048DeviceCertificate + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/Rsa2048DeviceKey.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/Rsa2048DeviceKey.cs new file mode 100644 index 000000000..d2fd51cf7 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/Rsa2048DeviceKey.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x248)] + struct Rsa2048DeviceKey + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/SerialNumber.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/SerialNumber.cs new file mode 100644 index 000000000..af664cdc5 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/SerialNumber.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x18, Pack = 0x1)] + struct SerialNumber + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/SpeakerParameter.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/SpeakerParameter.cs new file mode 100644 index 000000000..f147f66ff --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/SpeakerParameter.cs @@ -0,0 +1,32 @@ +using Ryujinx.Common.Memory; +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x5A, Pack = 0x2)] + struct SpeakerParameter + { + public ushort Version; + public Array34 Reserved; + public ushort SpeakerHpf2A1; + public ushort SpeakerHpf2A2; + public ushort SpeakerHpf2H0; + public ushort SpeakerEqInputVolume; + public ushort SpeakerEqOutputVolume; + public ushort SpeakerEqCtrl1; + public ushort SpeakerEqCtrl2; + public ushort SpeakerDrcAgcCtrl2; + public ushort SpeakerDrcAgcCtrl3; + public ushort SpeakerDrcAgcCtrl1; + public ushort SpeakerAnalogVolume; + public ushort HeadphoneAnalogVolume; + public ushort SpeakerDigitalVolumeMin; + public ushort SpeakerDigitalVolumeMax; + public ushort HeadphoneDigitalVolumeMin; + public ushort HeadphoneDigitalVolumeMax; + public ushort MicFixedGain; + public ushort MicVariableVolumeMin; + public ushort MicVariableVolumeMax; + public Array16 Reserved2; + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/SslCertificate.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/SslCertificate.cs new file mode 100644 index 000000000..5d8252164 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/SslCertificate.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x804)] + struct SslCertificate + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/SslKey.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/SslKey.cs new file mode 100644 index 000000000..7d4b41369 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/SslKey.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.Factory +{ + [StructLayout(LayoutKind.Sequential, Size = 0x138)] + struct SslKey + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Language.cs b/src/Ryujinx.Horizon/Sdk/Settings/Language.cs new file mode 100644 index 000000000..4ffc66fec --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/Language.cs @@ -0,0 +1,24 @@ +namespace Ryujinx.Horizon.Sdk.Settings +{ + enum Language : uint + { + Japanese, + AmericanEnglish, + French, + German, + Italian, + Spanish, + Chinese, + Korean, + Dutch, + Portuguese, + Russian, + Taiwanese, + BritishEnglish, + CanadianFrench, + LatinAmericanSpanish, + SimplifiedChinese, + TraditionalChinese, + BrazilianPortuguese, + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/LanguageCode.cs b/src/Ryujinx.Horizon/Sdk/Settings/LanguageCode.cs new file mode 100644 index 000000000..dc9712692 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/LanguageCode.cs @@ -0,0 +1,63 @@ +using Ryujinx.Common.Memory; +using System; +using System.Runtime.InteropServices; +using System.Text; + +namespace Ryujinx.Horizon.Sdk.Settings +{ + [StructLayout(LayoutKind.Sequential, Size = 0x8, Pack = 0x1)] + struct LanguageCode + { + private static readonly string[] _languageCodes = new string[] + { + "ja", + "en-US", + "fr", + "de", + "it", + "es", + "zh-CN", + "ko", + "nl", + "pt", + "ru", + "zh-TW", + "en-GB", + "fr-CA", + "es-419", + "zh-Hans", + "zh-Hant", + "pt-BR" + }; + + public Array8 Value; + + public bool IsValid() + { + int length = Value.AsSpan().IndexOf((byte)0); + if (length < 0) + { + return false; + } + + string str = Encoding.ASCII.GetString(Value.AsSpan()[..length]); + + return _languageCodes.AsSpan().Contains(str); + } + + public LanguageCode(Language language) + { + if ((uint)language >= _languageCodes.Length) + { + throw new ArgumentOutOfRangeException(nameof(language)); + } + + Value = new LanguageCode(_languageCodes[(int)language]).Value; + } + + public LanguageCode(string strCode) + { + Encoding.ASCII.GetBytes(strCode, Value.AsSpan()); + } + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/SettingsItemKey.cs b/src/Ryujinx.Horizon/Sdk/Settings/SettingsItemKey.cs new file mode 100644 index 000000000..661184103 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/SettingsItemKey.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings +{ + [StructLayout(LayoutKind.Sequential, Size = 0x48)] + struct SettingsItemKey + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/SettingsName.cs b/src/Ryujinx.Horizon/Sdk/Settings/SettingsName.cs new file mode 100644 index 000000000..6864b8cd6 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/SettingsName.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings +{ + [StructLayout(LayoutKind.Sequential, Size = 0x48)] + struct SettingsName + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/AccountNotificationSettings.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/AccountNotificationSettings.cs new file mode 100644 index 000000000..a2cbad6a6 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/AccountNotificationSettings.cs @@ -0,0 +1,15 @@ +using Ryujinx.Horizon.Sdk.Account; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + struct AccountNotificationSettings + { +#pragma warning disable CS0649 // Field is never assigned to + public Uid UserId; + public uint Flags; + public byte FriendPresenceOverlayPermission; + public byte FriendInvitationOverlayPermission; + public ushort Reserved; +#pragma warning restore CS0649 + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/AccountOnlineStorageSettings.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/AccountOnlineStorageSettings.cs new file mode 100644 index 000000000..3ed77e52b --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/AccountOnlineStorageSettings.cs @@ -0,0 +1,6 @@ +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + struct AccountOnlineStorageSettings + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/AccountSettings.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/AccountSettings.cs new file mode 100644 index 000000000..bd27ea0bf --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/AccountSettings.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x4, Pack = 0x4)] + struct AccountSettings + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/AllowedSslHost.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/AllowedSslHost.cs new file mode 100644 index 000000000..cb90daf18 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/AllowedSslHost.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x100)] + struct AllowedSslHost + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/AnalogStickUserCalibration.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/AnalogStickUserCalibration.cs new file mode 100644 index 000000000..36023da9c --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/AnalogStickUserCalibration.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x10, Pack = 0x4)] + struct AnalogStickUserCalibration + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/AppletLaunchFlag.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/AppletLaunchFlag.cs new file mode 100644 index 000000000..00d6f4d06 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/AppletLaunchFlag.cs @@ -0,0 +1,9 @@ +using System; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [Flags] + enum AppletLaunchFlag : uint + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/AudioVolume.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/AudioVolume.cs new file mode 100644 index 000000000..d246bc2b9 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/AudioVolume.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x8, Pack = 0x4)] + struct AudioVolume + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/BacklightSettings.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/BacklightSettings.cs new file mode 100644 index 000000000..00de6869c --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/BacklightSettings.cs @@ -0,0 +1,22 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x28, Pack = 0x4)] + struct BacklightSettings + { + // TODO: Determine field names. + public uint Unknown0x00; + public float Unknown0x04; + // 1st group + public float Unknown0x08; + public float Unknown0x0C; + public float Unknown0x10; + // 2nd group + public float Unknown0x14; + public float Unknown0x18; + public float Unknown0x1C; + public float Unknown0x20; + public float Unknown0x24; + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/BacklightSettingsEx.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/BacklightSettingsEx.cs new file mode 100644 index 000000000..347afdfe3 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/BacklightSettingsEx.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x2C, Pack = 0x4)] + struct BacklightSettingsEx + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/BlePairingSettings.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/BlePairingSettings.cs new file mode 100644 index 000000000..d9b01f9ff --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/BlePairingSettings.cs @@ -0,0 +1,6 @@ +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + struct BlePairingSettings + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/BluetoothDevicesSettings.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/BluetoothDevicesSettings.cs new file mode 100644 index 000000000..ec5c97c5a --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/BluetoothDevicesSettings.cs @@ -0,0 +1,29 @@ +using Ryujinx.Common.Memory; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + struct BluetoothDevicesSettings + { +#pragma warning disable CS0649 // Field is never assigned to + public Array6 BdAddr; + public Array32 DeviceName; + public Array3 ClassOfDevice; + public Array16 LinkKey; + public bool LinkKeyPresent; + public ushort Version; + public uint TrustedServices; + public ushort Vid; + public ushort Pid; + public byte SubClass; + public byte AttributeMask; + public ushort DescriptorLength; + public Array128 Descriptor; + public byte KeyType; + public byte DeviceType; + public ushort BrrSize; + public Array9 Brr; + public Array256 Reserved; + public Array43 Reserved2; +#pragma warning restore CS0649 + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/ButtonConfigRegisteredSettings.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/ButtonConfigRegisteredSettings.cs new file mode 100644 index 000000000..8bd4924e9 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/ButtonConfigRegisteredSettings.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x5C8)] + struct ButtonConfigRegisteredSettings + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/ButtonConfigSettings.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/ButtonConfigSettings.cs new file mode 100644 index 000000000..2f06e32e1 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/ButtonConfigSettings.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x5A8)] + struct ButtonConfigSettings + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/ConsoleSixAxisSensorAccelerationBias.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/ConsoleSixAxisSensorAccelerationBias.cs new file mode 100644 index 000000000..c70d4ff28 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/ConsoleSixAxisSensorAccelerationBias.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0xC, Pack = 0x4)] + struct ConsoleSixAxisSensorAccelerationBias + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/ConsoleSixAxisSensorAccelerationGain.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/ConsoleSixAxisSensorAccelerationGain.cs new file mode 100644 index 000000000..0803beb87 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/ConsoleSixAxisSensorAccelerationGain.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x24, Pack = 0x4)] + struct ConsoleSixAxisSensorAccelerationGain + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/ConsoleSixAxisSensorAngularAcceleration.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/ConsoleSixAxisSensorAngularAcceleration.cs new file mode 100644 index 000000000..831e44bd5 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/ConsoleSixAxisSensorAngularAcceleration.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x24, Pack = 0x4)] + struct ConsoleSixAxisSensorAngularAcceleration + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/ConsoleSixAxisSensorAngularVelocityBias.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/ConsoleSixAxisSensorAngularVelocityBias.cs new file mode 100644 index 000000000..83d1faa8d --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/ConsoleSixAxisSensorAngularVelocityBias.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0xC, Pack = 0x4)] + struct ConsoleSixAxisSensorAngularVelocityBias + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/ConsoleSixAxisSensorAngularVelocityGain.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/ConsoleSixAxisSensorAngularVelocityGain.cs new file mode 100644 index 000000000..68e0c614a --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/ConsoleSixAxisSensorAngularVelocityGain.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x24, Pack = 0x4)] + struct ConsoleSixAxisSensorAngularVelocityGain + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/ConsoleSixAxisSensorAngularVelocityTimeBias.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/ConsoleSixAxisSensorAngularVelocityTimeBias.cs new file mode 100644 index 000000000..47f3d951c --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/ConsoleSixAxisSensorAngularVelocityTimeBias.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0xC, Pack = 0x4)] + struct ConsoleSixAxisSensorAngularVelocityTimeBias + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/DataDeletionSettings.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/DataDeletionSettings.cs new file mode 100644 index 000000000..a10a265d1 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/DataDeletionSettings.cs @@ -0,0 +1,18 @@ +using System; +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [Flags] + enum DataDeletionFlag : uint + { + AutomaticDeletionFlag = 1 << 0, + } + + [StructLayout(LayoutKind.Sequential, Size = 0x8, Pack = 0x4)] + struct DataDeletionSettings + { + public DataDeletionFlag Flags; + public uint UseCount; + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/DeviceNickName.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/DeviceNickName.cs new file mode 100644 index 000000000..99c9f9817 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/DeviceNickName.cs @@ -0,0 +1,25 @@ +using Ryujinx.Common.Memory; +using System.Runtime.InteropServices; +using System.Text; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x80)] + struct DeviceNickName + { + public Array128 Value; + + public DeviceNickName(string value) + { + int bytesWritten = Encoding.ASCII.GetBytes(value, Value.AsSpan()); + if (bytesWritten < 128) + { + Value[bytesWritten] = 0; + } + else + { + Value[127] = 0; + } + } + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/Edid.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/Edid.cs new file mode 100644 index 000000000..3ff566854 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/Edid.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x200)] + struct Edid + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/EulaVersion.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/EulaVersion.cs new file mode 100644 index 000000000..65905b1ba --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/EulaVersion.cs @@ -0,0 +1,6 @@ +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + struct EulaVersion + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/FatalDirtyFlag.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/FatalDirtyFlag.cs new file mode 100644 index 000000000..6be941151 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/FatalDirtyFlag.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x10, Pack = 0x8)] + struct FatalDirtyFlag + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/FirmwareVersion.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/FirmwareVersion.cs new file mode 100644 index 000000000..39825e010 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/FirmwareVersion.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x100)] + struct FirmwareVersion + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/FirmwareVersionDigest.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/FirmwareVersionDigest.cs new file mode 100644 index 000000000..0027d7ef1 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/FirmwareVersionDigest.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x40, Pack = 0x1)] + struct FirmwareVersionDigest + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/HomeMenuScheme.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/HomeMenuScheme.cs new file mode 100644 index 000000000..cc7b317be --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/HomeMenuScheme.cs @@ -0,0 +1,14 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x14, Pack = 0x1)] + struct HomeMenuScheme + { + public uint Main; + public uint Back; + public uint Sub; + public uint Bezel; + public uint Extra; + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/HostFsMountPoint.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/HostFsMountPoint.cs new file mode 100644 index 000000000..1a66abac9 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/HostFsMountPoint.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x100)] + struct HostFsMountPoint + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/InitialLaunchSettings.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/InitialLaunchSettings.cs new file mode 100644 index 000000000..b3989de75 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/InitialLaunchSettings.cs @@ -0,0 +1,14 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x20, Pack = 0x8)] + struct InitialLaunchSettings + { + public uint Flags; + public uint Reserved; + public ulong TimeStamp1; + public ulong TimeStamp2; + public ulong TimeStamp3; + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/NetworkSettings.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/NetworkSettings.cs new file mode 100644 index 000000000..a0101b626 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/NetworkSettings.cs @@ -0,0 +1,6 @@ +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + struct NetworkSettings + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/NotificationSettings.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/NotificationSettings.cs new file mode 100644 index 000000000..2ce56c4df --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/NotificationSettings.cs @@ -0,0 +1,38 @@ +using System; +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [Flags] + enum NotificationFlag : uint + { + RingtoneFlag = 1 << 0, + DownloadCompletionFlag = 1 << 1, + EnablesNews = 1 << 8, + IncomingLampFlag = 1 << 9, + } + + enum NotificationVolume : uint + { + Mute, + Low, + High, + } + + struct NotificationTime + { +#pragma warning disable CS0649 // Field is never assigned to + public uint Hour; + public uint Minute; +#pragma warning restore CS0649 + } + + [StructLayout(LayoutKind.Sequential, Size = 0x18, Pack = 0x4)] + struct NotificationSettings + { + public NotificationFlag Flag; + public NotificationVolume Volume; + public NotificationTime HeadTime; + public NotificationTime TailTime; + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/NxControllerLegacySettings.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/NxControllerLegacySettings.cs new file mode 100644 index 000000000..845715df2 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/NxControllerLegacySettings.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x29)] + struct NxControllerLegacySettings + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/NxControllerSettings.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/NxControllerSettings.cs new file mode 100644 index 000000000..c8f81cecb --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/NxControllerSettings.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x42C)] + struct NxControllerSettings + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/PtmFuelGaugeParameter.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/PtmFuelGaugeParameter.cs new file mode 100644 index 000000000..b843bcd64 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/PtmFuelGaugeParameter.cs @@ -0,0 +1,20 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x18, Pack = 0x4)] + struct PtmFuelGaugeParameter + { + public ushort Rcomp0; + public ushort TempCo; + public ushort FullCap; + public ushort FullCapNom; + public ushort IavgEmpty; + public ushort QrTable00; + public ushort QrTable10; + public ushort QrTable20; + public ushort QrTable30; + public ushort Reserved; + public uint Cycles; + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/RebootlessSystemUpdateVersion.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/RebootlessSystemUpdateVersion.cs new file mode 100644 index 000000000..b4e9b8b28 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/RebootlessSystemUpdateVersion.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x40, Pack = 0x4)] + struct RebootlessSystemUpdateVersion + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/SerialNumber.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/SerialNumber.cs new file mode 100644 index 000000000..22ddb85ce --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/SerialNumber.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x18, Pack = 0x1)] + struct SerialNumber + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/ServiceDiscoveryControlSettings.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/ServiceDiscoveryControlSettings.cs new file mode 100644 index 000000000..7c7b625a2 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/ServiceDiscoveryControlSettings.cs @@ -0,0 +1,10 @@ +using System; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [Flags] + enum ServiceDiscoveryControlSettings : uint + { + IsChangeEnvironmentIdentifierDisabled = 1 << 0, + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/SleepSettings.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/SleepSettings.cs new file mode 100644 index 000000000..7493c677c --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/SleepSettings.cs @@ -0,0 +1,40 @@ +using System; +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [Flags] + enum SleepFlag : uint + { + SleepsWhilePlayingMedia = 1 << 0, + WakesAtPowerStateChange = 1 << 1, + } + + enum HandheldSleepPlan : uint + { + At1Min, + At3Min, + At5Min, + At10Min, + At30Min, + Never, + } + + enum ConsoleSleepPlan : uint + { + At1Hour, + At2Hour, + At3Hour, + At6Hour, + At12Hour, + Never, + } + + [StructLayout(LayoutKind.Sequential, Size = 0xC, Pack = 0x4)] + struct SleepSettings + { + public SleepFlag Flags; + public HandheldSleepPlan HandheldSleepPlan; + public ConsoleSleepPlan ConsoleSleepPlan; + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/TelemetryDirtyFlag.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/TelemetryDirtyFlag.cs new file mode 100644 index 000000000..46ec2d767 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/TelemetryDirtyFlag.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x10, Pack = 0x8)] + struct TelemetryDirtyFlag + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/ThemeId.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/ThemeId.cs new file mode 100644 index 000000000..886ec8721 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/ThemeId.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x80, Pack = 0x8)] + struct ThemeId + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/ThemeSettings.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/ThemeSettings.cs new file mode 100644 index 000000000..ac36bcd80 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/ThemeSettings.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [StructLayout(LayoutKind.Sequential, Size = 0x8, Pack = 0x8)] + struct ThemeSettings + { + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Settings/System/TvSettings.cs b/src/Ryujinx.Horizon/Sdk/Settings/System/TvSettings.cs new file mode 100644 index 000000000..5ee0b85d9 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Settings/System/TvSettings.cs @@ -0,0 +1,59 @@ +using System; +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Settings.System +{ + [Flags] + enum TvFlag : uint + { + Allows4k = 1 << 0, + Allows3d = 1 << 1, + AllowsCec = 1 << 2, + PreventsScreenBurnIn = 1 << 3, + } + + enum TvResolution : uint + { + Auto, + At1080p, + At720p, + At480p, + } + + enum HdmiContentType : uint + { + None, + Graphics, + Cinema, + Photo, + Game, + } + + enum RgbRange : uint + { + Auto, + Full, + Limited, + } + + enum CmuMode : uint + { + None, + ColorInvert, + HighContrast, + GrayScale, + } + + [StructLayout(LayoutKind.Sequential, Size = 0x20, Pack = 0x4)] + struct TvSettings + { + public TvFlag Flags; + public TvResolution TvResolution; + public HdmiContentType HdmiContentType; + public RgbRange RgbRange; + public CmuMode CmuMode; + public float TvUnderscan; + public float TvGamma; + public float ContrastRatio; + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifDomainInHeader.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifDomainInHeader.cs index 882115013..cc1eb6cbb 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifDomainInHeader.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifDomainInHeader.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Sf.Cmif +namespace Ryujinx.Horizon.Sdk.Sf.Cmif { struct CmifDomainInHeader { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifDomainOutHeader.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifDomainOutHeader.cs index 89766a421..23c1ce248 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifDomainOutHeader.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifDomainOutHeader.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Sf.Cmif +namespace Ryujinx.Horizon.Sdk.Sf.Cmif { struct CmifDomainOutHeader { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifDomainRequestType.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifDomainRequestType.cs index 4e52ff936..0781d5890 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifDomainRequestType.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifDomainRequestType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Sf.Cmif +namespace Ryujinx.Horizon.Sdk.Sf.Cmif { enum CmifDomainRequestType : byte { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifInHeader.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifInHeader.cs index 55b859fca..12442dadd 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifInHeader.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifInHeader.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Sf.Cmif +namespace Ryujinx.Horizon.Sdk.Sf.Cmif { struct CmifInHeader { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifMessage.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifMessage.cs index f0b6f0c36..6b4c5cc52 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifMessage.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifMessage.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf.Hipc; using System; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifOutHeader.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifOutHeader.cs index ae32e78d6..ddceca030 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifOutHeader.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifOutHeader.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; namespace Ryujinx.Horizon.Sdk.Sf.Cmif { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifRequest.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifRequest.cs index 80772ad33..62c15baa6 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifRequest.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifRequest.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf.Hipc; +using Ryujinx.Horizon.Sdk.Sf.Hipc; using System; namespace Ryujinx.Horizon.Sdk.Sf.Cmif @@ -10,5 +10,12 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif public Span OutPointerSizes; public Span Objects; public int ServerPointerSize; + public int CurrentInPointerId; + public int SendBufferIndex; + public int RecvBufferIndex; + public int ExchBufferIndex; + public int SendStaticIndex; + public int RecvListIndex; + public int OutPointerSizeIndex; } } diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifRequestFormat.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifRequestFormat.cs index c32646e30..370341994 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifRequestFormat.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifRequestFormat.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Sf.Cmif +namespace Ryujinx.Horizon.Sdk.Sf.Cmif { struct CmifRequestFormat { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifResponse.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifResponse.cs index d1d8dc9c5..fbe90085f 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifResponse.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifResponse.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Horizon.Sdk.Sf.Cmif { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObject.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObject.cs index 148396876..e7d1ab6b2 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObject.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObject.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Sf.Cmif +namespace Ryujinx.Horizon.Sdk.Sf.Cmif { abstract partial class DomainServiceObject : ServerDomainBase, IServiceObject { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObjectDispatchTable.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObjectDispatchTable.cs index ccfacd908..58957a701 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObjectDispatchTable.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObjectDispatchTable.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObjectProcessor.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObjectProcessor.cs index 20ac5f101..f677e0598 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObjectProcessor.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObjectProcessor.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf.Hipc; using System; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/HandlesToClose.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/HandlesToClose.cs index 3c37e8b2e..b3c4aae0b 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/HandlesToClose.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/HandlesToClose.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Horizon.Sdk.Sf.Cmif { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServerDomainBase.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServerDomainBase.cs index f38fa0303..fc6350f76 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServerDomainBase.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServerDomainBase.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using System; namespace Ryujinx.Horizon.Sdk.Sf.Cmif diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServerDomainManager.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServerDomainManager.cs index f0222991d..7762345af 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServerDomainManager.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServerDomainManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServerMessageProcessor.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServerMessageProcessor.cs index e76502381..a682f716f 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServerMessageProcessor.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServerMessageProcessor.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf.Hipc; using System; diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServerMessageRuntimeMetadata.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServerMessageRuntimeMetadata.cs index 206676020..d79f852a3 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServerMessageRuntimeMetadata.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServerMessageRuntimeMetadata.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Sf.Cmif +namespace Ryujinx.Horizon.Sdk.Sf.Cmif { readonly struct ServerMessageRuntimeMetadata { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchContext.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchContext.cs index 3339a1a60..4ebe294b9 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchContext.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchContext.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf.Hipc; +using Ryujinx.Horizon.Sdk.Sf.Hipc; using System; namespace Ryujinx.Horizon.Sdk.Sf.Cmif diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchMeta.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchMeta.cs index 286e94148..008af90ae 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchMeta.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchMeta.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Sf.Cmif +namespace Ryujinx.Horizon.Sdk.Sf.Cmif { readonly struct ServiceDispatchMeta { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchTable.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchTable.cs index 145c17839..ef0372aa1 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchTable.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchTable.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchTableBase.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchTableBase.cs index a127bfcd5..2625a4c3e 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchTableBase.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchTableBase.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf.Hipc; using System; diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceObjectHolder.cs b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceObjectHolder.cs index 6e87e3405..4dd435377 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceObjectHolder.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceObjectHolder.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using System; namespace Ryujinx.Horizon.Sdk.Sf.Cmif diff --git a/src/Ryujinx.Horizon/Sdk/Sf/CmifCommandAttribute.cs b/src/Ryujinx.Horizon/Sdk/Sf/CmifCommandAttribute.cs index 51a7b5976..5af7d156f 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/CmifCommandAttribute.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/CmifCommandAttribute.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Horizon.Sdk.Sf { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/CommandArg.cs b/src/Ryujinx.Horizon/Sdk/Sf/CommandArg.cs index f6b54403f..48407a731 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/CommandArg.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/CommandArg.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf.Hipc; +using Ryujinx.Horizon.Sdk.Sf.Hipc; namespace Ryujinx.Horizon.Sdk.Sf { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/CommandArgAttributes.cs b/src/Ryujinx.Horizon/Sdk/Sf/CommandArgAttributes.cs index 5b7c302f2..f6f0e0682 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/CommandArgAttributes.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/CommandArgAttributes.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf.Hipc; +using Ryujinx.Horizon.Sdk.Sf.Hipc; using System; namespace Ryujinx.Horizon.Sdk.Sf diff --git a/src/Ryujinx.Horizon/Sdk/Sf/CommandHandler.cs b/src/Ryujinx.Horizon/Sdk/Sf/CommandHandler.cs index fb88eaaa0..d0efe0d4b 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/CommandHandler.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/CommandHandler.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf.Cmif; using System; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Horizon/Sdk/Sf/CommandSerialization.cs b/src/Ryujinx.Horizon/Sdk/Sf/CommandSerialization.cs index a14892a8d..038135ac8 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/CommandSerialization.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/CommandSerialization.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf.Cmif; +using Ryujinx.Horizon.Sdk.Sf.Cmif; using Ryujinx.Horizon.Sdk.Sf.Hipc; using Ryujinx.Memory; using System; diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/Api.cs b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/Api.cs index 530f81bd1..5f3f67061 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/Api.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/Api.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using System; namespace Ryujinx.Horizon.Sdk.Sf.Hipc diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcBufferDescriptor.cs b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcBufferDescriptor.cs index bef772e67..4e9628947 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcBufferDescriptor.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcBufferDescriptor.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Sf.Hipc +namespace Ryujinx.Horizon.Sdk.Sf.Hipc { readonly struct HipcBufferDescriptor { @@ -11,5 +11,12 @@ public ulong Address => _addressLow | (((ulong)_word2 << 4) & 0xf00000000UL) | (((ulong)_word2 << 34) & 0x7000000000UL); public ulong Size => _sizeLow | ((ulong)_word2 << 8) & 0xf00000000UL; public HipcBufferMode Mode => (HipcBufferMode)(_word2 & 3); + + public HipcBufferDescriptor(ulong address, ulong size, HipcBufferMode mode) + { + _sizeLow = (uint)size; + _addressLow = (uint)address; + _word2 = (uint)mode | ((uint)(address >> 34) & 0x1c) | ((uint)(size >> 32) << 24) | ((uint)(address >> 4) & 0xf0000000); + } } } diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcBufferFlags.cs b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcBufferFlags.cs index b1523d61d..b3995613c 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcBufferFlags.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcBufferFlags.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Horizon.Sdk.Sf.Hipc { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcBufferMode.cs b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcBufferMode.cs index bc2d5336c..ffd46c5e5 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcBufferMode.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcBufferMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Sf.Hipc +namespace Ryujinx.Horizon.Sdk.Sf.Hipc { enum HipcBufferMode { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcManager.cs b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcManager.cs index f72d8e81d..4f0bbb014 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcManager.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf.Cmif; using System; diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMessage.cs b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMessage.cs index 82cf6e75f..73321a891 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMessage.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMessage.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Horizon.Sdk.Sf.Cmif; using System; using System.Runtime.CompilerServices; @@ -181,6 +181,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc } Span dataWords = Span.Empty; + Span dataWordsPadded = Span.Empty; if (meta.DataWordsCount != 0) { @@ -189,6 +190,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc int padding = (dataOffsetAligned - dataOffset) / sizeof(uint); dataWords = MemoryMarshal.Cast(data)[padding..meta.DataWordsCount]; + dataWordsPadded = MemoryMarshal.Cast(data)[..meta.DataWordsCount]; data = data[(meta.DataWordsCount * sizeof(uint))..]; } @@ -209,6 +211,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc ReceiveBuffers = receiveBuffers, ExchangeBuffers = exchangeBuffers, DataWords = dataWords, + DataWordsPadded = dataWordsPadded, ReceiveList = receiveList, CopyHandles = copyHandles, MoveHandles = moveHandles, diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMessageData.cs b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMessageData.cs index c83c422ca..0d45d756f 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMessageData.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMessageData.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Horizon.Sdk.Sf.Hipc { @@ -9,6 +9,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc public Span ReceiveBuffers; public Span ExchangeBuffers; public Span DataWords; + public Span DataWordsPadded; public Span ReceiveList; public Span CopyHandles; public Span MoveHandles; diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMetadata.cs b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMetadata.cs index fe13137a6..add17ce1b 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMetadata.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMetadata.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Sf.Hipc +namespace Ryujinx.Horizon.Sdk.Sf.Hipc { struct HipcMetadata { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcReceiveListEntry.cs b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcReceiveListEntry.cs index 955428b84..9a7c23e9a 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcReceiveListEntry.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcReceiveListEntry.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Sf.Hipc +namespace Ryujinx.Horizon.Sdk.Sf.Hipc { readonly struct HipcReceiveListEntry { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcStaticDescriptor.cs b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcStaticDescriptor.cs index 43e7afb9d..3d11d0212 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcStaticDescriptor.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcStaticDescriptor.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Sf.Hipc +namespace Ryujinx.Horizon.Sdk.Sf.Hipc { readonly struct HipcStaticDescriptor { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ManagerOptions.cs b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ManagerOptions.cs index e747490e6..aa0135aa5 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ManagerOptions.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ManagerOptions.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Sf.Hipc +namespace Ryujinx.Horizon.Sdk.Sf.Hipc { readonly struct ManagerOptions { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ReceiveResult.cs b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ReceiveResult.cs index efe99f3f9..9e3a67a73 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ReceiveResult.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ReceiveResult.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sdk.Sf.Hipc +namespace Ryujinx.Horizon.Sdk.Sf.Hipc { enum ReceiveResult { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/Server.cs b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/Server.cs index 923f2d52d..935c34a87 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/Server.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/Server.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.OsTypes; +using Ryujinx.Horizon.Sdk.OsTypes; using Ryujinx.Horizon.Sdk.Sf.Cmif; using Ryujinx.Horizon.Sdk.Sm; diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerDomainSessionManager.cs b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerDomainSessionManager.cs index dda775397..daac6fc9c 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerDomainSessionManager.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerDomainSessionManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf.Cmif; using System; diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerManager.cs b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerManager.cs index 65a433038..e8957b758 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerManager.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.OsTypes; +using Ryujinx.Horizon.Sdk.OsTypes; using Ryujinx.Horizon.Sdk.Sf.Cmif; using Ryujinx.Horizon.Sdk.Sm; using System; diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerManagerBase.cs b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerManagerBase.cs index 764078408..9886e1cbf 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerManagerBase.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerManagerBase.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.OsTypes; using Ryujinx.Horizon.Sdk.Sf.Cmif; using Ryujinx.Horizon.Sdk.Sm; diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerSession.cs b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerSession.cs index eb98fefd0..66d5be197 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerSession.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerSession.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.OsTypes; +using Ryujinx.Horizon.Sdk.OsTypes; using Ryujinx.Horizon.Sdk.Sf.Cmif; namespace Ryujinx.Horizon.Sdk.Sf.Hipc diff --git a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/SpecialHeader.cs b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/SpecialHeader.cs index b6304b7b6..150159fba 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/Hipc/SpecialHeader.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/Hipc/SpecialHeader.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; namespace Ryujinx.Horizon.Sdk.Sf.Hipc { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/HipcCommandProcessor.cs b/src/Ryujinx.Horizon/Sdk/Sf/HipcCommandProcessor.cs index 08b1d89b9..f7694a74d 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/HipcCommandProcessor.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/HipcCommandProcessor.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf.Cmif; using Ryujinx.Horizon.Sdk.Sf.Hipc; @@ -206,7 +206,7 @@ namespace Ryujinx.Horizon.Sdk.Sf } else { - var data = MemoryMarshal.Cast(context.Request.Data.DataWords); + var data = MemoryMarshal.Cast(context.Request.Data.DataWordsPadded); var recvPointerSizes = MemoryMarshal.Cast(data[runtimeMetadata.UnfixedOutPointerSizeOffset..]); size = recvPointerSizes[unfixedRecvPointerIndex++]; diff --git a/src/Ryujinx.Horizon/Sdk/Sf/IServiceObject.cs b/src/Ryujinx.Horizon/Sdk/Sf/IServiceObject.cs index afa57fef9..f777f510a 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/IServiceObject.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/IServiceObject.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace Ryujinx.Horizon.Sdk.Sf { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/RawDataOffsetCalculator.cs b/src/Ryujinx.Horizon/Sdk/Sf/RawDataOffsetCalculator.cs index 0172c1151..573a50f26 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/RawDataOffsetCalculator.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/RawDataOffsetCalculator.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; namespace Ryujinx.Horizon.Sdk.Sf { diff --git a/src/Ryujinx.Horizon/Sdk/Sf/SfResult.cs b/src/Ryujinx.Horizon/Sdk/Sf/SfResult.cs index 029e17af0..32f160b2d 100644 --- a/src/Ryujinx.Horizon/Sdk/Sf/SfResult.cs +++ b/src/Ryujinx.Horizon/Sdk/Sf/SfResult.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; namespace Ryujinx.Horizon.Sdk.Sf { diff --git a/src/Ryujinx.Horizon/Sdk/Sm/IManagerService.cs b/src/Ryujinx.Horizon/Sdk/Sm/IManagerService.cs index 2343c7d6f..8d8578fe8 100644 --- a/src/Ryujinx.Horizon/Sdk/Sm/IManagerService.cs +++ b/src/Ryujinx.Horizon/Sdk/Sm/IManagerService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Sm { diff --git a/src/Ryujinx.Horizon/Sdk/Sm/IUserService.cs b/src/Ryujinx.Horizon/Sdk/Sm/IUserService.cs index 8605cdd1b..bc05c007f 100644 --- a/src/Ryujinx.Horizon/Sdk/Sm/IUserService.cs +++ b/src/Ryujinx.Horizon/Sdk/Sm/IUserService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Sm diff --git a/src/Ryujinx.Horizon/Sdk/Sm/ServiceName.cs b/src/Ryujinx.Horizon/Sdk/Sm/ServiceName.cs index 1233fad8a..b44106d63 100644 --- a/src/Ryujinx.Horizon/Sdk/Sm/ServiceName.cs +++ b/src/Ryujinx.Horizon/Sdk/Sm/ServiceName.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; using System.Text; diff --git a/src/Ryujinx.Horizon/Sdk/Sm/SmApi.cs b/src/Ryujinx.Horizon/Sdk/Sm/SmApi.cs index 1ab400bde..a63a03a5c 100644 --- a/src/Ryujinx.Horizon/Sdk/Sm/SmApi.cs +++ b/src/Ryujinx.Horizon/Sdk/Sm/SmApi.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf.Cmif; using System; diff --git a/src/Ryujinx.Horizon/Sdk/Srepo/ISrepoService.cs b/src/Ryujinx.Horizon/Sdk/Srepo/ISrepoService.cs index 9a1f4ba4f..35218b44e 100644 --- a/src/Ryujinx.Horizon/Sdk/Srepo/ISrepoService.cs +++ b/src/Ryujinx.Horizon/Sdk/Srepo/ISrepoService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Srepo { diff --git a/src/Ryujinx.Horizon/Sdk/Usb/IClientRootSession.cs b/src/Ryujinx.Horizon/Sdk/Usb/IClientRootSession.cs index 4975ad6b5..b69b94d99 100644 --- a/src/Ryujinx.Horizon/Sdk/Usb/IClientRootSession.cs +++ b/src/Ryujinx.Horizon/Sdk/Usb/IClientRootSession.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Usb { diff --git a/src/Ryujinx.Horizon/Sdk/Usb/IDsRootSession.cs b/src/Ryujinx.Horizon/Sdk/Usb/IDsRootSession.cs index 32d7aba6c..fb802a262 100644 --- a/src/Ryujinx.Horizon/Sdk/Usb/IDsRootSession.cs +++ b/src/Ryujinx.Horizon/Sdk/Usb/IDsRootSession.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Usb { diff --git a/src/Ryujinx.Horizon/Sdk/Usb/IPdCradleManager.cs b/src/Ryujinx.Horizon/Sdk/Usb/IPdCradleManager.cs index 0d3865114..125d2e8f2 100644 --- a/src/Ryujinx.Horizon/Sdk/Usb/IPdCradleManager.cs +++ b/src/Ryujinx.Horizon/Sdk/Usb/IPdCradleManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Usb { diff --git a/src/Ryujinx.Horizon/Sdk/Usb/IPdManager.cs b/src/Ryujinx.Horizon/Sdk/Usb/IPdManager.cs index d63821516..52953882e 100644 --- a/src/Ryujinx.Horizon/Sdk/Usb/IPdManager.cs +++ b/src/Ryujinx.Horizon/Sdk/Usb/IPdManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Usb { diff --git a/src/Ryujinx.Horizon/Sdk/Usb/IPdManufactureManager.cs b/src/Ryujinx.Horizon/Sdk/Usb/IPdManufactureManager.cs index 18bac3ea4..eba159c02 100644 --- a/src/Ryujinx.Horizon/Sdk/Usb/IPdManufactureManager.cs +++ b/src/Ryujinx.Horizon/Sdk/Usb/IPdManufactureManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Usb { diff --git a/src/Ryujinx.Horizon/Sdk/Usb/IPmObserverService.cs b/src/Ryujinx.Horizon/Sdk/Usb/IPmObserverService.cs index ef4cc65af..03b1c89be 100644 --- a/src/Ryujinx.Horizon/Sdk/Usb/IPmObserverService.cs +++ b/src/Ryujinx.Horizon/Sdk/Usb/IPmObserverService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Usb { diff --git a/src/Ryujinx.Horizon/Sdk/Usb/IPmService.cs b/src/Ryujinx.Horizon/Sdk/Usb/IPmService.cs index b8d177bd0..88510eae9 100644 --- a/src/Ryujinx.Horizon/Sdk/Usb/IPmService.cs +++ b/src/Ryujinx.Horizon/Sdk/Usb/IPmService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Usb { diff --git a/src/Ryujinx.Horizon/Sdk/Usb/IQdbManager.cs b/src/Ryujinx.Horizon/Sdk/Usb/IQdbManager.cs index a8f61f058..1615b020f 100644 --- a/src/Ryujinx.Horizon/Sdk/Usb/IQdbManager.cs +++ b/src/Ryujinx.Horizon/Sdk/Usb/IQdbManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Usb { diff --git a/src/Ryujinx.Horizon/Sdk/Wlan/IDetectManager.cs b/src/Ryujinx.Horizon/Sdk/Wlan/IDetectManager.cs index 2629ed6ef..a48af332f 100644 --- a/src/Ryujinx.Horizon/Sdk/Wlan/IDetectManager.cs +++ b/src/Ryujinx.Horizon/Sdk/Wlan/IDetectManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Wlan { diff --git a/src/Ryujinx.Horizon/Sdk/Wlan/IGeneralServiceCreator.cs b/src/Ryujinx.Horizon/Sdk/Wlan/IGeneralServiceCreator.cs index fa7704e79..7a2d15ea6 100644 --- a/src/Ryujinx.Horizon/Sdk/Wlan/IGeneralServiceCreator.cs +++ b/src/Ryujinx.Horizon/Sdk/Wlan/IGeneralServiceCreator.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Wlan { diff --git a/src/Ryujinx.Horizon/Sdk/Wlan/IInfraManager.cs b/src/Ryujinx.Horizon/Sdk/Wlan/IInfraManager.cs index 6739e1686..473c13a22 100644 --- a/src/Ryujinx.Horizon/Sdk/Wlan/IInfraManager.cs +++ b/src/Ryujinx.Horizon/Sdk/Wlan/IInfraManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Wlan { diff --git a/src/Ryujinx.Horizon/Sdk/Wlan/ILocalGetActionFrame.cs b/src/Ryujinx.Horizon/Sdk/Wlan/ILocalGetActionFrame.cs index 171ddba79..a6b6f475c 100644 --- a/src/Ryujinx.Horizon/Sdk/Wlan/ILocalGetActionFrame.cs +++ b/src/Ryujinx.Horizon/Sdk/Wlan/ILocalGetActionFrame.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Wlan { diff --git a/src/Ryujinx.Horizon/Sdk/Wlan/ILocalGetFrame.cs b/src/Ryujinx.Horizon/Sdk/Wlan/ILocalGetFrame.cs index 0a8d587ed..000a7f8ab 100644 --- a/src/Ryujinx.Horizon/Sdk/Wlan/ILocalGetFrame.cs +++ b/src/Ryujinx.Horizon/Sdk/Wlan/ILocalGetFrame.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Wlan { diff --git a/src/Ryujinx.Horizon/Sdk/Wlan/ILocalManager.cs b/src/Ryujinx.Horizon/Sdk/Wlan/ILocalManager.cs index cba9eb918..485a66a1b 100644 --- a/src/Ryujinx.Horizon/Sdk/Wlan/ILocalManager.cs +++ b/src/Ryujinx.Horizon/Sdk/Wlan/ILocalManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Wlan { diff --git a/src/Ryujinx.Horizon/Sdk/Wlan/IPrivateServiceCreator.cs b/src/Ryujinx.Horizon/Sdk/Wlan/IPrivateServiceCreator.cs index 5ab2e0eef..200d88625 100644 --- a/src/Ryujinx.Horizon/Sdk/Wlan/IPrivateServiceCreator.cs +++ b/src/Ryujinx.Horizon/Sdk/Wlan/IPrivateServiceCreator.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Wlan { diff --git a/src/Ryujinx.Horizon/Sdk/Wlan/ISfDriverServiceCreator.cs b/src/Ryujinx.Horizon/Sdk/Wlan/ISfDriverServiceCreator.cs index 78d32e6ae..5a19e208f 100644 --- a/src/Ryujinx.Horizon/Sdk/Wlan/ISfDriverServiceCreator.cs +++ b/src/Ryujinx.Horizon/Sdk/Wlan/ISfDriverServiceCreator.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Wlan { diff --git a/src/Ryujinx.Horizon/Sdk/Wlan/ISocketGetFrame.cs b/src/Ryujinx.Horizon/Sdk/Wlan/ISocketGetFrame.cs index c6d3e0b9a..0c9967c5c 100644 --- a/src/Ryujinx.Horizon/Sdk/Wlan/ISocketGetFrame.cs +++ b/src/Ryujinx.Horizon/Sdk/Wlan/ISocketGetFrame.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Wlan { diff --git a/src/Ryujinx.Horizon/Sdk/Wlan/ISocketManager.cs b/src/Ryujinx.Horizon/Sdk/Wlan/ISocketManager.cs index dcdfef48c..6df88b54f 100644 --- a/src/Ryujinx.Horizon/Sdk/Wlan/ISocketManager.cs +++ b/src/Ryujinx.Horizon/Sdk/Wlan/ISocketManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf; namespace Ryujinx.Horizon.Sdk.Wlan { diff --git a/src/Ryujinx.Horizon/ServiceTable.cs b/src/Ryujinx.Horizon/ServiceTable.cs index c79328a96..f3fe51940 100644 --- a/src/Ryujinx.Horizon/ServiceTable.cs +++ b/src/Ryujinx.Horizon/ServiceTable.cs @@ -1,4 +1,6 @@ +using Ryujinx.Horizon.Arp; using Ryujinx.Horizon.Bcat; +using Ryujinx.Horizon.Friends; using Ryujinx.Horizon.Hshl; using Ryujinx.Horizon.Ins; using Ryujinx.Horizon.Lbl; @@ -8,6 +10,7 @@ using Ryujinx.Horizon.Ngc; using Ryujinx.Horizon.Ovln; using Ryujinx.Horizon.Prepo; using Ryujinx.Horizon.Psc; +using Ryujinx.Horizon.Sdk.Arp; using Ryujinx.Horizon.Srepo; using Ryujinx.Horizon.Usb; using Ryujinx.Horizon.Wlan; @@ -23,6 +26,9 @@ namespace Ryujinx.Horizon private readonly ManualResetEvent _servicesReadyEvent = new(false); + public IReader ArpReader { get; internal set; } + public IWriter ArpWriter { get; internal set; } + public IEnumerable GetServices(HorizonOptions options) { List entries = new(); @@ -32,7 +38,9 @@ namespace Ryujinx.Horizon entries.Add(new ServiceEntry(T.Main, this, options)); } + RegisterService(); RegisterService(); + RegisterService(); RegisterService(); RegisterService(); RegisterService(); diff --git a/src/Ryujinx.Horizon/Sm/Impl/ServiceInfo.cs b/src/Ryujinx.Horizon/Sm/Impl/ServiceInfo.cs index fed420aa8..39ed57ceb 100644 --- a/src/Ryujinx.Horizon/Sm/Impl/ServiceInfo.cs +++ b/src/Ryujinx.Horizon/Sm/Impl/ServiceInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sm; +using Ryujinx.Horizon.Sdk.Sm; namespace Ryujinx.Horizon.Sm.Impl { diff --git a/src/Ryujinx.Horizon/Sm/Impl/ServiceManager.cs b/src/Ryujinx.Horizon/Sm/Impl/ServiceManager.cs index 929474aa7..177cc0d3d 100644 --- a/src/Ryujinx.Horizon/Sm/Impl/ServiceManager.cs +++ b/src/Ryujinx.Horizon/Sm/Impl/ServiceManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.OsTypes; using Ryujinx.Horizon.Sdk.Sf; using Ryujinx.Horizon.Sdk.Sm; diff --git a/src/Ryujinx.Horizon/Sm/Ipc/ManagerService.cs b/src/Ryujinx.Horizon/Sm/Ipc/ManagerService.cs index c7dcddc91..b9fb9cdad 100644 --- a/src/Ryujinx.Horizon/Sm/Ipc/ManagerService.cs +++ b/src/Ryujinx.Horizon/Sm/Ipc/ManagerService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sm; +using Ryujinx.Horizon.Sdk.Sm; namespace Ryujinx.Horizon.Sm.Ipc { diff --git a/src/Ryujinx.Horizon/Sm/Ipc/UserService.cs b/src/Ryujinx.Horizon/Sm/Ipc/UserService.cs index 868a15e6f..6223f9b51 100644 --- a/src/Ryujinx.Horizon/Sm/Ipc/UserService.cs +++ b/src/Ryujinx.Horizon/Sm/Ipc/UserService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf; using Ryujinx.Horizon.Sdk.Sm; using Ryujinx.Horizon.Sm.Impl; diff --git a/src/Ryujinx.Horizon/Sm/SmMain.cs b/src/Ryujinx.Horizon/Sm/SmMain.cs index 7303847ab..024d569f6 100644 --- a/src/Ryujinx.Horizon/Sm/SmMain.cs +++ b/src/Ryujinx.Horizon/Sm/SmMain.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf.Hipc; +using Ryujinx.Horizon.Sdk.Sf.Hipc; using Ryujinx.Horizon.Sdk.Sm; using Ryujinx.Horizon.Sm.Impl; using Ryujinx.Horizon.Sm.Types; diff --git a/src/Ryujinx.Horizon/Sm/SmResult.cs b/src/Ryujinx.Horizon/Sm/SmResult.cs index 75f47ca93..4cc423788 100644 --- a/src/Ryujinx.Horizon/Sm/SmResult.cs +++ b/src/Ryujinx.Horizon/Sm/SmResult.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; namespace Ryujinx.Horizon.Sm { diff --git a/src/Ryujinx.Horizon/Sm/SmServerManager.cs b/src/Ryujinx.Horizon/Sm/SmServerManager.cs index c04123455..4b1fa2567 100644 --- a/src/Ryujinx.Horizon/Sm/SmServerManager.cs +++ b/src/Ryujinx.Horizon/Sm/SmServerManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf.Hipc; using Ryujinx.Horizon.Sdk.Sm; using Ryujinx.Horizon.Sm.Impl; diff --git a/src/Ryujinx.Horizon/Sm/Types/SmPortIndex.cs b/src/Ryujinx.Horizon/Sm/Types/SmPortIndex.cs index a29778566..fd024bbbb 100644 --- a/src/Ryujinx.Horizon/Sm/Types/SmPortIndex.cs +++ b/src/Ryujinx.Horizon/Sm/Types/SmPortIndex.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Sm.Types +namespace Ryujinx.Horizon.Sm.Types { enum SmPortIndex { diff --git a/src/Ryujinx.Horizon/Srepo/Ipc/SrepoService.cs b/src/Ryujinx.Horizon/Srepo/Ipc/SrepoService.cs index 501eb5fed..df5ac0f0a 100644 --- a/src/Ryujinx.Horizon/Srepo/Ipc/SrepoService.cs +++ b/src/Ryujinx.Horizon/Srepo/Ipc/SrepoService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Srepo; +using Ryujinx.Horizon.Sdk.Srepo; namespace Ryujinx.Horizon.Srepo.Ipc { diff --git a/src/Ryujinx.Horizon/Srepo/SrepoIpcServer.cs b/src/Ryujinx.Horizon/Srepo/SrepoIpcServer.cs index a971f97b8..2060782cc 100644 --- a/src/Ryujinx.Horizon/Srepo/SrepoIpcServer.cs +++ b/src/Ryujinx.Horizon/Srepo/SrepoIpcServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf.Hipc; +using Ryujinx.Horizon.Sdk.Sf.Hipc; using Ryujinx.Horizon.Sdk.Sm; using Ryujinx.Horizon.Srepo.Ipc; diff --git a/src/Ryujinx.Horizon/Srepo/SrepoMain.cs b/src/Ryujinx.Horizon/Srepo/SrepoMain.cs index 78d813ac9..9c90b94a2 100644 --- a/src/Ryujinx.Horizon/Srepo/SrepoMain.cs +++ b/src/Ryujinx.Horizon/Srepo/SrepoMain.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Srepo +namespace Ryujinx.Horizon.Srepo { class SrepoMain : IService { diff --git a/src/Ryujinx.Horizon/Usb/Ipc/ClientRootSession.cs b/src/Ryujinx.Horizon/Usb/Ipc/ClientRootSession.cs index 2167ebcad..dec3f3f91 100644 --- a/src/Ryujinx.Horizon/Usb/Ipc/ClientRootSession.cs +++ b/src/Ryujinx.Horizon/Usb/Ipc/ClientRootSession.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Usb; +using Ryujinx.Horizon.Sdk.Usb; namespace Ryujinx.Horizon.Usb.Ipc { diff --git a/src/Ryujinx.Horizon/Usb/Ipc/DsRootSession.cs b/src/Ryujinx.Horizon/Usb/Ipc/DsRootSession.cs index 8a84537f8..1dd0d32b4 100644 --- a/src/Ryujinx.Horizon/Usb/Ipc/DsRootSession.cs +++ b/src/Ryujinx.Horizon/Usb/Ipc/DsRootSession.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Usb; +using Ryujinx.Horizon.Sdk.Usb; namespace Ryujinx.Horizon.Usb.Ipc { diff --git a/src/Ryujinx.Horizon/Usb/Ipc/PdCradleManager.cs b/src/Ryujinx.Horizon/Usb/Ipc/PdCradleManager.cs index 27e1c4e37..5c0efb667 100644 --- a/src/Ryujinx.Horizon/Usb/Ipc/PdCradleManager.cs +++ b/src/Ryujinx.Horizon/Usb/Ipc/PdCradleManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Usb; +using Ryujinx.Horizon.Sdk.Usb; namespace Ryujinx.Horizon.Usb.Ipc { diff --git a/src/Ryujinx.Horizon/Usb/Ipc/PdManager.cs b/src/Ryujinx.Horizon/Usb/Ipc/PdManager.cs index c501e3f20..1c502919b 100644 --- a/src/Ryujinx.Horizon/Usb/Ipc/PdManager.cs +++ b/src/Ryujinx.Horizon/Usb/Ipc/PdManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf.Hipc; +using Ryujinx.Horizon.Sdk.Sf.Hipc; using Ryujinx.Horizon.Sdk.Usb; namespace Ryujinx.Horizon.Usb.Ipc diff --git a/src/Ryujinx.Horizon/Usb/Ipc/PdManufactureManager.cs b/src/Ryujinx.Horizon/Usb/Ipc/PdManufactureManager.cs index 04f78b9c2..a909c861b 100644 --- a/src/Ryujinx.Horizon/Usb/Ipc/PdManufactureManager.cs +++ b/src/Ryujinx.Horizon/Usb/Ipc/PdManufactureManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Usb; +using Ryujinx.Horizon.Sdk.Usb; namespace Ryujinx.Horizon.Usb.Ipc { diff --git a/src/Ryujinx.Horizon/Usb/Ipc/PmObserverService.cs b/src/Ryujinx.Horizon/Usb/Ipc/PmObserverService.cs index e2edf4cb9..e1debf423 100644 --- a/src/Ryujinx.Horizon/Usb/Ipc/PmObserverService.cs +++ b/src/Ryujinx.Horizon/Usb/Ipc/PmObserverService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Usb; +using Ryujinx.Horizon.Sdk.Usb; namespace Ryujinx.Horizon.Usb.Ipc { diff --git a/src/Ryujinx.Horizon/Usb/Ipc/PmService.cs b/src/Ryujinx.Horizon/Usb/Ipc/PmService.cs index 625aaa497..8daa27c40 100644 --- a/src/Ryujinx.Horizon/Usb/Ipc/PmService.cs +++ b/src/Ryujinx.Horizon/Usb/Ipc/PmService.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Usb; +using Ryujinx.Horizon.Sdk.Usb; namespace Ryujinx.Horizon.Usb.Ipc { diff --git a/src/Ryujinx.Horizon/Usb/Ipc/QdbManager.cs b/src/Ryujinx.Horizon/Usb/Ipc/QdbManager.cs index 1421142fb..a458bef05 100644 --- a/src/Ryujinx.Horizon/Usb/Ipc/QdbManager.cs +++ b/src/Ryujinx.Horizon/Usb/Ipc/QdbManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Usb; +using Ryujinx.Horizon.Sdk.Usb; namespace Ryujinx.Horizon.Usb.Ipc { diff --git a/src/Ryujinx.Horizon/Usb/UsbIpcServer.cs b/src/Ryujinx.Horizon/Usb/UsbIpcServer.cs index a9158b507..38eeed496 100644 --- a/src/Ryujinx.Horizon/Usb/UsbIpcServer.cs +++ b/src/Ryujinx.Horizon/Usb/UsbIpcServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf.Hipc; +using Ryujinx.Horizon.Sdk.Sf.Hipc; using Ryujinx.Horizon.Sdk.Sm; using Ryujinx.Horizon.Usb.Ipc; diff --git a/src/Ryujinx.Horizon/Usb/UsbMain.cs b/src/Ryujinx.Horizon/Usb/UsbMain.cs index c54b39a65..a9c2e6807 100644 --- a/src/Ryujinx.Horizon/Usb/UsbMain.cs +++ b/src/Ryujinx.Horizon/Usb/UsbMain.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Usb +namespace Ryujinx.Horizon.Usb { class UsbMain : IService { diff --git a/src/Ryujinx.Horizon/Wlan/Ipc/DetectManager.cs b/src/Ryujinx.Horizon/Wlan/Ipc/DetectManager.cs index 595592f77..9158807bd 100644 --- a/src/Ryujinx.Horizon/Wlan/Ipc/DetectManager.cs +++ b/src/Ryujinx.Horizon/Wlan/Ipc/DetectManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Wlan; +using Ryujinx.Horizon.Sdk.Wlan; namespace Ryujinx.Horizon.Wlan.Ipc { diff --git a/src/Ryujinx.Horizon/Wlan/Ipc/GeneralServiceCreator.cs b/src/Ryujinx.Horizon/Wlan/Ipc/GeneralServiceCreator.cs index 7f651d227..ef5407d8f 100644 --- a/src/Ryujinx.Horizon/Wlan/Ipc/GeneralServiceCreator.cs +++ b/src/Ryujinx.Horizon/Wlan/Ipc/GeneralServiceCreator.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Wlan; +using Ryujinx.Horizon.Sdk.Wlan; namespace Ryujinx.Horizon.Wlan.Ipc { diff --git a/src/Ryujinx.Horizon/Wlan/Ipc/InfraManager.cs b/src/Ryujinx.Horizon/Wlan/Ipc/InfraManager.cs index d69c73b5c..7d3f0fac5 100644 --- a/src/Ryujinx.Horizon/Wlan/Ipc/InfraManager.cs +++ b/src/Ryujinx.Horizon/Wlan/Ipc/InfraManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Wlan; +using Ryujinx.Horizon.Sdk.Wlan; namespace Ryujinx.Horizon.Wlan.Ipc { diff --git a/src/Ryujinx.Horizon/Wlan/Ipc/LocalGetActionFrame.cs b/src/Ryujinx.Horizon/Wlan/Ipc/LocalGetActionFrame.cs index 8458655ed..4606f6e23 100644 --- a/src/Ryujinx.Horizon/Wlan/Ipc/LocalGetActionFrame.cs +++ b/src/Ryujinx.Horizon/Wlan/Ipc/LocalGetActionFrame.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Wlan; +using Ryujinx.Horizon.Sdk.Wlan; namespace Ryujinx.Horizon.Wlan.Ipc { diff --git a/src/Ryujinx.Horizon/Wlan/Ipc/LocalGetFrame.cs b/src/Ryujinx.Horizon/Wlan/Ipc/LocalGetFrame.cs index 5ce8724db..ff5bedb0e 100644 --- a/src/Ryujinx.Horizon/Wlan/Ipc/LocalGetFrame.cs +++ b/src/Ryujinx.Horizon/Wlan/Ipc/LocalGetFrame.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Wlan; +using Ryujinx.Horizon.Sdk.Wlan; namespace Ryujinx.Horizon.Wlan.Ipc { diff --git a/src/Ryujinx.Horizon/Wlan/Ipc/LocalManager.cs b/src/Ryujinx.Horizon/Wlan/Ipc/LocalManager.cs index 789ac1903..602423328 100644 --- a/src/Ryujinx.Horizon/Wlan/Ipc/LocalManager.cs +++ b/src/Ryujinx.Horizon/Wlan/Ipc/LocalManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Wlan; +using Ryujinx.Horizon.Sdk.Wlan; namespace Ryujinx.Horizon.Wlan.Ipc { diff --git a/src/Ryujinx.Horizon/Wlan/Ipc/PrivateServiceCreator.cs b/src/Ryujinx.Horizon/Wlan/Ipc/PrivateServiceCreator.cs index c25723f91..7045419d0 100644 --- a/src/Ryujinx.Horizon/Wlan/Ipc/PrivateServiceCreator.cs +++ b/src/Ryujinx.Horizon/Wlan/Ipc/PrivateServiceCreator.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Wlan; +using Ryujinx.Horizon.Sdk.Wlan; namespace Ryujinx.Horizon.Wlan.Ipc { diff --git a/src/Ryujinx.Horizon/Wlan/Ipc/SfDriverServiceCreator.cs b/src/Ryujinx.Horizon/Wlan/Ipc/SfDriverServiceCreator.cs index fd74024b6..212bfae13 100644 --- a/src/Ryujinx.Horizon/Wlan/Ipc/SfDriverServiceCreator.cs +++ b/src/Ryujinx.Horizon/Wlan/Ipc/SfDriverServiceCreator.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Wlan; +using Ryujinx.Horizon.Sdk.Wlan; namespace Ryujinx.Horizon.Wlan.Ipc { diff --git a/src/Ryujinx.Horizon/Wlan/Ipc/SocketGetFrame.cs b/src/Ryujinx.Horizon/Wlan/Ipc/SocketGetFrame.cs index 5c1663f68..4104980e2 100644 --- a/src/Ryujinx.Horizon/Wlan/Ipc/SocketGetFrame.cs +++ b/src/Ryujinx.Horizon/Wlan/Ipc/SocketGetFrame.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Wlan; +using Ryujinx.Horizon.Sdk.Wlan; namespace Ryujinx.Horizon.Wlan.Ipc { diff --git a/src/Ryujinx.Horizon/Wlan/Ipc/SocketManager.cs b/src/Ryujinx.Horizon/Wlan/Ipc/SocketManager.cs index a112e7452..947d2a1e5 100644 --- a/src/Ryujinx.Horizon/Wlan/Ipc/SocketManager.cs +++ b/src/Ryujinx.Horizon/Wlan/Ipc/SocketManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Wlan; +using Ryujinx.Horizon.Sdk.Wlan; namespace Ryujinx.Horizon.Wlan.Ipc { diff --git a/src/Ryujinx.Horizon/Wlan/WlanIpcServer.cs b/src/Ryujinx.Horizon/Wlan/WlanIpcServer.cs index eb13f028c..c7b336231 100644 --- a/src/Ryujinx.Horizon/Wlan/WlanIpcServer.cs +++ b/src/Ryujinx.Horizon/Wlan/WlanIpcServer.cs @@ -1,4 +1,4 @@ -using Ryujinx.Horizon.Sdk.Sf.Hipc; +using Ryujinx.Horizon.Sdk.Sf.Hipc; using Ryujinx.Horizon.Sdk.Sm; using Ryujinx.Horizon.Wlan.Ipc; diff --git a/src/Ryujinx.Horizon/Wlan/WlanMain.cs b/src/Ryujinx.Horizon/Wlan/WlanMain.cs index 1381a8cb0..6eef64a21 100644 --- a/src/Ryujinx.Horizon/Wlan/WlanMain.cs +++ b/src/Ryujinx.Horizon/Wlan/WlanMain.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Horizon.Wlan +namespace Ryujinx.Horizon.Wlan { class WlanMain : IService { diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index f04fdeb3c..187ca48dd 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Configuration.Hid; +using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid.Controller; using Ryujinx.Common.Logging; using System; diff --git a/src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs b/src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs index d0e793de4..c741493c1 100644 --- a/src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs +++ b/src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs @@ -1,4 +1,4 @@ -using Ryujinx.SDL2.Common; +using Ryujinx.SDL2.Common; using System; using System.Collections.Generic; using static SDL2.SDL; @@ -9,8 +9,18 @@ namespace Ryujinx.Input.SDL2 { private readonly Dictionary _gamepadsInstanceIdsMapping; private readonly List _gamepadsIds; + private readonly object _lock = new object(); - public ReadOnlySpan GamepadsIds => _gamepadsIds.ToArray(); + public ReadOnlySpan GamepadsIds + { + get + { + lock (_lock) + { + return _gamepadsIds.ToArray(); + } + } + } public string DriverName => "SDL2"; @@ -35,28 +45,39 @@ namespace Ryujinx.Input.SDL2 } } - private static string GenerateGamepadId(int joystickIndex) + private string GenerateGamepadId(int joystickIndex) { Guid guid = SDL_JoystickGetDeviceGUID(joystickIndex); + // Add a unique identifier to the start of the GUID in case of duplicates. + if (guid == Guid.Empty) { return null; } - return joystickIndex + "-" + guid; - } + string id; - private static int GetJoystickIndexByGamepadId(string id) - { - string[] data = id.Split("-"); - - if (data.Length != 6 || !int.TryParse(data[0], out int joystickIndex)) + lock (_lock) { - return -1; + int guidIndex = 0; + id = guidIndex + "-" + guid; + + while (_gamepadsIds.Contains(id)) + { + id = (++guidIndex) + "-" + guid; + } } - return joystickIndex; + return id; + } + + private int GetJoystickIndexByGamepadId(string id) + { + lock (_lock) + { + return _gamepadsIds.IndexOf(id); + } } private void HandleJoyStickDisconnected(int joystickInstanceId) @@ -64,7 +85,11 @@ namespace Ryujinx.Input.SDL2 if (_gamepadsInstanceIdsMapping.TryGetValue(joystickInstanceId, out string id)) { _gamepadsInstanceIdsMapping.Remove(joystickInstanceId); - _gamepadsIds.Remove(id); + + lock (_lock) + { + _gamepadsIds.Remove(id); + } OnGamepadDisconnected?.Invoke(id); } @@ -74,6 +99,13 @@ namespace Ryujinx.Input.SDL2 { if (SDL_IsGameController(joystickDeviceId) == SDL_bool.SDL_TRUE) { + if (_gamepadsInstanceIdsMapping.ContainsKey(joystickInstanceId)) + { + // Sometimes a JoyStick connected event fires after the app starts even though it was connected before + // so it is rejected to avoid doubling the entries. + return; + } + string id = GenerateGamepadId(joystickDeviceId); if (id == null) @@ -81,16 +113,12 @@ namespace Ryujinx.Input.SDL2 return; } - // Sometimes a JoyStick connected event fires after the app starts even though it was connected before - // so it is rejected to avoid doubling the entries. - if (_gamepadsIds.Contains(id)) - { - return; - } - if (_gamepadsInstanceIdsMapping.TryAdd(joystickInstanceId, id)) { - _gamepadsIds.Add(id); + lock (_lock) + { + _gamepadsIds.Add(id); + } OnGamepadConnected?.Invoke(id); } @@ -110,7 +138,10 @@ namespace Ryujinx.Input.SDL2 OnGamepadDisconnected?.Invoke(id); } - _gamepadsIds.Clear(); + lock (_lock) + { + _gamepadsIds.Clear(); + } SDL2Driver.Instance.Dispose(); } @@ -131,11 +162,6 @@ namespace Ryujinx.Input.SDL2 return null; } - if (id != GenerateGamepadId(joystickIndex)) - { - return null; - } - IntPtr gamepadHandle = SDL_GameControllerOpen(joystickIndex); if (gamepadHandle == IntPtr.Zero) diff --git a/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs b/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs index f46930a8e..bc0a7e660 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Configuration.Hid; +using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid.Keyboard; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.Input.SDL2/SDLKeyboardDriver.cs b/src/Ryujinx.Input.SDL2/SDLKeyboardDriver.cs index d0268adbb..965f7935a 100644 --- a/src/Ryujinx.Input.SDL2/SDLKeyboardDriver.cs +++ b/src/Ryujinx.Input.SDL2/SDLKeyboardDriver.cs @@ -1,4 +1,4 @@ -using Ryujinx.SDL2.Common; +using Ryujinx.SDL2.Common; using System; namespace Ryujinx.Input.SDL2 diff --git a/src/Ryujinx.Input/GamepadButtonInputId.cs b/src/Ryujinx.Input/GamepadButtonInputId.cs index 618f8d0a0..59baa22b4 100644 --- a/src/Ryujinx.Input/GamepadButtonInputId.cs +++ b/src/Ryujinx.Input/GamepadButtonInputId.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Input +namespace Ryujinx.Input { /// /// Represent a button from a gamepad. diff --git a/src/Ryujinx.Input/GamepadFeaturesFlag.cs b/src/Ryujinx.Input/GamepadFeaturesFlag.cs index 206b4ea11..69ec23686 100644 --- a/src/Ryujinx.Input/GamepadFeaturesFlag.cs +++ b/src/Ryujinx.Input/GamepadFeaturesFlag.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Input { diff --git a/src/Ryujinx.Input/GamepadStateSnapshot.cs b/src/Ryujinx.Input/GamepadStateSnapshot.cs index cf3e3e28d..3de08f574 100644 --- a/src/Ryujinx.Input/GamepadStateSnapshot.cs +++ b/src/Ryujinx.Input/GamepadStateSnapshot.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.CompilerServices; namespace Ryujinx.Input diff --git a/src/Ryujinx.Input/HLE/InputManager.cs b/src/Ryujinx.Input/HLE/InputManager.cs index 6dba839b9..7111f5502 100644 --- a/src/Ryujinx.Input/HLE/InputManager.cs +++ b/src/Ryujinx.Input/HLE/InputManager.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Input.HLE { diff --git a/src/Ryujinx.Input/HLE/NpadController.cs b/src/Ryujinx.Input/HLE/NpadController.cs index c193b45c2..f00db94e2 100644 --- a/src/Ryujinx.Input/HLE/NpadController.cs +++ b/src/Ryujinx.Input/HLE/NpadController.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid.Controller; using Ryujinx.Common.Configuration.Hid.Controller.Motion; diff --git a/src/Ryujinx.Input/HLE/NpadManager.cs b/src/Ryujinx.Input/HLE/NpadManager.cs index 25887748f..5ae73bda1 100644 --- a/src/Ryujinx.Input/HLE/NpadManager.cs +++ b/src/Ryujinx.Input/HLE/NpadManager.cs @@ -5,6 +5,7 @@ using Ryujinx.HLE.HOS.Services.Hid; using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using System.Runtime.CompilerServices; using CemuHookClient = Ryujinx.Input.Motion.CemuHook.Client; using ControllerType = Ryujinx.Common.Configuration.Hid.ControllerType; @@ -69,7 +70,20 @@ namespace Ryujinx.Input.HLE private void HandleOnGamepadDisconnected(string obj) { // Force input reload - ReloadConfiguration(_inputConfig, _enableKeyboard, _enableMouse); + lock (_lock) + { + // Forcibly disconnect any controllers with this ID. + for (int i = 0; i < _controllers.Length; i++) + { + if (_controllers[i]?.Id == obj) + { + _controllers[i]?.Dispose(); + _controllers[i] = null; + } + } + + ReloadConfiguration(_inputConfig, _enableKeyboard, _enableMouse); + } } private void HandleOnGamepadConnected(string id) @@ -106,31 +120,48 @@ namespace Ryujinx.Input.HLE { lock (_lock) { - for (int i = 0; i < _controllers.Length; i++) - { - _controllers[i]?.Dispose(); - _controllers[i] = null; - } + NpadController[] oldControllers = _controllers.ToArray(); List validInputs = new(); foreach (InputConfig inputConfigEntry in inputConfig) { - NpadController controller = new(_cemuHookClient); + NpadController controller; + int index = (int)inputConfigEntry.PlayerIndex; + + if (oldControllers[index] != null) + { + // Try reuse the existing controller. + controller = oldControllers[index]; + oldControllers[index] = null; + } + else + { + controller = new(_cemuHookClient); + } bool isValid = DriverConfigurationUpdate(ref controller, inputConfigEntry); if (!isValid) { + _controllers[index] = null; controller.Dispose(); } else { - _controllers[(int)inputConfigEntry.PlayerIndex] = controller; + _controllers[index] = controller; validInputs.Add(inputConfigEntry); } } + for (int i = 0; i < oldControllers.Length; i++) + { + // Disconnect any controllers that weren't reused by the new configuration. + + oldControllers[i]?.Dispose(); + oldControllers[i] = null; + } + _inputConfig = inputConfig; _enableKeyboard = enableKeyboard; _enableMouse = enableMouse; diff --git a/src/Ryujinx.Input/IGamepad.cs b/src/Ryujinx.Input/IGamepad.cs index c83ad5f82..3853f2819 100644 --- a/src/Ryujinx.Input/IGamepad.cs +++ b/src/Ryujinx.Input/IGamepad.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Configuration.Hid; +using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Memory; using System; using System.Numerics; diff --git a/src/Ryujinx.Input/IGamepadDriver.cs b/src/Ryujinx.Input/IGamepadDriver.cs index 792aef004..67b01c26c 100644 --- a/src/Ryujinx.Input/IGamepadDriver.cs +++ b/src/Ryujinx.Input/IGamepadDriver.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Input { diff --git a/src/Ryujinx.Input/IKeyboard.cs b/src/Ryujinx.Input/IKeyboard.cs index 506ec0995..2fc660112 100644 --- a/src/Ryujinx.Input/IKeyboard.cs +++ b/src/Ryujinx.Input/IKeyboard.cs @@ -1,4 +1,4 @@ -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; namespace Ryujinx.Input { diff --git a/src/Ryujinx.Input/Key.cs b/src/Ryujinx.Input/Key.cs index b4229e059..604022156 100644 --- a/src/Ryujinx.Input/Key.cs +++ b/src/Ryujinx.Input/Key.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Input +namespace Ryujinx.Input { /// /// Represent a key from a keyboard. diff --git a/src/Ryujinx.Input/KeyboardStateSnapshot.cs b/src/Ryujinx.Input/KeyboardStateSnapshot.cs index abf85666b..e0374a861 100644 --- a/src/Ryujinx.Input/KeyboardStateSnapshot.cs +++ b/src/Ryujinx.Input/KeyboardStateSnapshot.cs @@ -1,4 +1,4 @@ -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; namespace Ryujinx.Input { diff --git a/src/Ryujinx.Input/Motion/CemuHook/Client.cs b/src/Ryujinx.Input/Motion/CemuHook/Client.cs index b8b936c1e..e19f3d847 100644 --- a/src/Ryujinx.Input/Motion/CemuHook/Client.cs +++ b/src/Ryujinx.Input/Motion/CemuHook/Client.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid.Controller; using Ryujinx.Common.Configuration.Hid.Controller.Motion; diff --git a/src/Ryujinx.Input/Motion/CemuHook/Protocol/ControllerData.cs b/src/Ryujinx.Input/Motion/CemuHook/Protocol/ControllerData.cs index 4eee2e8e0..3a2282ad2 100644 --- a/src/Ryujinx.Input/Motion/CemuHook/Protocol/ControllerData.cs +++ b/src/Ryujinx.Input/Motion/CemuHook/Protocol/ControllerData.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.Input.Motion.CemuHook.Protocol diff --git a/src/Ryujinx.Input/Motion/CemuHook/Protocol/ControllerInfo.cs b/src/Ryujinx.Input/Motion/CemuHook/Protocol/ControllerInfo.cs index 3e51c2915..d19c99c57 100644 --- a/src/Ryujinx.Input/Motion/CemuHook/Protocol/ControllerInfo.cs +++ b/src/Ryujinx.Input/Motion/CemuHook/Protocol/ControllerInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.Input.Motion.CemuHook.Protocol diff --git a/src/Ryujinx.Input/Motion/CemuHook/Protocol/Header.cs b/src/Ryujinx.Input/Motion/CemuHook/Protocol/Header.cs index 142006d17..9faa189cd 100644 --- a/src/Ryujinx.Input/Motion/CemuHook/Protocol/Header.cs +++ b/src/Ryujinx.Input/Motion/CemuHook/Protocol/Header.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.Input.Motion.CemuHook.Protocol diff --git a/src/Ryujinx.Input/Motion/CemuHook/Protocol/MessageType.cs b/src/Ryujinx.Input/Motion/CemuHook/Protocol/MessageType.cs index 5ef15a7a3..5c4b04a2b 100644 --- a/src/Ryujinx.Input/Motion/CemuHook/Protocol/MessageType.cs +++ b/src/Ryujinx.Input/Motion/CemuHook/Protocol/MessageType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Input.Motion.CemuHook.Protocol +namespace Ryujinx.Input.Motion.CemuHook.Protocol { public enum MessageType : uint { diff --git a/src/Ryujinx.Input/Motion/CemuHook/Protocol/SharedResponse.cs b/src/Ryujinx.Input/Motion/CemuHook/Protocol/SharedResponse.cs index be37f53b6..3cb52bb81 100644 --- a/src/Ryujinx.Input/Motion/CemuHook/Protocol/SharedResponse.cs +++ b/src/Ryujinx.Input/Motion/CemuHook/Protocol/SharedResponse.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using Ryujinx.Common.Memory; using System.Runtime.InteropServices; namespace Ryujinx.Input.Motion.CemuHook.Protocol diff --git a/src/Ryujinx.Input/Motion/MotionInput.cs b/src/Ryujinx.Input/Motion/MotionInput.cs index 2c7af58f6..9d781c58a 100644 --- a/src/Ryujinx.Input/Motion/MotionInput.cs +++ b/src/Ryujinx.Input/Motion/MotionInput.cs @@ -1,4 +1,4 @@ -using Ryujinx.Input.Motion; +using Ryujinx.Input.Motion; using System; using System.Numerics; diff --git a/src/Ryujinx.Input/Motion/MotionSensorFilter.cs b/src/Ryujinx.Input/Motion/MotionSensorFilter.cs index 1a9749682..e51633c18 100644 --- a/src/Ryujinx.Input/Motion/MotionSensorFilter.cs +++ b/src/Ryujinx.Input/Motion/MotionSensorFilter.cs @@ -1,4 +1,4 @@ -using System.Numerics; +using System.Numerics; namespace Ryujinx.Input.Motion { diff --git a/src/Ryujinx.Input/MotionInputId.cs b/src/Ryujinx.Input/MotionInputId.cs index 61c7d305c..8aeb043a9 100644 --- a/src/Ryujinx.Input/MotionInputId.cs +++ b/src/Ryujinx.Input/MotionInputId.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Input +namespace Ryujinx.Input { /// /// Represent a motion sensor on a gamepad. diff --git a/src/Ryujinx.Input/StickInputId.cs b/src/Ryujinx.Input/StickInputId.cs index 94c0f25e8..fa2113ec5 100644 --- a/src/Ryujinx.Input/StickInputId.cs +++ b/src/Ryujinx.Input/StickInputId.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Input +namespace Ryujinx.Input { /// /// Represent a joystick from a gamepad. diff --git a/src/Ryujinx.Memory/AddressSpaceManager.cs b/src/Ryujinx.Memory/AddressSpaceManager.cs index b8d48365c..021d33663 100644 --- a/src/Ryujinx.Memory/AddressSpaceManager.cs +++ b/src/Ryujinx.Memory/AddressSpaceManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Memory.Range; +using Ryujinx.Memory.Range; using System; using System.Collections.Generic; using System.Linq; diff --git a/src/Ryujinx.Memory/IRefCounted.cs b/src/Ryujinx.Memory/IRefCounted.cs index e0a311d6d..697a16277 100644 --- a/src/Ryujinx.Memory/IRefCounted.cs +++ b/src/Ryujinx.Memory/IRefCounted.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Memory +namespace Ryujinx.Memory { public interface IRefCounted { diff --git a/src/Ryujinx.Memory/IVirtualMemoryManager.cs b/src/Ryujinx.Memory/IVirtualMemoryManager.cs index 8c9ca1684..9cf3663cf 100644 --- a/src/Ryujinx.Memory/IVirtualMemoryManager.cs +++ b/src/Ryujinx.Memory/IVirtualMemoryManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Memory.Range; +using Ryujinx.Memory.Range; using System; using System.Buffers; using System.Collections.Generic; diff --git a/src/Ryujinx.Memory/IWritableBlock.cs b/src/Ryujinx.Memory/IWritableBlock.cs index 36b9f5a6e..0858e0c96 100644 --- a/src/Ryujinx.Memory/IWritableBlock.cs +++ b/src/Ryujinx.Memory/IWritableBlock.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Memory { diff --git a/src/Ryujinx.Memory/InvalidAccessHandler.cs b/src/Ryujinx.Memory/InvalidAccessHandler.cs index 3dadb766d..963cee9d5 100644 --- a/src/Ryujinx.Memory/InvalidAccessHandler.cs +++ b/src/Ryujinx.Memory/InvalidAccessHandler.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Memory +namespace Ryujinx.Memory { /// /// Function that handles a invalid memory access from the emulated CPU. diff --git a/src/Ryujinx.Memory/InvalidMemoryRegionException.cs b/src/Ryujinx.Memory/InvalidMemoryRegionException.cs index 014824002..55503dd76 100644 --- a/src/Ryujinx.Memory/InvalidMemoryRegionException.cs +++ b/src/Ryujinx.Memory/InvalidMemoryRegionException.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Memory { diff --git a/src/Ryujinx.Memory/MemoryAllocationFlags.cs b/src/Ryujinx.Memory/MemoryAllocationFlags.cs index e5fa9360d..d8d1a83c4 100644 --- a/src/Ryujinx.Memory/MemoryAllocationFlags.cs +++ b/src/Ryujinx.Memory/MemoryAllocationFlags.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Memory { diff --git a/src/Ryujinx.Memory/MemoryBlock.cs b/src/Ryujinx.Memory/MemoryBlock.cs index 7d8d7cf05..7fe7862a9 100644 --- a/src/Ryujinx.Memory/MemoryBlock.cs +++ b/src/Ryujinx.Memory/MemoryBlock.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.CompilerServices; using System.Threading; diff --git a/src/Ryujinx.Memory/MemoryConstants.cs b/src/Ryujinx.Memory/MemoryConstants.cs index fc6f87e03..6cf9403bf 100644 --- a/src/Ryujinx.Memory/MemoryConstants.cs +++ b/src/Ryujinx.Memory/MemoryConstants.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Memory +namespace Ryujinx.Memory { static class MemoryConstants { diff --git a/src/Ryujinx.Memory/MemoryManagement.cs b/src/Ryujinx.Memory/MemoryManagement.cs index 3415ba40e..860d3f368 100644 --- a/src/Ryujinx.Memory/MemoryManagement.cs +++ b/src/Ryujinx.Memory/MemoryManagement.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Memory { diff --git a/src/Ryujinx.Memory/MemoryManagementUnix.cs b/src/Ryujinx.Memory/MemoryManagementUnix.cs index 9827b59be..e132dbbb8 100644 --- a/src/Ryujinx.Memory/MemoryManagementUnix.cs +++ b/src/Ryujinx.Memory/MemoryManagementUnix.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Concurrent; using System.Runtime.InteropServices; using System.Runtime.Versioning; diff --git a/src/Ryujinx.Memory/MemoryManagementWindows.cs b/src/Ryujinx.Memory/MemoryManagementWindows.cs index b5be5b3cf..742ef6c96 100644 --- a/src/Ryujinx.Memory/MemoryManagementWindows.cs +++ b/src/Ryujinx.Memory/MemoryManagementWindows.cs @@ -1,4 +1,4 @@ -using Ryujinx.Memory.WindowsShared; +using Ryujinx.Memory.WindowsShared; using System; using System.Runtime.InteropServices; using System.Runtime.Versioning; diff --git a/src/Ryujinx.Memory/MemoryManagerUnixHelper.cs b/src/Ryujinx.Memory/MemoryManagerUnixHelper.cs index 6f36a6d56..43888c85b 100644 --- a/src/Ryujinx.Memory/MemoryManagerUnixHelper.cs +++ b/src/Ryujinx.Memory/MemoryManagerUnixHelper.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; using System.Runtime.Versioning; diff --git a/src/Ryujinx.Memory/MemoryNotContiguousException.cs b/src/Ryujinx.Memory/MemoryNotContiguousException.cs index 3468adb99..b392ead85 100644 --- a/src/Ryujinx.Memory/MemoryNotContiguousException.cs +++ b/src/Ryujinx.Memory/MemoryNotContiguousException.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Memory { diff --git a/src/Ryujinx.Memory/MemoryPermission.cs b/src/Ryujinx.Memory/MemoryPermission.cs index 6e71d7b8c..fae9428af 100644 --- a/src/Ryujinx.Memory/MemoryPermission.cs +++ b/src/Ryujinx.Memory/MemoryPermission.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Memory { diff --git a/src/Ryujinx.Memory/MemoryProtectionException.cs b/src/Ryujinx.Memory/MemoryProtectionException.cs index e5606e99f..304ce8ed5 100644 --- a/src/Ryujinx.Memory/MemoryProtectionException.cs +++ b/src/Ryujinx.Memory/MemoryProtectionException.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; namespace Ryujinx.Memory diff --git a/src/Ryujinx.Memory/NativeMemoryManager.cs b/src/Ryujinx.Memory/NativeMemoryManager.cs index d17579354..fe718bda8 100644 --- a/src/Ryujinx.Memory/NativeMemoryManager.cs +++ b/src/Ryujinx.Memory/NativeMemoryManager.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Buffers; namespace Ryujinx.Memory diff --git a/src/Ryujinx.Memory/PageTable.cs b/src/Ryujinx.Memory/PageTable.cs index 8fdedd4f8..ff22d028e 100644 --- a/src/Ryujinx.Memory/PageTable.cs +++ b/src/Ryujinx.Memory/PageTable.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Memory +namespace Ryujinx.Memory { public class PageTable where T : unmanaged { diff --git a/src/Ryujinx.Memory/Range/IMultiRangeItem.cs b/src/Ryujinx.Memory/Range/IMultiRangeItem.cs index e95a69fc3..87fde2465 100644 --- a/src/Ryujinx.Memory/Range/IMultiRangeItem.cs +++ b/src/Ryujinx.Memory/Range/IMultiRangeItem.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Memory.Range +namespace Ryujinx.Memory.Range { public interface IMultiRangeItem { diff --git a/src/Ryujinx.Memory/Range/INonOverlappingRange.cs b/src/Ryujinx.Memory/Range/INonOverlappingRange.cs index 1886eb1d0..23194e0f2 100644 --- a/src/Ryujinx.Memory/Range/INonOverlappingRange.cs +++ b/src/Ryujinx.Memory/Range/INonOverlappingRange.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Memory.Range +namespace Ryujinx.Memory.Range { /// /// Range of memory that can be split in two. diff --git a/src/Ryujinx.Memory/Range/MemoryRange.cs b/src/Ryujinx.Memory/Range/MemoryRange.cs index 7e7b84b51..46aca9ba0 100644 --- a/src/Ryujinx.Memory/Range/MemoryRange.cs +++ b/src/Ryujinx.Memory/Range/MemoryRange.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Memory.Range +namespace Ryujinx.Memory.Range { /// /// Range of memory composed of an address and size. diff --git a/src/Ryujinx.Memory/Range/MultiRange.cs b/src/Ryujinx.Memory/Range/MultiRange.cs index 5a0b4178a..093e21903 100644 --- a/src/Ryujinx.Memory/Range/MultiRange.cs +++ b/src/Ryujinx.Memory/Range/MultiRange.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; namespace Ryujinx.Memory.Range @@ -15,6 +15,11 @@ namespace Ryujinx.Memory.Range private bool HasSingleRange => _ranges == null; + /// + /// Indicates that the range is fully unmapped. + /// + public bool IsUnmapped => HasSingleRange && _singleRange.Address == InvalidAddress; + /// /// Total of physical sub-ranges on the virtual memory region. /// @@ -38,8 +43,18 @@ namespace Ryujinx.Memory.Range /// is null public MultiRange(MemoryRange[] ranges) { - _singleRange = MemoryRange.Empty; - _ranges = ranges ?? throw new ArgumentNullException(nameof(ranges)); + ArgumentNullException.ThrowIfNull(ranges); + + if (ranges.Length == 1) + { + _singleRange = ranges[0]; + _ranges = null; + } + else + { + _singleRange = MemoryRange.Empty; + _ranges = ranges; + } } /// @@ -91,7 +106,7 @@ namespace Ryujinx.Memory.Range offset -= range.Size; } - return new MultiRange(ranges.ToArray()); + return ranges.Count == 1 ? new MultiRange(ranges[0].Address, ranges[0].Size) : new MultiRange(ranges.ToArray()); } } diff --git a/src/Ryujinx.Memory/Range/MultiRangeList.cs b/src/Ryujinx.Memory/Range/MultiRangeList.cs index 5131889fc..1804ff5c8 100644 --- a/src/Ryujinx.Memory/Range/MultiRangeList.cs +++ b/src/Ryujinx.Memory/Range/MultiRangeList.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Collections; +using Ryujinx.Common.Collections; using System.Collections; using System.Collections.Generic; diff --git a/src/Ryujinx.Memory/Range/NonOverlappingRangeList.cs b/src/Ryujinx.Memory/Range/NonOverlappingRangeList.cs index 60b2b3784..511589176 100644 --- a/src/Ryujinx.Memory/Range/NonOverlappingRangeList.cs +++ b/src/Ryujinx.Memory/Range/NonOverlappingRangeList.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; namespace Ryujinx.Memory.Range diff --git a/src/Ryujinx.Memory/Tracking/AbstractRegion.cs b/src/Ryujinx.Memory/Tracking/AbstractRegion.cs index bd4c8ab5c..7226fe954 100644 --- a/src/Ryujinx.Memory/Tracking/AbstractRegion.cs +++ b/src/Ryujinx.Memory/Tracking/AbstractRegion.cs @@ -1,4 +1,4 @@ -using Ryujinx.Memory.Range; +using Ryujinx.Memory.Range; namespace Ryujinx.Memory.Tracking { diff --git a/src/Ryujinx.Memory/Tracking/BitMap.cs b/src/Ryujinx.Memory/Tracking/BitMap.cs index 173952f3c..8f0086fc1 100644 --- a/src/Ryujinx.Memory/Tracking/BitMap.cs +++ b/src/Ryujinx.Memory/Tracking/BitMap.cs @@ -1,4 +1,4 @@ -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; namespace Ryujinx.Memory.Tracking { diff --git a/src/Ryujinx.Memory/Tracking/ConcurrentBitmap.cs b/src/Ryujinx.Memory/Tracking/ConcurrentBitmap.cs index 994fda921..b588b0a84 100644 --- a/src/Ryujinx.Memory/Tracking/ConcurrentBitmap.cs +++ b/src/Ryujinx.Memory/Tracking/ConcurrentBitmap.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading; namespace Ryujinx.Memory.Tracking diff --git a/src/Ryujinx.Memory/Tracking/IMultiRegionHandle.cs b/src/Ryujinx.Memory/Tracking/IMultiRegionHandle.cs index 71bd602fa..62b58344d 100644 --- a/src/Ryujinx.Memory/Tracking/IMultiRegionHandle.cs +++ b/src/Ryujinx.Memory/Tracking/IMultiRegionHandle.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Memory.Tracking { diff --git a/src/Ryujinx.Memory/Tracking/IRegionHandle.cs b/src/Ryujinx.Memory/Tracking/IRegionHandle.cs index 9d99d90e8..28bae8328 100644 --- a/src/Ryujinx.Memory/Tracking/IRegionHandle.cs +++ b/src/Ryujinx.Memory/Tracking/IRegionHandle.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Memory.Tracking { diff --git a/src/Ryujinx.Memory/Tracking/MemoryTracking.cs b/src/Ryujinx.Memory/Tracking/MemoryTracking.cs index ab9d98932..6febcbbb3 100644 --- a/src/Ryujinx.Memory/Tracking/MemoryTracking.cs +++ b/src/Ryujinx.Memory/Tracking/MemoryTracking.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Pools; +using Ryujinx.Common.Pools; using Ryujinx.Memory.Range; using System.Collections.Generic; diff --git a/src/Ryujinx.Memory/Tracking/MultiRegionHandle.cs b/src/Ryujinx.Memory/Tracking/MultiRegionHandle.cs index 5d3f20f4f..1c1b48b3c 100644 --- a/src/Ryujinx.Memory/Tracking/MultiRegionHandle.cs +++ b/src/Ryujinx.Memory/Tracking/MultiRegionHandle.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Numerics; diff --git a/src/Ryujinx.Memory/Tracking/PreciseRegionSignal.cs b/src/Ryujinx.Memory/Tracking/PreciseRegionSignal.cs index 038f95956..9828584a6 100644 --- a/src/Ryujinx.Memory/Tracking/PreciseRegionSignal.cs +++ b/src/Ryujinx.Memory/Tracking/PreciseRegionSignal.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Memory.Tracking +namespace Ryujinx.Memory.Tracking { public delegate bool PreciseRegionSignal(ulong address, ulong size, bool write); } diff --git a/src/Ryujinx.Memory/Tracking/RegionHandle.cs b/src/Ryujinx.Memory/Tracking/RegionHandle.cs index d36207cad..df3d9c311 100644 --- a/src/Ryujinx.Memory/Tracking/RegionHandle.cs +++ b/src/Ryujinx.Memory/Tracking/RegionHandle.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Threading; diff --git a/src/Ryujinx.Memory/Tracking/RegionSignal.cs b/src/Ryujinx.Memory/Tracking/RegionSignal.cs index c8a28d7d7..78c8687f0 100644 --- a/src/Ryujinx.Memory/Tracking/RegionSignal.cs +++ b/src/Ryujinx.Memory/Tracking/RegionSignal.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Memory.Tracking +namespace Ryujinx.Memory.Tracking { public delegate void RegionSignal(ulong address, ulong size); } diff --git a/src/Ryujinx.Memory/Tracking/SmartMultiRegionHandle.cs b/src/Ryujinx.Memory/Tracking/SmartMultiRegionHandle.cs index bab00377d..57129a182 100644 --- a/src/Ryujinx.Memory/Tracking/SmartMultiRegionHandle.cs +++ b/src/Ryujinx.Memory/Tracking/SmartMultiRegionHandle.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.CompilerServices; namespace Ryujinx.Memory.Tracking diff --git a/src/Ryujinx.Memory/Tracking/VirtualRegion.cs b/src/Ryujinx.Memory/Tracking/VirtualRegion.cs index e595196c7..538e94fef 100644 --- a/src/Ryujinx.Memory/Tracking/VirtualRegion.cs +++ b/src/Ryujinx.Memory/Tracking/VirtualRegion.cs @@ -1,4 +1,4 @@ -using Ryujinx.Memory.Range; +using Ryujinx.Memory.Range; using System.Collections.Generic; namespace Ryujinx.Memory.Tracking diff --git a/src/Ryujinx.Memory/WindowsShared/WindowsFlags.cs b/src/Ryujinx.Memory/WindowsShared/WindowsFlags.cs index 7dd4215ee..6effff743 100644 --- a/src/Ryujinx.Memory/WindowsShared/WindowsFlags.cs +++ b/src/Ryujinx.Memory/WindowsShared/WindowsFlags.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Memory.WindowsShared { diff --git a/src/Ryujinx.Memory/WritableRegion.cs b/src/Ryujinx.Memory/WritableRegion.cs index 21565ea5c..666c8a99b 100644 --- a/src/Ryujinx.Memory/WritableRegion.cs +++ b/src/Ryujinx.Memory/WritableRegion.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Memory { diff --git a/src/Ryujinx.SDL2.Common/SDL2Driver.cs b/src/Ryujinx.SDL2.Common/SDL2Driver.cs index 2642b26fa..552deafdd 100644 --- a/src/Ryujinx.SDL2.Common/SDL2Driver.cs +++ b/src/Ryujinx.SDL2.Common/SDL2Driver.cs @@ -1,4 +1,3 @@ -using Ryujinx.Common; using Ryujinx.Common.Logging; using System; using System.Collections.Concurrent; @@ -13,8 +12,6 @@ namespace Ryujinx.SDL2.Common { private static SDL2Driver _instance; - public static bool IsInitialized => _instance != null; - public static SDL2Driver Instance { get @@ -96,7 +93,7 @@ namespace Ryujinx.SDL2.Common SDL_EventState(SDL_EventType.SDL_CONTROLLERSENSORUPDATE, SDL_DISABLE); - string gamepadDbPath = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "SDL_GameControllerDB.txt"); + string gamepadDbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SDL_GameControllerDB.txt"); if (File.Exists(gamepadDbPath)) { diff --git a/src/Ryujinx.ShaderTools/Program.cs b/src/Ryujinx.ShaderTools/Program.cs index 4211ab491..04453912b 100644 --- a/src/Ryujinx.ShaderTools/Program.cs +++ b/src/Ryujinx.ShaderTools/Program.cs @@ -1,4 +1,4 @@ -using CommandLine; +using CommandLine; using Ryujinx.Graphics.Shader; using Ryujinx.Graphics.Shader.Translation; using System; diff --git a/src/Ryujinx.Tests.Memory/MockVirtualMemoryManager.cs b/src/Ryujinx.Tests.Memory/MockVirtualMemoryManager.cs index 435bb35ae..5c8396e6d 100644 --- a/src/Ryujinx.Tests.Memory/MockVirtualMemoryManager.cs +++ b/src/Ryujinx.Tests.Memory/MockVirtualMemoryManager.cs @@ -1,4 +1,4 @@ -using Ryujinx.Memory; +using Ryujinx.Memory; using Ryujinx.Memory.Range; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.Tests.Memory/MultiRegionTrackingTests.cs b/src/Ryujinx.Tests.Memory/MultiRegionTrackingTests.cs index 564ebd806..c71a3e1f0 100644 --- a/src/Ryujinx.Tests.Memory/MultiRegionTrackingTests.cs +++ b/src/Ryujinx.Tests.Memory/MultiRegionTrackingTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Memory; using Ryujinx.Memory.Tracking; using System; diff --git a/src/Ryujinx.Tests.Memory/TrackingTests.cs b/src/Ryujinx.Tests.Memory/TrackingTests.cs index 035f0c228..c74446cfb 100644 --- a/src/Ryujinx.Tests.Memory/TrackingTests.cs +++ b/src/Ryujinx.Tests.Memory/TrackingTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Memory; using Ryujinx.Memory.Tracking; using System; diff --git a/src/Ryujinx.Tests.Unicorn/UnicornAArch32.cs b/src/Ryujinx.Tests.Unicorn/UnicornAArch32.cs index 245487771..6fe62b741 100644 --- a/src/Ryujinx.Tests.Unicorn/UnicornAArch32.cs +++ b/src/Ryujinx.Tests.Unicorn/UnicornAArch32.cs @@ -1,4 +1,4 @@ -using System; +using System; using UnicornEngine.Const; namespace Ryujinx.Tests.Unicorn diff --git a/src/Ryujinx.Tests/Audio/Renderer/AudioRendererConfigurationTests.cs b/src/Ryujinx.Tests/Audio/Renderer/AudioRendererConfigurationTests.cs index 6467bdf3b..845b6493c 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/AudioRendererConfigurationTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/AudioRendererConfigurationTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/BehaviourParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/BehaviourParameterTests.cs index cf87e15c1..1d8c8964f 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/BehaviourParameterTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/BehaviourParameterTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Common; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/BiquadFilterParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/BiquadFilterParameterTests.cs index 0f6e38335..617b52457 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/BiquadFilterParameterTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/BiquadFilterParameterTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Common/UpdateDataHeaderTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Common/UpdateDataHeaderTests.cs index f6572e555..256679f73 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Common/UpdateDataHeaderTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Common/UpdateDataHeaderTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Common; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Common/VoiceUpdateStateTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Common/VoiceUpdateStateTests.cs index fe935cb60..7b09d18cc 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Common/VoiceUpdateStateTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Common/VoiceUpdateStateTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Common; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Common/WaveBufferTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Common/WaveBufferTests.cs index f7411e719..91f9c0561 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Common/WaveBufferTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Common/WaveBufferTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Common; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Dsp/ResamplerTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Dsp/ResamplerTests.cs index 0624f3401..f393c971a 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Dsp/ResamplerTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Dsp/ResamplerTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Dsp; using Ryujinx.Audio.Renderer.Parameter; using System; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Dsp/UpsamplerTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Dsp/UpsamplerTests.cs index 9b01b3ca6..3b1b94441 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Dsp/UpsamplerTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Dsp/UpsamplerTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Dsp; using Ryujinx.Audio.Renderer.Server.Upsampler; using System; diff --git a/src/Ryujinx.Tests/Audio/Renderer/EffectInfoParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/EffectInfoParameterTests.cs index c4ac82f07..ee28423be 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/EffectInfoParameterTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/EffectInfoParameterTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/EffectOutStatusTests.cs b/src/Ryujinx.Tests/Audio/Renderer/EffectOutStatusTests.cs index 8cb57da37..2a4449437 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/EffectOutStatusTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/EffectOutStatusTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/MemoryPoolParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/MemoryPoolParameterTests.cs index 2850fd35b..733629a95 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/MemoryPoolParameterTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/MemoryPoolParameterTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/BehaviourErrorInfoOutStatusTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/BehaviourErrorInfoOutStatusTests.cs index 7323e7205..a21729561 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/BehaviourErrorInfoOutStatusTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/BehaviourErrorInfoOutStatusTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/AuxParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/AuxParameterTests.cs index 101bd3481..75b24c40a 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/AuxParameterTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/AuxParameterTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter.Effect; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameterTests.cs index 6cb7d93a6..73c1ea9d3 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameterTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameterTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter.Effect; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/BufferMixerParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/BufferMixerParameterTests.cs index 49ff509ca..7a86e3736 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/BufferMixerParameterTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/BufferMixerParameterTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter.Effect; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/CompressorParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/CompressorParameterTests.cs index 016338dc7..de7733ae4 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/CompressorParameterTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/CompressorParameterTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter.Effect; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/DelayParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/DelayParameterTests.cs index b11e3f473..3daaf9a16 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/DelayParameterTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/DelayParameterTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter.Effect; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/LimiterParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/LimiterParameterTests.cs index e176cc62f..b74999567 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/LimiterParameterTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/LimiterParameterTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter.Effect; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/LimiterStatisticsTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/LimiterStatisticsTests.cs index 13ad34ebd..9b3bfb13f 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/LimiterStatisticsTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/LimiterStatisticsTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter.Effect; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/Reverb3dParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/Reverb3dParameterTests.cs index 694ed55d6..a5d562fbe 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/Reverb3dParameterTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/Reverb3dParameterTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter.Effect; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/ReverbParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/ReverbParameterTests.cs index ef9f3457d..6cc103f82 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/ReverbParameterTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/ReverbParameterTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter.Effect; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/MixInParameterDirtyOnlyUpdateTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/MixInParameterDirtyOnlyUpdateTests.cs index 03184fdf5..148e8a5db 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/MixInParameterDirtyOnlyUpdateTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/MixInParameterDirtyOnlyUpdateTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/MixParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/MixParameterTests.cs index 4fb2bb770..d9c0e1c73 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/MixParameterTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/MixParameterTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/PerformanceInParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/PerformanceInParameterTests.cs index a81fa1460..685b9ed5f 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/PerformanceInParameterTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/PerformanceInParameterTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter.Performance; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/PerformanceOutStatusTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/PerformanceOutStatusTests.cs index e61dea2e5..eb39fe48d 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/PerformanceOutStatusTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/PerformanceOutStatusTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter.Performance; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/RendererInfoOutStatusTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/RendererInfoOutStatusTests.cs index 6b60db29e..34f049656 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/RendererInfoOutStatusTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/RendererInfoOutStatusTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Sink/CircularBufferParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Sink/CircularBufferParameterTests.cs index 8bc37c1c1..f5113fd06 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Sink/CircularBufferParameterTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Sink/CircularBufferParameterTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter.Sink; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Sink/DeviceParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Sink/DeviceParameterTests.cs index 27ae2b473..e7677c822 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Sink/DeviceParameterTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Sink/DeviceParameterTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter.Sink; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/SinkInParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/SinkInParameterTests.cs index 21a178890..84f9cd9a1 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/SinkInParameterTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/SinkInParameterTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/SinkOutStatusTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/SinkOutStatusTests.cs index 828248afe..18c501d22 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/SinkOutStatusTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/SinkOutStatusTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/SplitterInParamHeaderTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/SplitterInParamHeaderTests.cs index fc966e4c8..f7a2965f5 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/SplitterInParamHeaderTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/SplitterInParamHeaderTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/AddressInfoTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/AddressInfoTests.cs index 7c6b65267..53a662584 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Server/AddressInfoTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Server/AddressInfoTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Server.MemoryPool; using System; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/MemoryPoolStateTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/MemoryPoolStateTests.cs index 94dc69066..c6a2e473e 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Server/MemoryPoolStateTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Server/MemoryPoolStateTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Server.MemoryPool; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/MixStateTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/MixStateTests.cs index d1ddf64d1..6262913b4 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Server/MixStateTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Server/MixStateTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Server.Mix; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/PoolMapperTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/PoolMapperTests.cs index 4c931d9ee..d7879d627 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Server/PoolMapperTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Server/PoolMapperTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio; using Ryujinx.Audio.Renderer.Server.MemoryPool; using System; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/SplitterDestinationTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/SplitterDestinationTests.cs index 513629546..ad974aab1 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Server/SplitterDestinationTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Server/SplitterDestinationTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Server.Splitter; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/SplitterStateTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/SplitterStateTests.cs index 2486f8c0b..0421bd9d1 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Server/SplitterStateTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Server/SplitterStateTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Server.Splitter; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/VoiceChannelResourceTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/VoiceChannelResourceTests.cs index 0b8672862..565ac7a69 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Server/VoiceChannelResourceTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Server/VoiceChannelResourceTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Server.Voice; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/VoiceStateTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/VoiceStateTests.cs index ddd05bc4f..dbd6eff8f 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Server/VoiceStateTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Server/VoiceStateTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Server.Voice; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/WaveBufferTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/WaveBufferTests.cs index 9f3889c08..0e2ed0e85 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Server/WaveBufferTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Server/WaveBufferTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Server.Voice; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/VoiceChannelResourceInParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/VoiceChannelResourceInParameterTests.cs index b04f505e5..2bcfd32c3 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/VoiceChannelResourceInParameterTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/VoiceChannelResourceInParameterTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/VoiceInParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/VoiceInParameterTests.cs index 9770189cb..239da195a 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/VoiceInParameterTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/VoiceInParameterTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Audio/Renderer/VoiceOutStatusTests.cs b/src/Ryujinx.Tests/Audio/Renderer/VoiceOutStatusTests.cs index abef0646b..1579d89b5 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/VoiceOutStatusTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/VoiceOutStatusTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Audio.Renderer.Parameter; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/Cpu/CpuTest.cs b/src/Ryujinx.Tests/Cpu/CpuTest.cs index 35158c0b4..da0f03e6b 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTest.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTest.cs @@ -61,7 +61,6 @@ namespace Ryujinx.Tests.Cpu _memory.Map(DataBaseAddress, Size, Size, MemoryMapFlags.Private); _context = CpuContext.CreateExecutionContext(); - Translator.IsReadyForTranslation.Set(); _cpuContext = new CpuContext(_memory, for64Bit: true); diff --git a/src/Ryujinx.Tests/Cpu/CpuTest32.cs b/src/Ryujinx.Tests/Cpu/CpuTest32.cs index 05a4d3bee..6a690834f 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTest32.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTest32.cs @@ -1,4 +1,4 @@ -using ARMeilleure; +using ARMeilleure; using ARMeilleure.State; using ARMeilleure.Translation; using NUnit.Framework; @@ -56,7 +56,6 @@ namespace Ryujinx.Tests.Cpu _context = CpuContext.CreateExecutionContext(); _context.IsAarch32 = true; - Translator.IsReadyForTranslation.Set(); _cpuContext = new CpuContext(_memory, for64Bit: false); diff --git a/src/Ryujinx.Tests/Cpu/CpuTestAlu32.cs b/src/Ryujinx.Tests/Cpu/CpuTestAlu32.cs index 404dfd7de..41365c624 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestAlu32.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestAlu32.cs @@ -1,4 +1,4 @@ -#define Alu32 +#define Alu32 using NUnit.Framework; diff --git a/src/Ryujinx.Tests/Cpu/CpuTestAluBinary32.cs b/src/Ryujinx.Tests/Cpu/CpuTestAluBinary32.cs index 4e355358a..43d054368 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestAluBinary32.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestAluBinary32.cs @@ -1,4 +1,4 @@ -#define AluBinary32 +#define AluBinary32 using ARMeilleure.State; using NUnit.Framework; diff --git a/src/Ryujinx.Tests/Cpu/CpuTestAluRs32.cs b/src/Ryujinx.Tests/Cpu/CpuTestAluRs32.cs index f8fb013d5..0e71b1839 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestAluRs32.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestAluRs32.cs @@ -1,4 +1,4 @@ -#define AluRs32 +#define AluRs32 using NUnit.Framework; diff --git a/src/Ryujinx.Tests/Cpu/CpuTestBf32.cs b/src/Ryujinx.Tests/Cpu/CpuTestBf32.cs index 5afefd62c..197171b8d 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestBf32.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestBf32.cs @@ -1,4 +1,4 @@ -#define Bf32 +#define Bf32 using NUnit.Framework; using System; diff --git a/src/Ryujinx.Tests/Cpu/CpuTestMul32.cs b/src/Ryujinx.Tests/Cpu/CpuTestMul32.cs index 58da762dd..7e4b4c062 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestMul32.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestMul32.cs @@ -1,4 +1,4 @@ -#define Mul32 +#define Mul32 using NUnit.Framework; diff --git a/src/Ryujinx.Tests/Cpu/CpuTestSimdCrypto32.cs b/src/Ryujinx.Tests/Cpu/CpuTestSimdCrypto32.cs index c82b17978..60076da47 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestSimdCrypto32.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestSimdCrypto32.cs @@ -1,4 +1,4 @@ -// https://www.intel.com/content/dam/doc/white-paper/advanced-encryption-standard-new-instructions-set-paper.pdf +// https://www.intel.com/content/dam/doc/white-paper/advanced-encryption-standard-new-instructions-set-paper.pdf using ARMeilleure.State; using NUnit.Framework; diff --git a/src/Ryujinx.Tests/Cpu/CpuTestSimdCvt32.cs b/src/Ryujinx.Tests/Cpu/CpuTestSimdCvt32.cs index 5b24432bb..ba201a480 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestSimdCvt32.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestSimdCvt32.cs @@ -511,6 +511,45 @@ namespace Ryujinx.Tests.Cpu CompareAgainstUnicorn(); } + + [Test, Pairwise, Description("VRINTR.F , ")] + [Platform(Exclude = "Linux,MacOsX")] // Instruction isn't testable due to Unicorn. + public void Vrintr([Values(0u, 1u)] uint rd, + [Values(0u, 1u)] uint rm, + [Values(2u, 3u)] uint size, + [ValueSource(nameof(_1D_F_))] ulong s0, + [ValueSource(nameof(_1D_F_))] ulong s1, + [ValueSource(nameof(_1D_F_))] ulong s2, + [Values(RMode.Rn, RMode.Rm, RMode.Rp)] RMode rMode) + { + uint opcode = 0xEEB60A40; + + V128 v0, v1, v2; + + if (size == 2) + { + opcode |= ((rm & 0x1e) >> 1) | ((rm & 0x1) << 5); + opcode |= ((rd & 0x1e) << 11) | ((rd & 0x1) << 22); + v0 = MakeVectorE0E1((uint)BitConverter.SingleToInt32Bits(s0), (uint)BitConverter.SingleToInt32Bits(s0)); + v1 = MakeVectorE0E1((uint)BitConverter.SingleToInt32Bits(s1), (uint)BitConverter.SingleToInt32Bits(s0)); + v2 = MakeVectorE0E1((uint)BitConverter.SingleToInt32Bits(s2), (uint)BitConverter.SingleToInt32Bits(s1)); + } + else + { + opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1); + opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18); + v0 = MakeVectorE0E1((uint)BitConverter.DoubleToInt64Bits(s0), (uint)BitConverter.DoubleToInt64Bits(s0)); + v1 = MakeVectorE0E1((uint)BitConverter.DoubleToInt64Bits(s1), (uint)BitConverter.DoubleToInt64Bits(s0)); + v2 = MakeVectorE0E1((uint)BitConverter.DoubleToInt64Bits(s2), (uint)BitConverter.DoubleToInt64Bits(s1)); + } + + opcode |= ((size & 3) << 8); + + int fpscr = (int)rMode << (int)Fpcr.RMode; + SingleOpcode(opcode, v0: v0, v1: v1, v2: v2, fpscr: fpscr); + + CompareAgainstUnicorn(); + } #endif } } diff --git a/src/Ryujinx.Tests/Cpu/CpuTestSimdLogical32.cs b/src/Ryujinx.Tests/Cpu/CpuTestSimdLogical32.cs index 65cac9dee..819d9300b 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestSimdLogical32.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestSimdLogical32.cs @@ -1,4 +1,4 @@ -#define SimdLogical32 +#define SimdLogical32 using ARMeilleure.State; using NUnit.Framework; diff --git a/src/Ryujinx.Tests/Cpu/CpuTestSimdMemory32.cs b/src/Ryujinx.Tests/Cpu/CpuTestSimdMemory32.cs index 28f00d58e..d59e963b5 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestSimdMemory32.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestSimdMemory32.cs @@ -1,4 +1,4 @@ -#define SimdMemory32 +#define SimdMemory32 using ARMeilleure.State; using NUnit.Framework; diff --git a/src/Ryujinx.Tests/Cpu/CpuTestSimdMov32.cs b/src/Ryujinx.Tests/Cpu/CpuTestSimdMov32.cs index 0566df20f..85f77fff1 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestSimdMov32.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestSimdMov32.cs @@ -1,4 +1,4 @@ -#define SimdMov32 +#define SimdMov32 using ARMeilleure.State; using NUnit.Framework; diff --git a/src/Ryujinx.Tests/Cpu/CpuTestSimdReg32.cs b/src/Ryujinx.Tests/Cpu/CpuTestSimdReg32.cs index 1db90bfa4..38e08bf89 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestSimdReg32.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestSimdReg32.cs @@ -1,4 +1,4 @@ -#define SimdReg32 +#define SimdReg32 using ARMeilleure.State; using NUnit.Framework; @@ -908,6 +908,44 @@ namespace Ryujinx.Tests.Cpu CompareAgainstUnicorn(); } + + [Test, Pairwise] + public void Vp_Add_Long_Accumulate([Values(0u, 2u, 4u, 8u)] uint rd, + [Values(0u, 2u, 4u, 8u)] uint rm, + [Values(0u, 1u, 2u)] uint size, + [Random(RndCnt)] ulong z, + [Random(RndCnt)] ulong a, + [Random(RndCnt)] ulong b, + [Values] bool q, + [Values] bool unsigned) + { + uint opcode = 0xF3B00600; // VPADAL.S8 D0, Q0 + + if (q) + { + opcode |= 1 << 6; + rm <<= 1; + rd <<= 1; + } + + if (unsigned) + { + opcode |= 1 << 7; + } + + opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1); + opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18); + + opcode |= size << 18; + + V128 v0 = MakeVectorE0E1(z, z); + V128 v1 = MakeVectorE0E1(a, z); + V128 v2 = MakeVectorE0E1(b, z); + + SingleOpcode(opcode, v0: v0, v1: v1, v2: v2); + + CompareAgainstUnicorn(); + } #endif } } diff --git a/src/Ryujinx.Tests/Cpu/CpuTestSimdRegElem32.cs b/src/Ryujinx.Tests/Cpu/CpuTestSimdRegElem32.cs index cf960dfdf..49aab0513 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestSimdRegElem32.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestSimdRegElem32.cs @@ -1,4 +1,4 @@ -#define SimdRegElem32 +#define SimdRegElem32 using ARMeilleure.State; using NUnit.Framework; diff --git a/src/Ryujinx.Tests/Cpu/CpuTestSimdShImm.cs b/src/Ryujinx.Tests/Cpu/CpuTestSimdShImm.cs index fbac54c8c..9816bc2cc 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestSimdShImm.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestSimdShImm.cs @@ -311,6 +311,46 @@ namespace Ryujinx.Tests.Cpu }; } + private static uint[] _ShlImm_S_D_() + { + return new[] + { + 0x5F407400u, // SQSHL D0, D0, #0 + }; + } + + private static uint[] _ShlImm_V_8B_16B_() + { + return new[] + { + 0x0F087400u, // SQSHL V0.8B, V0.8B, #0 + }; + } + + private static uint[] _ShlImm_V_4H_8H_() + { + return new[] + { + 0x0F107400u, // SQSHL V0.4H, V0.4H, #0 + }; + } + + private static uint[] _ShlImm_V_2S_4S_() + { + return new[] + { + 0x0F207400u, // SQSHL V0.2S, V0.2S, #0 + }; + } + + private static uint[] _ShlImm_V_2D_() + { + return new[] + { + 0x4F407400u, // SQSHL V0.2D, V0.2D, #0 + }; + } + private static uint[] _ShrImm_Sri_S_D_() { return new[] @@ -813,6 +853,117 @@ namespace Ryujinx.Tests.Cpu CompareAgainstUnicorn(); } + [Test, Pairwise] + public void ShlImm_S_D([ValueSource(nameof(_ShlImm_S_D_))] uint opcodes, + [Values(0u)] uint rd, + [Values(1u, 0u)] uint rn, + [ValueSource(nameof(_1D_))] ulong z, + [ValueSource(nameof(_1D_))] ulong a, + [Values(1u, 64u)] uint shift) + { + uint immHb = (64 + shift) & 0x7F; + + opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0); + opcodes |= (immHb << 16); + + V128 v0 = MakeVectorE0E1(z, z); + V128 v1 = MakeVectorE0(a); + + SingleOpcode(opcodes, v0: v0, v1: v1); + + CompareAgainstUnicorn(); + } + + [Test, Pairwise] + public void ShlImm_V_8B_16B([ValueSource(nameof(_ShlImm_V_8B_16B_))] uint opcodes, + [Values(0u)] uint rd, + [Values(1u, 0u)] uint rn, + [ValueSource(nameof(_8B_))] ulong z, + [ValueSource(nameof(_8B_))] ulong a, + [Values(1u, 8u)] uint shift, + [Values(0b0u, 0b1u)] uint q) // <8B, 16B> + { + uint immHb = (8 + shift) & 0x7F; + + opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0); + opcodes |= (immHb << 16); + opcodes |= ((q & 1) << 30); + + V128 v0 = MakeVectorE0E1(z, z); + V128 v1 = MakeVectorE0E1(a, a * q); + + SingleOpcode(opcodes, v0: v0, v1: v1); + + CompareAgainstUnicorn(); + } + + [Test, Pairwise] + public void ShlImm_V_4H_8H([ValueSource(nameof(_ShlImm_V_4H_8H_))] uint opcodes, + [Values(0u)] uint rd, + [Values(1u, 0u)] uint rn, + [ValueSource(nameof(_4H_))] ulong z, + [ValueSource(nameof(_4H_))] ulong a, + [Values(1u, 16u)] uint shift, + [Values(0b0u, 0b1u)] uint q) // <4H, 8H> + { + uint immHb = (16 + shift) & 0x7F; + + opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0); + opcodes |= (immHb << 16); + opcodes |= ((q & 1) << 30); + + V128 v0 = MakeVectorE0E1(z, z); + V128 v1 = MakeVectorE0E1(a, a * q); + + SingleOpcode(opcodes, v0: v0, v1: v1); + + CompareAgainstUnicorn(); + } + + [Test, Pairwise] + public void ShlImm_V_2S_4S([ValueSource(nameof(_ShlImm_V_2S_4S_))] uint opcodes, + [Values(0u)] uint rd, + [Values(1u, 0u)] uint rn, + [ValueSource(nameof(_2S_))] ulong z, + [ValueSource(nameof(_2S_))] ulong a, + [Values(1u, 32u)] uint shift, + [Values(0b0u, 0b1u)] uint q) // <2S, 4S> + { + uint immHb = (32 + shift) & 0x7F; + + opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0); + opcodes |= (immHb << 16); + opcodes |= (((q | (immHb >> 6)) & 1) << 30); + + V128 v0 = MakeVectorE0E1(z, z); + V128 v1 = MakeVectorE0E1(a, a * q); + + SingleOpcode(opcodes, v0: v0, v1: v1); + + CompareAgainstUnicorn(); + } + + [Test, Pairwise] + public void ShlImm_V_2D([ValueSource(nameof(_ShlImm_V_2D_))] uint opcodes, + [Values(0u)] uint rd, + [Values(1u, 0u)] uint rn, + [ValueSource(nameof(_1D_))] ulong z, + [ValueSource(nameof(_1D_))] ulong a, + [Values(1u, 64u)] uint shift) + { + uint immHb = (64 + shift) & 0x7F; + + opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0); + opcodes |= (immHb << 16); + + V128 v0 = MakeVectorE0E1(z, z); + V128 v1 = MakeVectorE0E1(a, a); + + SingleOpcode(opcodes, v0: v0, v1: v1); + + CompareAgainstUnicorn(); + } + [Test, Pairwise] public void ShrImm_Sri_S_D([ValueSource(nameof(_ShrImm_Sri_S_D_))] uint opcodes, [Values(0u)] uint rd, diff --git a/src/Ryujinx.Tests/Cpu/CpuTestSimdShImm32.cs b/src/Ryujinx.Tests/Cpu/CpuTestSimdShImm32.cs index f81d22c21..39b50867f 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestSimdShImm32.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestSimdShImm32.cs @@ -1,4 +1,4 @@ -#define SimdShImm32 +#define SimdShImm32 using ARMeilleure.State; using NUnit.Framework; diff --git a/src/Ryujinx.Tests/Cpu/CpuTestT32Alu.cs b/src/Ryujinx.Tests/Cpu/CpuTestT32Alu.cs index 8046d581b..a0d46692c 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestT32Alu.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestT32Alu.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; namespace Ryujinx.Tests.Cpu { diff --git a/src/Ryujinx.Tests/Cpu/CpuTestT32Flow.cs b/src/Ryujinx.Tests/Cpu/CpuTestT32Flow.cs index f3832a8c3..01159afc6 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestT32Flow.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestT32Flow.cs @@ -1,4 +1,4 @@ -using ARMeilleure.State; +using ARMeilleure.State; using NUnit.Framework; namespace Ryujinx.Tests.Cpu diff --git a/src/Ryujinx.Tests/Cpu/CpuTestT32Mem.cs b/src/Ryujinx.Tests/Cpu/CpuTestT32Mem.cs index ca47d8e36..94ccb950c 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestT32Mem.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestT32Mem.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using System; namespace Ryujinx.Tests.Cpu diff --git a/src/Ryujinx.Tests/Cpu/CpuTestThumb.cs b/src/Ryujinx.Tests/Cpu/CpuTestThumb.cs index 625ce2d82..6111e53fa 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestThumb.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestThumb.cs @@ -1,4 +1,4 @@ -using ARMeilleure.State; +using ARMeilleure.State; using NUnit.Framework; namespace Ryujinx.Tests.Cpu diff --git a/src/Ryujinx.Tests/Cpu/EnvironmentTests.cs b/src/Ryujinx.Tests/Cpu/EnvironmentTests.cs index 5e6b286bd..2a4775a31 100644 --- a/src/Ryujinx.Tests/Cpu/EnvironmentTests.cs +++ b/src/Ryujinx.Tests/Cpu/EnvironmentTests.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Translation; +using ARMeilleure.Translation; using NUnit.Framework; using Ryujinx.Cpu.Jit; using Ryujinx.Tests.Memory; diff --git a/src/Ryujinx.Tests/Cpu/PrecomputedThumbTestCase.cs b/src/Ryujinx.Tests/Cpu/PrecomputedThumbTestCase.cs index e699f8bbf..28d739fcd 100644 --- a/src/Ryujinx.Tests/Cpu/PrecomputedThumbTestCase.cs +++ b/src/Ryujinx.Tests/Cpu/PrecomputedThumbTestCase.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Tests.Cpu +namespace Ryujinx.Tests.Cpu { public class PrecomputedThumbTestCase { diff --git a/src/Ryujinx.Tests/HLE/SoftwareKeyboardTests.cs b/src/Ryujinx.Tests/HLE/SoftwareKeyboardTests.cs index b5bcc213f..79ca2d480 100644 --- a/src/Ryujinx.Tests/HLE/SoftwareKeyboardTests.cs +++ b/src/Ryujinx.Tests/HLE/SoftwareKeyboardTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.HLE.HOS.Applets; using System.Text; diff --git a/src/Ryujinx.Tests/Memory/MockMemoryManager.cs b/src/Ryujinx.Tests/Memory/MockMemoryManager.cs index 8a902db41..20c318de6 100644 --- a/src/Ryujinx.Tests/Memory/MockMemoryManager.cs +++ b/src/Ryujinx.Tests/Memory/MockMemoryManager.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Memory; +using ARMeilleure.Memory; using System; namespace Ryujinx.Tests.Memory diff --git a/src/Ryujinx.Tests/Memory/PartialUnmaps.cs b/src/Ryujinx.Tests/Memory/PartialUnmaps.cs index 296f74917..04f7f40e6 100644 --- a/src/Ryujinx.Tests/Memory/PartialUnmaps.cs +++ b/src/Ryujinx.Tests/Memory/PartialUnmaps.cs @@ -1,4 +1,4 @@ -using ARMeilleure.Signal; +using ARMeilleure.Signal; using ARMeilleure.Translation; using NUnit.Framework; using Ryujinx.Common.Memory.PartialUnmaps; diff --git a/src/Ryujinx.Tests/Time/TimeZoneRuleTests.cs b/src/Ryujinx.Tests/Time/TimeZoneRuleTests.cs index 4d5c4eaa3..8448309ee 100644 --- a/src/Ryujinx.Tests/Time/TimeZoneRuleTests.cs +++ b/src/Ryujinx.Tests/Time/TimeZoneRuleTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.HLE.HOS.Services.Time.TimeZone; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx.Tests/TreeDictionaryTests.cs b/src/Ryujinx.Tests/TreeDictionaryTests.cs index f1a8ee73d..ea9fb0731 100644 --- a/src/Ryujinx.Tests/TreeDictionaryTests.cs +++ b/src/Ryujinx.Tests/TreeDictionaryTests.cs @@ -1,4 +1,4 @@ -using NUnit.Framework; +using NUnit.Framework; using Ryujinx.Common.Collections; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.Ui.Common/App/ApplicationAddedEventArgs.cs b/src/Ryujinx.Ui.Common/App/ApplicationAddedEventArgs.cs index 78eed7afd..01e20276e 100644 --- a/src/Ryujinx.Ui.Common/App/ApplicationAddedEventArgs.cs +++ b/src/Ryujinx.Ui.Common/App/ApplicationAddedEventArgs.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Ui.App.Common { diff --git a/src/Ryujinx.Ui.Common/App/ApplicationCountUpdatedEventArgs.cs b/src/Ryujinx.Ui.Common/App/ApplicationCountUpdatedEventArgs.cs index 6a8e465e0..ca54ddf7a 100644 --- a/src/Ryujinx.Ui.Common/App/ApplicationCountUpdatedEventArgs.cs +++ b/src/Ryujinx.Ui.Common/App/ApplicationCountUpdatedEventArgs.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Ui.App.Common { diff --git a/src/Ryujinx.Ui.Common/App/ApplicationData.cs b/src/Ryujinx.Ui.Common/App/ApplicationData.cs index 65ab01eeb..bd844805b 100644 --- a/src/Ryujinx.Ui.Common/App/ApplicationData.cs +++ b/src/Ryujinx.Ui.Common/App/ApplicationData.cs @@ -1,4 +1,4 @@ -using LibHac.Common; +using LibHac.Common; using LibHac.Fs; using LibHac.Fs.Fsa; using LibHac.FsSystem; diff --git a/src/Ryujinx.Ui.Common/App/ApplicationJsonSerializerContext.cs b/src/Ryujinx.Ui.Common/App/ApplicationJsonSerializerContext.cs index 76eea33ca..9a7b3eddf 100644 --- a/src/Ryujinx.Ui.Common/App/ApplicationJsonSerializerContext.cs +++ b/src/Ryujinx.Ui.Common/App/ApplicationJsonSerializerContext.cs @@ -1,4 +1,4 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace Ryujinx.Ui.App.Common { diff --git a/src/Ryujinx.Ui.Common/App/ApplicationLibrary.cs b/src/Ryujinx.Ui.Common/App/ApplicationLibrary.cs index 46f29851c..3b35ff270 100644 --- a/src/Ryujinx.Ui.Common/App/ApplicationLibrary.cs +++ b/src/Ryujinx.Ui.Common/App/ApplicationLibrary.cs @@ -8,6 +8,7 @@ using LibHac.Ns; using LibHac.Tools.Fs; using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem.NcaUtils; +using Ryujinx.Common; using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Common.Utilities; @@ -105,7 +106,7 @@ namespace Ryujinx.Ui.App.Common if (!Directory.Exists(appDir)) { - Logger.Warning?.Print(LogClass.Application, $"The \"game_dirs\" section in \"Config.json\" contains an invalid directory: \"{appDir}\""); + Logger.Warning?.Print(LogClass.Application, $"The \"game_dirs\" section in \"{ReleaseInformation.ConfigName}\" contains an invalid directory: \"{appDir}\""); continue; } @@ -136,6 +137,13 @@ namespace Ryujinx.Ui.App.Common if (!fileInfo.Attributes.HasFlag(FileAttributes.Hidden) && extension is ".nsp" or ".pfs0" or ".xci" or ".nca" or ".nro" or ".nso") { var fullPath = fileInfo.ResolveLinkTarget(true)?.FullName ?? fileInfo.FullName; + + if (!File.Exists(fullPath)) + { + Logger.Warning?.Print(LogClass.Application, $"Skipping invalid symlink: {fileInfo.FullName}"); + continue; + } + applications.Add(fullPath); numApplicationsFound++; } diff --git a/src/Ryujinx.Ui.Common/App/ApplicationMetadata.cs b/src/Ryujinx.Ui.Common/App/ApplicationMetadata.cs index 9e2ca6870..43647feef 100644 --- a/src/Ryujinx.Ui.Common/App/ApplicationMetadata.cs +++ b/src/Ryujinx.Ui.Common/App/ApplicationMetadata.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text.Json.Serialization; namespace Ryujinx.Ui.App.Common diff --git a/src/Ryujinx.Ui.Common/Configuration/AudioBackend.cs b/src/Ryujinx.Ui.Common/Configuration/AudioBackend.cs index 1147a0a6b..dc0a5ac61 100644 --- a/src/Ryujinx.Ui.Common/Configuration/AudioBackend.cs +++ b/src/Ryujinx.Ui.Common/Configuration/AudioBackend.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System.Text.Json.Serialization; namespace Ryujinx.Ui.Common.Configuration diff --git a/src/Ryujinx.Ui.Common/Configuration/ConfigurationFileFormatSettings.cs b/src/Ryujinx.Ui.Common/Configuration/ConfigurationFileFormatSettings.cs index a1727df51..9a1841fc5 100644 --- a/src/Ryujinx.Ui.Common/Configuration/ConfigurationFileFormatSettings.cs +++ b/src/Ryujinx.Ui.Common/Configuration/ConfigurationFileFormatSettings.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; namespace Ryujinx.Ui.Common.Configuration { diff --git a/src/Ryujinx.Ui.Common/Configuration/ConfigurationJsonSerializerContext.cs b/src/Ryujinx.Ui.Common/Configuration/ConfigurationJsonSerializerContext.cs index 2aa7e5366..03989edec 100644 --- a/src/Ryujinx.Ui.Common/Configuration/ConfigurationJsonSerializerContext.cs +++ b/src/Ryujinx.Ui.Common/Configuration/ConfigurationJsonSerializerContext.cs @@ -1,4 +1,4 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace Ryujinx.Ui.Common.Configuration { diff --git a/src/Ryujinx.Ui.Common/Configuration/FileTypes.cs b/src/Ryujinx.Ui.Common/Configuration/FileTypes.cs index 0b8b7384b..9d2f63864 100644 --- a/src/Ryujinx.Ui.Common/Configuration/FileTypes.cs +++ b/src/Ryujinx.Ui.Common/Configuration/FileTypes.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Ui.Common +namespace Ryujinx.Ui.Common { public enum FileTypes { diff --git a/src/Ryujinx.Ui.Common/Configuration/LoggerModule.cs b/src/Ryujinx.Ui.Common/Configuration/LoggerModule.cs index e18b2bfa3..f22ee83ae 100644 --- a/src/Ryujinx.Ui.Common/Configuration/LoggerModule.cs +++ b/src/Ryujinx.Ui.Common/Configuration/LoggerModule.cs @@ -1,12 +1,16 @@ -using Ryujinx.Common; +using Ryujinx.Common; +using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Common.Logging.Targets; using System; +using System.IO; namespace Ryujinx.Ui.Common.Configuration { public static class LoggerModule { + public static string LogDirectoryPath { get; private set; } + public static void Initialize() { ConfigurationState.Instance.Logger.EnableDebug.Event += ReloadEnableDebug; @@ -80,8 +84,28 @@ namespace Ryujinx.Ui.Common.Configuration { if (e.NewValue) { + string logDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs"); + FileStream logFile = FileLogTarget.PrepareLogFile(logDir); + + if (logFile == null) + { + logDir = Path.Combine(AppDataManager.BaseDirPath, "Logs"); + logFile = FileLogTarget.PrepareLogFile(logDir); + + if (logFile == null) + { + Logger.Error?.Print(LogClass.Application, "No writable log directory available. Make sure either the application directory or the Ryujinx directory is writable."); + LogDirectoryPath = null; + Logger.RemoveTarget("file"); + + return; + } + } + + LogDirectoryPath = logDir; + Logger.AddTarget(new AsyncLogTargetWrapper( - new FileLogTarget(ReleaseInformation.GetBaseApplicationDirectory(), "file"), + new FileLogTarget("file", logFile), 1000, AsyncLogTargetOverflowAction.Block )); diff --git a/src/Ryujinx.Ui.Common/Configuration/System/Language.cs b/src/Ryujinx.Ui.Common/Configuration/System/Language.cs index 2eb9ef5c1..72416bfe7 100644 --- a/src/Ryujinx.Ui.Common/Configuration/System/Language.cs +++ b/src/Ryujinx.Ui.Common/Configuration/System/Language.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System.Text.Json.Serialization; namespace Ryujinx.Ui.Common.Configuration.System diff --git a/src/Ryujinx.Ui.Common/Configuration/System/Region.cs b/src/Ryujinx.Ui.Common/Configuration/System/Region.cs index 03aed7d50..2478b40f9 100644 --- a/src/Ryujinx.Ui.Common/Configuration/System/Region.cs +++ b/src/Ryujinx.Ui.Common/Configuration/System/Region.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Utilities; +using Ryujinx.Common.Utilities; using System.Text.Json.Serialization; namespace Ryujinx.Ui.Common.Configuration.System diff --git a/src/Ryujinx.Ui.Common/Configuration/Ui/ColumnSort.cs b/src/Ryujinx.Ui.Common/Configuration/Ui/ColumnSort.cs index cbc13b857..88cf7cdac 100644 --- a/src/Ryujinx.Ui.Common/Configuration/Ui/ColumnSort.cs +++ b/src/Ryujinx.Ui.Common/Configuration/Ui/ColumnSort.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Ui.Common.Configuration.Ui +namespace Ryujinx.Ui.Common.Configuration.Ui { public struct ColumnSort { diff --git a/src/Ryujinx.Ui.Common/Configuration/Ui/GuiColumns.cs b/src/Ryujinx.Ui.Common/Configuration/Ui/GuiColumns.cs index aff654599..7e944015b 100644 --- a/src/Ryujinx.Ui.Common/Configuration/Ui/GuiColumns.cs +++ b/src/Ryujinx.Ui.Common/Configuration/Ui/GuiColumns.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Ui.Common.Configuration.Ui +namespace Ryujinx.Ui.Common.Configuration.Ui { public struct GuiColumns { diff --git a/src/Ryujinx.Ui.Common/DiscordIntegrationModule.cs b/src/Ryujinx.Ui.Common/DiscordIntegrationModule.cs index 69d725967..edc634aa5 100644 --- a/src/Ryujinx.Ui.Common/DiscordIntegrationModule.cs +++ b/src/Ryujinx.Ui.Common/DiscordIntegrationModule.cs @@ -1,4 +1,4 @@ -using DiscordRPC; +using DiscordRPC; using Ryujinx.Common; using Ryujinx.Ui.Common.Configuration; diff --git a/src/Ryujinx.Ui.Common/Extensions/FileTypeExtensions.cs b/src/Ryujinx.Ui.Common/Extensions/FileTypeExtensions.cs index e60fa78cd..c827f750e 100644 --- a/src/Ryujinx.Ui.Common/Extensions/FileTypeExtensions.cs +++ b/src/Ryujinx.Ui.Common/Extensions/FileTypeExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using static Ryujinx.Ui.Common.Configuration.ConfigurationState.UiSection; namespace Ryujinx.Ui.Common diff --git a/src/Ryujinx.Ui.Common/Helper/ConsoleHelper.cs b/src/Ryujinx.Ui.Common/Helper/ConsoleHelper.cs index 160c6390f..65155641f 100644 --- a/src/Ryujinx.Ui.Common/Helper/ConsoleHelper.cs +++ b/src/Ryujinx.Ui.Common/Helper/ConsoleHelper.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using System; using System.Runtime.InteropServices; using System.Runtime.Versioning; diff --git a/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs b/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs index 570fb91e2..daa59d251 100644 --- a/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs +++ b/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs @@ -22,7 +22,7 @@ namespace Ryujinx.Ui.Common.Helper [LibraryImport("shell32.dll", SetLastError = true)] public static partial void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2); - public static bool IsTypeAssociationSupported => (OperatingSystem.IsLinux() || OperatingSystem.IsWindows()) && !ReleaseInformation.IsFlatHubBuild(); + public static bool IsTypeAssociationSupported => (OperatingSystem.IsLinux() || OperatingSystem.IsWindows()) && !ReleaseInformation.IsFlatHubBuild; [SupportedOSPlatform("linux")] private static bool AreMimeTypesRegisteredLinux() => File.Exists(Path.Combine(_mimeDbPath, "packages", "Ryujinx.xml")); @@ -34,7 +34,7 @@ namespace Ryujinx.Ui.Common.Helper if ((uninstall && AreMimeTypesRegisteredLinux()) || (!uninstall && !AreMimeTypesRegisteredLinux())) { - string mimeTypesFile = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "mime", "Ryujinx.xml"); + string mimeTypesFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "mime", "Ryujinx.xml"); string additionalArgs = !uninstall ? "--novendor" : ""; using Process mimeProcess = new(); diff --git a/src/Ryujinx.Ui.Common/Helper/OpenHelper.cs b/src/Ryujinx.Ui.Common/Helper/OpenHelper.cs index 49a53ae48..04ebbf3b0 100644 --- a/src/Ryujinx.Ui.Common/Helper/OpenHelper.cs +++ b/src/Ryujinx.Ui.Common/Helper/OpenHelper.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using System; using System.Diagnostics; using System.IO; diff --git a/src/Ryujinx.Ui.Common/Helper/SetupValidator.cs b/src/Ryujinx.Ui.Common/Helper/SetupValidator.cs index 4a7dac474..65c38d7b8 100644 --- a/src/Ryujinx.Ui.Common/Helper/SetupValidator.cs +++ b/src/Ryujinx.Ui.Common/Helper/SetupValidator.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.HLE.FileSystem; using System; using System.IO; diff --git a/src/Ryujinx.Ui.Common/Helper/ShortcutHelper.cs b/src/Ryujinx.Ui.Common/Helper/ShortcutHelper.cs index 103b78c24..60b928985 100644 --- a/src/Ryujinx.Ui.Common/Helper/ShortcutHelper.cs +++ b/src/Ryujinx.Ui.Common/Helper/ShortcutHelper.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common; +using Ryujinx.Common; using Ryujinx.Common.Configuration; using ShellLink; using SixLabors.ImageSharp; @@ -54,6 +54,7 @@ namespace Ryujinx.Ui.Common.Helper { string basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx"); var plistFile = EmbeddedResources.ReadAllText("Ryujinx.Ui.Common/shortcut-template.plist"); + var shortcutScript = EmbeddedResources.ReadAllText("Ryujinx.Ui.Common/shortcut-launch-script.sh"); // Macos .App folder string contentFolderPath = Path.Combine("/Applications", cleanedAppName + ".app", "Contents"); string scriptFolderPath = Path.Combine(contentFolderPath, "MacOS"); @@ -68,8 +69,7 @@ namespace Ryujinx.Ui.Common.Helper string scriptPath = Path.Combine(scriptFolderPath, ScriptName); using StreamWriter scriptFile = new(scriptPath); - scriptFile.WriteLine("#!/bin/sh"); - scriptFile.WriteLine($"{basePath} {GetArgsString(appFilePath)}"); + scriptFile.Write(shortcutScript, basePath, GetArgsString(appFilePath)); // Set execute permission FileInfo fileInfo = new(scriptPath); diff --git a/src/Ryujinx.Ui.Common/Helper/TitleHelper.cs b/src/Ryujinx.Ui.Common/Helper/TitleHelper.cs new file mode 100644 index 000000000..089b52154 --- /dev/null +++ b/src/Ryujinx.Ui.Common/Helper/TitleHelper.cs @@ -0,0 +1,30 @@ +using Ryujinx.HLE.Loaders.Processes; +using System; + +namespace Ryujinx.Ui.Common.Helper +{ + public static class TitleHelper + { + public static string ActiveApplicationTitle(ProcessResult activeProcess, string applicationVersion, string pauseString = "") + { + if (activeProcess == null) + { + return String.Empty; + } + + string titleNameSection = string.IsNullOrWhiteSpace(activeProcess.Name) ? string.Empty : $" {activeProcess.Name}"; + string titleVersionSection = string.IsNullOrWhiteSpace(activeProcess.DisplayVersion) ? string.Empty : $" v{activeProcess.DisplayVersion}"; + string titleIdSection = $" ({activeProcess.ProgramIdText.ToUpper()})"; + string titleArchSection = activeProcess.Is64Bit ? " (64-bit)" : " (32-bit)"; + + string appTitle = $"Ryujinx {applicationVersion} -{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}"; + + if (!string.IsNullOrEmpty(pauseString)) + { + appTitle += $" ({pauseString})"; + } + + return appTitle; + } + } +} diff --git a/src/Ryujinx.Ui.Common/Helper/ValueFormatUtils.cs b/src/Ryujinx.Ui.Common/Helper/ValueFormatUtils.cs index 951cd089e..b1597a7cc 100644 --- a/src/Ryujinx.Ui.Common/Helper/ValueFormatUtils.cs +++ b/src/Ryujinx.Ui.Common/Helper/ValueFormatUtils.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Globalization; using System.Linq; diff --git a/src/Ryujinx.Ui.Common/Models/Amiibo/AmiiboApi.cs b/src/Ryujinx.Ui.Common/Models/Amiibo/AmiiboApi.cs index e8eba6d38..ff0b80c46 100644 --- a/src/Ryujinx.Ui.Common/Models/Amiibo/AmiiboApi.cs +++ b/src/Ryujinx.Ui.Common/Models/Amiibo/AmiiboApi.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Text.Json.Serialization; diff --git a/src/Ryujinx.Ui.Common/Models/Amiibo/AmiiboApiGamesSwitch.cs b/src/Ryujinx.Ui.Common/Models/Amiibo/AmiiboApiGamesSwitch.cs index 6a0442f08..3c62b7cc4 100644 --- a/src/Ryujinx.Ui.Common/Models/Amiibo/AmiiboApiGamesSwitch.cs +++ b/src/Ryujinx.Ui.Common/Models/Amiibo/AmiiboApiGamesSwitch.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Text.Json.Serialization; namespace Ryujinx.Ui.Common.Models.Amiibo diff --git a/src/Ryujinx.Ui.Common/Models/Amiibo/AmiiboApiUsage.cs b/src/Ryujinx.Ui.Common/Models/Amiibo/AmiiboApiUsage.cs index d9d3a18f6..3c774fd56 100644 --- a/src/Ryujinx.Ui.Common/Models/Amiibo/AmiiboApiUsage.cs +++ b/src/Ryujinx.Ui.Common/Models/Amiibo/AmiiboApiUsage.cs @@ -1,4 +1,4 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace Ryujinx.Ui.Common.Models.Amiibo { diff --git a/src/Ryujinx.Ui.Common/Models/Amiibo/AmiiboJson.cs b/src/Ryujinx.Ui.Common/Models/Amiibo/AmiiboJson.cs index bcfe230dd..c9d91c50a 100644 --- a/src/Ryujinx.Ui.Common/Models/Amiibo/AmiiboJson.cs +++ b/src/Ryujinx.Ui.Common/Models/Amiibo/AmiiboJson.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Text.Json.Serialization; diff --git a/src/Ryujinx.Ui.Common/Models/Amiibo/AmiiboJsonSerializerContext.cs b/src/Ryujinx.Ui.Common/Models/Amiibo/AmiiboJsonSerializerContext.cs index 09888d37b..4906c6524 100644 --- a/src/Ryujinx.Ui.Common/Models/Amiibo/AmiiboJsonSerializerContext.cs +++ b/src/Ryujinx.Ui.Common/Models/Amiibo/AmiiboJsonSerializerContext.cs @@ -1,4 +1,4 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace Ryujinx.Ui.Common.Models.Amiibo { diff --git a/src/Ryujinx.Ui.Common/Models/Github/GithubReleaseAssetJsonResponse.cs b/src/Ryujinx.Ui.Common/Models/Github/GithubReleaseAssetJsonResponse.cs index ed0a49f6c..67d238d24 100644 --- a/src/Ryujinx.Ui.Common/Models/Github/GithubReleaseAssetJsonResponse.cs +++ b/src/Ryujinx.Ui.Common/Models/Github/GithubReleaseAssetJsonResponse.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Ui.Common.Models.Github +namespace Ryujinx.Ui.Common.Models.Github { public class GithubReleaseAssetJsonResponse { diff --git a/src/Ryujinx.Ui.Common/Models/Github/GithubReleasesJsonResponse.cs b/src/Ryujinx.Ui.Common/Models/Github/GithubReleasesJsonResponse.cs index 3fa7cf817..0f83e32cc 100644 --- a/src/Ryujinx.Ui.Common/Models/Github/GithubReleasesJsonResponse.cs +++ b/src/Ryujinx.Ui.Common/Models/Github/GithubReleasesJsonResponse.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace Ryujinx.Ui.Common.Models.Github { diff --git a/src/Ryujinx.Ui.Common/Models/Github/GithubReleasesJsonSerializerContext.cs b/src/Ryujinx.Ui.Common/Models/Github/GithubReleasesJsonSerializerContext.cs index c6dd88755..8a19277b3 100644 --- a/src/Ryujinx.Ui.Common/Models/Github/GithubReleasesJsonSerializerContext.cs +++ b/src/Ryujinx.Ui.Common/Models/Github/GithubReleasesJsonSerializerContext.cs @@ -1,4 +1,4 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace Ryujinx.Ui.Common.Models.Github { diff --git a/src/Ryujinx.Ui.Common/Ryujinx.Ui.Common.csproj b/src/Ryujinx.Ui.Common/Ryujinx.Ui.Common.csproj index 74331fdef..1a8c216aa 100644 --- a/src/Ryujinx.Ui.Common/Ryujinx.Ui.Common.csproj +++ b/src/Ryujinx.Ui.Common/Ryujinx.Ui.Common.csproj @@ -51,6 +51,7 @@ + diff --git a/src/Ryujinx.Ui.Common/SystemInfo/SystemInfo.cs b/src/Ryujinx.Ui.Common/SystemInfo/SystemInfo.cs index 6a4fe6803..e78db8af7 100644 --- a/src/Ryujinx.Ui.Common/SystemInfo/SystemInfo.cs +++ b/src/Ryujinx.Ui.Common/SystemInfo/SystemInfo.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using Ryujinx.Ui.Common.Helper; using System; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Ui.Common/UserError.cs b/src/Ryujinx.Ui.Common/UserError.cs index 63be1e264..832aae9d6 100644 --- a/src/Ryujinx.Ui.Common/UserError.cs +++ b/src/Ryujinx.Ui.Common/UserError.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Ui.Common +namespace Ryujinx.Ui.Common { /// /// Represent a common error that could be reported to the user by the emulator. diff --git a/src/Ryujinx.Ui.LocaleGenerator/LocaleGenerator.cs b/src/Ryujinx.Ui.LocaleGenerator/LocaleGenerator.cs index d1b9131d0..27573a8fb 100644 --- a/src/Ryujinx.Ui.LocaleGenerator/LocaleGenerator.cs +++ b/src/Ryujinx.Ui.LocaleGenerator/LocaleGenerator.cs @@ -1,4 +1,4 @@ -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using System.Linq; using System.Text; diff --git a/src/Ryujinx/Input/GTK3/GTK3Keyboard.cs b/src/Ryujinx/Input/GTK3/GTK3Keyboard.cs index 16bef39b4..ff7a2c3b6 100644 --- a/src/Ryujinx/Input/GTK3/GTK3Keyboard.cs +++ b/src/Ryujinx/Input/GTK3/GTK3Keyboard.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Configuration.Hid; +using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid.Keyboard; using System; using System.Collections.Generic; diff --git a/src/Ryujinx/Input/GTK3/GTK3KeyboardDriver.cs b/src/Ryujinx/Input/GTK3/GTK3KeyboardDriver.cs index ae249c273..e502254be 100644 --- a/src/Ryujinx/Input/GTK3/GTK3KeyboardDriver.cs +++ b/src/Ryujinx/Input/GTK3/GTK3KeyboardDriver.cs @@ -1,4 +1,4 @@ -using Gdk; +using Gdk; using Gtk; using System; using System.Collections.Generic; diff --git a/src/Ryujinx/Input/GTK3/GTK3MappingHelper.cs b/src/Ryujinx/Input/GTK3/GTK3MappingHelper.cs index 7a72a6093..422a96030 100644 --- a/src/Ryujinx/Input/GTK3/GTK3MappingHelper.cs +++ b/src/Ryujinx/Input/GTK3/GTK3MappingHelper.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; diff --git a/src/Ryujinx/Modules/Updater/UpdateDialog.cs b/src/Ryujinx/Modules/Updater/UpdateDialog.cs index 695634374..0057761bb 100644 --- a/src/Ryujinx/Modules/Updater/UpdateDialog.cs +++ b/src/Ryujinx/Modules/Updater/UpdateDialog.cs @@ -1,6 +1,7 @@ using Gdk; using Gtk; using Ryujinx.Common; +using Ryujinx.Common.Configuration; using Ryujinx.Ui; using Ryujinx.Ui.Common.Configuration; using Ryujinx.Ui.Common.Helper; @@ -52,7 +53,7 @@ namespace Ryujinx.Modules ProcessStartInfo processStart = new(ryuName) { UseShellExecute = true, - WorkingDirectory = ReleaseInformation.GetBaseApplicationDirectory(), + WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory }; foreach (string argument in CommandLineState.Arguments) diff --git a/src/Ryujinx/Modules/Updater/Updater.cs b/src/Ryujinx/Modules/Updater/Updater.cs index f8ce4c0b9..2fed43622 100644 --- a/src/Ryujinx/Modules/Updater/Updater.cs +++ b/src/Ryujinx/Modules/Updater/Updater.cs @@ -532,7 +532,7 @@ namespace Ryujinx.Modules return false; } - if (Program.Version.Contains("dirty") || !ReleaseInformation.IsValid()) + if (Program.Version.Contains("dirty") || !ReleaseInformation.IsValid) { if (showWarnings) { @@ -546,7 +546,7 @@ namespace Ryujinx.Modules #else if (showWarnings) { - if (ReleaseInformation.IsFlatHubBuild()) + if (ReleaseInformation.IsFlatHubBuild) { GtkDialog.CreateWarningDialog("Updater Disabled!", "Please update Ryujinx via FlatHub."); } diff --git a/src/Ryujinx/Program.cs b/src/Ryujinx/Program.cs index 597d00f30..3b5cd770b 100644 --- a/src/Ryujinx/Program.cs +++ b/src/Ryujinx/Program.cs @@ -71,7 +71,7 @@ namespace Ryujinx static void Main(string[] args) { - Version = ReleaseInformation.GetVersion(); + Version = ReleaseInformation.Version; if (OperatingSystem.IsWindows() && !OperatingSystem.IsWindowsVersionAtLeast(10, 0, 17134)) { @@ -167,8 +167,8 @@ namespace Ryujinx Quality = 100, }); - string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"); - string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, "Config.json"); + string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ReleaseInformation.ConfigName); + string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, ReleaseInformation.ConfigName); // Now load the configuration as the other subsystems are now registered ConfigurationPath = File.Exists(localConfigurationPath) diff --git a/src/Ryujinx/Ui/Applet/ErrorAppletDialog.cs b/src/Ryujinx/Ui/Applet/ErrorAppletDialog.cs index cd3530f34..c6bcf3f28 100644 --- a/src/Ryujinx/Ui/Applet/ErrorAppletDialog.cs +++ b/src/Ryujinx/Ui/Applet/ErrorAppletDialog.cs @@ -1,4 +1,4 @@ -using Gtk; +using Gtk; using Ryujinx.Ui.Common.Configuration; using System.Reflection; diff --git a/src/Ryujinx/Ui/Applet/GtkHostUiTheme.cs b/src/Ryujinx/Ui/Applet/GtkHostUiTheme.cs index df8103325..1bc010591 100644 --- a/src/Ryujinx/Ui/Applet/GtkHostUiTheme.cs +++ b/src/Ryujinx/Ui/Applet/GtkHostUiTheme.cs @@ -1,4 +1,4 @@ -using Gtk; +using Gtk; using Ryujinx.HLE.Ui; using System.Diagnostics; diff --git a/src/Ryujinx/Ui/Helper/SortHelper.cs b/src/Ryujinx/Ui/Helper/SortHelper.cs index c7a72ab9b..4e625f922 100644 --- a/src/Ryujinx/Ui/Helper/SortHelper.cs +++ b/src/Ryujinx/Ui/Helper/SortHelper.cs @@ -1,4 +1,4 @@ -using Gtk; +using Gtk; using Ryujinx.Ui.Common.Helper; using System; diff --git a/src/Ryujinx/Ui/Helper/ThemeHelper.cs b/src/Ryujinx/Ui/Helper/ThemeHelper.cs index 5289ebc5f..5cd9ad520 100644 --- a/src/Ryujinx/Ui/Helper/ThemeHelper.cs +++ b/src/Ryujinx/Ui/Helper/ThemeHelper.cs @@ -1,4 +1,5 @@ -using Gtk; +using Gtk; +using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.Ui.Common.Configuration; using System.IO; @@ -24,7 +25,7 @@ namespace Ryujinx.Ui.Helper } else { - Logger.Warning?.Print(LogClass.Application, $"The \"custom_theme_path\" section in \"Config.json\" contains an invalid path: \"{ConfigurationState.Instance.Ui.CustomThemePath}\"."); + Logger.Warning?.Print(LogClass.Application, $"The \"custom_theme_path\" section in \"{ReleaseInformation.ConfigName}\" contains an invalid path: \"{ConfigurationState.Instance.Ui.CustomThemePath}\"."); ConfigurationState.Instance.Ui.CustomThemePath.Value = ""; ConfigurationState.Instance.Ui.EnableCustomTheme.Value = false; diff --git a/src/Ryujinx/Ui/MainWindow.cs b/src/Ryujinx/Ui/MainWindow.cs index d3f46d1f9..99d2c5a3a 100644 --- a/src/Ryujinx/Ui/MainWindow.cs +++ b/src/Ryujinx/Ui/MainWindow.cs @@ -1,4 +1,3 @@ -using ARMeilleure.Translation; using Gtk; using LibHac.Common; using LibHac.Common.Keys; @@ -931,8 +930,6 @@ namespace Ryujinx.Ui _deviceExitStatus.Reset(); - Translator.IsReadyForTranslation.Reset(); - Thread windowThread = new(CreateGameWindow) { Name = "GUI.WindowThread", @@ -1380,7 +1377,12 @@ namespace Ryujinx.Ui private void OpenLogsFolder_Pressed(object sender, EventArgs args) { - string logPath = System.IO.Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "Logs"); + string logPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs"); + + if (LoggerModule.LogDirectoryPath != null) + { + logPath = LoggerModule.LogDirectoryPath; + } new DirectoryInfo(logPath).Create(); @@ -1454,6 +1456,8 @@ namespace Ryujinx.Ui _pauseEmulation.Sensitive = false; _resumeEmulation.Sensitive = true; _emulationContext.System.TogglePauseEmulation(true); + Title = TitleHelper.ActiveApplicationTitle(_emulationContext.Processes.ActiveApplication, Program.Version, "Paused"); + Logger.Info?.Print(LogClass.Emulation, "Emulation was paused"); } private void ResumeEmulation_Pressed(object sender, EventArgs args) @@ -1461,6 +1465,8 @@ namespace Ryujinx.Ui _pauseEmulation.Sensitive = true; _resumeEmulation.Sensitive = false; _emulationContext.System.TogglePauseEmulation(false); + Title = TitleHelper.ActiveApplicationTitle(_emulationContext.Processes.ActiveApplication, Program.Version); + Logger.Info?.Print(LogClass.Emulation, "Emulation was resumed"); } public void ActivatePauseMenu() diff --git a/src/Ryujinx/Ui/OpenGLRenderer.cs b/src/Ryujinx/Ui/OpenGLRenderer.cs index 2ca791fe8..d10445b00 100644 --- a/src/Ryujinx/Ui/OpenGLRenderer.cs +++ b/src/Ryujinx/Ui/OpenGLRenderer.cs @@ -1,4 +1,4 @@ -using OpenTK.Graphics.OpenGL; +using OpenTK.Graphics.OpenGL; using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Input.HLE; diff --git a/src/Ryujinx/Ui/OpenToolkitBindingsContext.cs b/src/Ryujinx/Ui/OpenToolkitBindingsContext.cs index b35673ebb..49dd5da8e 100644 --- a/src/Ryujinx/Ui/OpenToolkitBindingsContext.cs +++ b/src/Ryujinx/Ui/OpenToolkitBindingsContext.cs @@ -1,4 +1,4 @@ -using SPB.Graphics; +using SPB.Graphics; using System; namespace Ryujinx.Ui diff --git a/src/Ryujinx/Ui/RendererWidgetBase.cs b/src/Ryujinx/Ui/RendererWidgetBase.cs index 0ee344434..7794e0448 100644 --- a/src/Ryujinx/Ui/RendererWidgetBase.cs +++ b/src/Ryujinx/Ui/RendererWidgetBase.cs @@ -1,4 +1,3 @@ -using ARMeilleure.Translation; using Gdk; using Gtk; using Ryujinx.Common; @@ -11,6 +10,7 @@ using Ryujinx.Input; using Ryujinx.Input.GTK3; using Ryujinx.Input.HLE; using Ryujinx.Ui.Common.Configuration; +using Ryujinx.Ui.Common.Helper; using Ryujinx.Ui.Widgets; using SixLabors.ImageSharp; using SixLabors.ImageSharp.Formats.Png; @@ -77,7 +77,7 @@ namespace Ryujinx.Ui private readonly IKeyboard _keyboardInterface; private readonly GraphicsDebugLevel _glLogLevel; private string _gpuBackendName; - private string _gpuVendorName; + private string _gpuDriverName; private bool _isMouseInClient; public RendererWidgetBase(InputManager inputManager, GraphicsDebugLevel glLogLevel) @@ -141,9 +141,9 @@ namespace Ryujinx.Ui protected abstract string GetGpuBackendName(); - private string GetGpuVendorName() + private string GetGpuDriverName() { - return Renderer.GetHardwareInfo().GpuVendor; + return Renderer.GetHardwareInfo().GpuDriver; } private void HideCursorStateChanged(object sender, ReactiveEventArgs state) @@ -443,13 +443,12 @@ namespace Ryujinx.Ui Renderer.Window.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value); _gpuBackendName = GetGpuBackendName(); - _gpuVendorName = GetGpuVendorName(); + _gpuDriverName = GetGpuDriverName(); Device.Gpu.Renderer.RunLoop(() => { Device.Gpu.SetGpuThread(); Device.Gpu.InitializeShaderCache(_gpuCancellationTokenSource.Token); - Translator.IsReadyForTranslation.Set(); Renderer.Window.ChangeVSyncMode(Device.EnableDeviceVsync); @@ -495,7 +494,7 @@ namespace Ryujinx.Ui ConfigurationState.Instance.Graphics.AspectRatio.Value.ToText(), $"Game: {Device.Statistics.GetGameFrameRate():00.00} FPS ({Device.Statistics.GetGameFrameTime():00.00} ms)", $"FIFO: {Device.Statistics.GetFifoPercent():0.00} %", - $"GPU: {_gpuVendorName}")); + $"GPU: {_gpuDriverName}")); _ticks = Math.Min(_ticks - _ticksPerFrame, _ticksPerFrame); } @@ -525,12 +524,7 @@ namespace Ryujinx.Ui var activeProcess = Device.Processes.ActiveApplication; - string titleNameSection = string.IsNullOrWhiteSpace(activeProcess.Name) ? string.Empty : $" {activeProcess.Name}"; - string titleVersionSection = string.IsNullOrWhiteSpace(activeProcess.DisplayVersion) ? string.Empty : $" v{activeProcess.DisplayVersion}"; - string titleIdSection = $" ({activeProcess.ProgramIdText.ToUpper()})"; - string titleArchSection = activeProcess.Is64Bit ? " (64-bit)" : " (32-bit)"; - - parent.Title = $"Ryujinx {Program.Version} -{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}"; + parent.Title = TitleHelper.ActiveApplicationTitle(activeProcess, Program.Version); }); Thread renderLoopThread = new(Render) diff --git a/src/Ryujinx/Ui/SPBOpenGLContext.cs b/src/Ryujinx/Ui/SPBOpenGLContext.cs index b6195a9c6..6f2db697a 100644 --- a/src/Ryujinx/Ui/SPBOpenGLContext.cs +++ b/src/Ryujinx/Ui/SPBOpenGLContext.cs @@ -1,4 +1,4 @@ -using OpenTK.Graphics.OpenGL; +using OpenTK.Graphics.OpenGL; using Ryujinx.Graphics.OpenGL; using SPB.Graphics; using SPB.Graphics.OpenGL; diff --git a/src/Ryujinx/Ui/StatusUpdatedEventArgs.cs b/src/Ryujinx/Ui/StatusUpdatedEventArgs.cs index 949390caa..72e7d7f5b 100644 --- a/src/Ryujinx/Ui/StatusUpdatedEventArgs.cs +++ b/src/Ryujinx/Ui/StatusUpdatedEventArgs.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Ryujinx.Ui { diff --git a/src/Ryujinx/Ui/VulkanRenderer.cs b/src/Ryujinx/Ui/VulkanRenderer.cs index ecb3fa243..e1aae0965 100644 --- a/src/Ryujinx/Ui/VulkanRenderer.cs +++ b/src/Ryujinx/Ui/VulkanRenderer.cs @@ -1,4 +1,4 @@ -using Gdk; +using Gdk; using Ryujinx.Common.Configuration; using Ryujinx.Input.HLE; using Ryujinx.Ui.Helper; diff --git a/src/Ryujinx/Ui/Widgets/GameTableContextMenu.Designer.cs b/src/Ryujinx/Ui/Widgets/GameTableContextMenu.Designer.cs index 734437eea..162c172d9 100644 --- a/src/Ryujinx/Ui/Widgets/GameTableContextMenu.Designer.cs +++ b/src/Ryujinx/Ui/Widgets/GameTableContextMenu.Designer.cs @@ -1,4 +1,5 @@ using Gtk; +using System; namespace Ryujinx.Ui.Widgets { @@ -193,7 +194,7 @@ namespace Ryujinx.Ui.Widgets // _createShortcutMenuItem = new MenuItem("Create Application Shortcut") { - TooltipText = "Create a Desktop Shortcut that launches the selected Application." + TooltipText = OperatingSystem.IsMacOS() ? "Create a shortcut in macOS's Applications folder that launches the selected Application" : "Create a Desktop Shortcut that launches the selected Application." }; _createShortcutMenuItem.Activated += CreateShortcut_Clicked; diff --git a/src/Ryujinx/Ui/Widgets/GameTableContextMenu.cs b/src/Ryujinx/Ui/Widgets/GameTableContextMenu.cs index 5af181b08..eb9f52d73 100644 --- a/src/Ryujinx/Ui/Widgets/GameTableContextMenu.cs +++ b/src/Ryujinx/Ui/Widgets/GameTableContextMenu.cs @@ -1,4 +1,4 @@ -using Gtk; +using Gtk; using LibHac; using LibHac.Account; using LibHac.Common; @@ -78,7 +78,7 @@ namespace Ryujinx.Ui.Widgets _extractExeFsMenuItem.Sensitive = hasNca; _extractLogoMenuItem.Sensitive = hasNca; - _createShortcutMenuItem.Sensitive = !ReleaseInformation.IsFlatHubBuild(); + _createShortcutMenuItem.Sensitive = !ReleaseInformation.IsFlatHubBuild; PopupAtPointer(null); } @@ -497,7 +497,7 @@ namespace Ryujinx.Ui.Widgets private void OpenTitleModDir_Clicked(object sender, EventArgs args) { string modsBasePath = ModLoader.GetModsBasePath(); - string titleModsPath = ModLoader.GetTitleDir(modsBasePath, _titleIdText); + string titleModsPath = ModLoader.GetApplicationDir(modsBasePath, _titleIdText); OpenHelper.OpenFolder(titleModsPath); } @@ -505,7 +505,7 @@ namespace Ryujinx.Ui.Widgets private void OpenTitleSdModDir_Clicked(object sender, EventArgs args) { string sdModsBasePath = ModLoader.GetSdModsBasePath(); - string titleModsPath = ModLoader.GetTitleDir(sdModsBasePath, _titleIdText); + string titleModsPath = ModLoader.GetApplicationDir(sdModsBasePath, _titleIdText); OpenHelper.OpenFolder(titleModsPath); } diff --git a/src/Ryujinx/Ui/Widgets/GtkInputDialog.cs b/src/Ryujinx/Ui/Widgets/GtkInputDialog.cs index e4fb5aa17..622980921 100644 --- a/src/Ryujinx/Ui/Widgets/GtkInputDialog.cs +++ b/src/Ryujinx/Ui/Widgets/GtkInputDialog.cs @@ -1,4 +1,4 @@ -using Gtk; +using Gtk; namespace Ryujinx.Ui.Widgets { diff --git a/src/Ryujinx/Ui/Widgets/RawInputToTextEntry.cs b/src/Ryujinx/Ui/Widgets/RawInputToTextEntry.cs index a0092f29b..e82a3d492 100644 --- a/src/Ryujinx/Ui/Widgets/RawInputToTextEntry.cs +++ b/src/Ryujinx/Ui/Widgets/RawInputToTextEntry.cs @@ -1,4 +1,4 @@ -using Gtk; +using Gtk; namespace Ryujinx.Ui.Widgets { diff --git a/src/Ryujinx/Ui/Widgets/UserErrorDialog.cs b/src/Ryujinx/Ui/Widgets/UserErrorDialog.cs index b2dea8355..63a280e6d 100644 --- a/src/Ryujinx/Ui/Widgets/UserErrorDialog.cs +++ b/src/Ryujinx/Ui/Widgets/UserErrorDialog.cs @@ -1,4 +1,4 @@ -using Gtk; +using Gtk; using Ryujinx.Ui.Common; using Ryujinx.Ui.Common.Helper; diff --git a/src/Ryujinx/Ui/Windows/AboutWindow.cs b/src/Ryujinx/Ui/Windows/AboutWindow.cs index 9e11905db..ba12bb68b 100644 --- a/src/Ryujinx/Ui/Windows/AboutWindow.cs +++ b/src/Ryujinx/Ui/Windows/AboutWindow.cs @@ -1,4 +1,4 @@ -using Gtk; +using Gtk; using Ryujinx.Common.Utilities; using Ryujinx.Ui.Common.Helper; using System.Net.Http; diff --git a/src/Ryujinx/Ui/Windows/AmiiboWindow.cs b/src/Ryujinx/Ui/Windows/AmiiboWindow.cs index 4bbaaaaa4..a2a5bce6f 100644 --- a/src/Ryujinx/Ui/Windows/AmiiboWindow.cs +++ b/src/Ryujinx/Ui/Windows/AmiiboWindow.cs @@ -1,4 +1,5 @@ -using Gtk; +using Gdk; +using Gtk; using Ryujinx.Common; using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; @@ -13,7 +14,9 @@ using System.Linq; using System.Net.Http; using System.Reflection; using System.Text; +using System.Text.Json; using System.Threading.Tasks; +using Window = Gtk.Window; namespace Ryujinx.Ui.Windows { @@ -49,11 +52,11 @@ namespace Ryujinx.Ui.Windows public AmiiboWindow() : base($"Ryujinx {Program.Version} - Amiibo") { - Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png"); + Icon = new Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png"); InitializeComponent(); - _httpClient = new HttpClient() + _httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(30), }; @@ -64,7 +67,7 @@ namespace Ryujinx.Ui.Windows _amiiboList = new List(); _amiiboLogoBytes = EmbeddedResources.Read("Ryujinx.Ui.Common/Resources/Logo_Amiibo.png"); - _amiiboImage.Pixbuf = new Gdk.Pixbuf(_amiiboLogoBytes); + _amiiboImage.Pixbuf = new Pixbuf(_amiiboLogoBytes); _scanButton.Sensitive = false; _randomUuidCheckBox.Sensitive = false; @@ -72,37 +75,83 @@ namespace Ryujinx.Ui.Windows _ = LoadContentAsync(); } - private async Task LoadContentAsync() + private static bool TryGetAmiiboJson(string json, out AmiiboJson amiiboJson) { - string amiiboJsonString = DefaultJson; - - if (File.Exists(_amiiboJsonPath)) + if (string.IsNullOrEmpty(json)) { - amiiboJsonString = await File.ReadAllTextAsync(_amiiboJsonPath); + amiiboJson = JsonHelper.Deserialize(DefaultJson, _serializerContext.AmiiboJson); - if (await NeedsUpdate(JsonHelper.Deserialize(amiiboJsonString, _serializerContext.AmiiboJson).LastUpdated)) - { - amiiboJsonString = await DownloadAmiiboJson(); - } + return false; } - else + + try + { + amiiboJson = JsonHelper.Deserialize(json, _serializerContext.AmiiboJson); + + return true; + } + catch (JsonException exception) + { + Logger.Error?.Print(LogClass.Application, $"Unable to deserialize amiibo data: {exception}"); + amiiboJson = JsonHelper.Deserialize(DefaultJson, _serializerContext.AmiiboJson); + + return false; + } + } + + private async Task GetMostRecentAmiiboListOrDefaultJson() + { + bool localIsValid = false; + bool remoteIsValid = false; + AmiiboJson amiiboJson = new(); + + try { try { - amiiboJsonString = await DownloadAmiiboJson(); + if (File.Exists(_amiiboJsonPath)) + { + localIsValid = TryGetAmiiboJson(await File.ReadAllTextAsync(_amiiboJsonPath), out amiiboJson); + } } - catch (Exception ex) + catch (Exception exception) { - Logger.Error?.Print(LogClass.Application, $"Failed to download amiibo data: {ex}"); + Logger.Warning?.Print(LogClass.Application, $"Unable to read data from '{_amiiboJsonPath}': {exception}"); + } + if (!localIsValid || await NeedsUpdate(amiiboJson.LastUpdated)) + { + remoteIsValid = TryGetAmiiboJson(await DownloadAmiiboJson(), out amiiboJson); + } + } + catch (Exception exception) + { + if (!(localIsValid || remoteIsValid)) + { + Logger.Error?.Print(LogClass.Application, $"Couldn't get valid amiibo data: {exception}"); + + // Neither local or remote files are valid JSON, close window. ShowInfoDialog(); - Close(); } + else if (!remoteIsValid) + { + Logger.Warning?.Print(LogClass.Application, $"Couldn't update amiibo data: {exception}"); + + // Only the local file is valid, the local one should be used + // but the user should be warned. + ShowInfoDialog(); + } } - _amiiboList = JsonHelper.Deserialize(amiiboJsonString, _serializerContext.AmiiboJson).Amiibo; - _amiiboList = _amiiboList.OrderBy(amiibo => amiibo.AmiiboSeries).ToList(); + return amiiboJson; + } + + private async Task LoadContentAsync() + { + AmiiboJson amiiboJson = await GetMostRecentAmiiboListOrDefaultJson(); + + _amiiboList = amiiboJson.Amiibo.OrderBy(amiibo => amiibo.AmiiboSeries).ToList(); if (LastScannedAmiiboShowAll) { @@ -178,46 +227,50 @@ namespace Ryujinx.Ui.Windows if (response.IsSuccessStatusCode) { - return response.Content.Headers.LastModified != new DateTimeOffset(oldLastModified.Ticks - (oldLastModified.Ticks % TimeSpan.TicksPerSecond), TimeSpan.Zero); + return response.Content.Headers.LastModified != oldLastModified; } - - return false; } - catch (Exception ex) + catch (HttpRequestException exception) { - Logger.Error?.Print(LogClass.Application, $"Failed to check for amiibo updates: {ex}"); - - ShowInfoDialog(); - - return false; + Logger.Error?.Print(LogClass.Application, $"Unable to check for amiibo data updates: {exception}"); } + + return false; } private async Task DownloadAmiiboJson() { - HttpResponseMessage response = await _httpClient.GetAsync("https://amiibo.ryujinx.org/"); - - if (response.IsSuccessStatusCode) + try { - string amiiboJsonString = await response.Content.ReadAsStringAsync(); + HttpResponseMessage response = await _httpClient.GetAsync("https://amiibo.ryujinx.org/"); - using (FileStream dlcJsonStream = File.Create(_amiiboJsonPath, 4096, FileOptions.WriteThrough)) + if (response.IsSuccessStatusCode) { - dlcJsonStream.Write(Encoding.UTF8.GetBytes(amiiboJsonString)); + string amiiboJsonString = await response.Content.ReadAsStringAsync(); + + try + { + using FileStream dlcJsonStream = File.Create(_amiiboJsonPath, 4096, FileOptions.WriteThrough); + dlcJsonStream.Write(Encoding.UTF8.GetBytes(amiiboJsonString)); + } + catch (Exception exception) + { + Logger.Warning?.Print(LogClass.Application, $"Couldn't write amiibo data to file '{_amiiboJsonPath}: {exception}'"); + } + + return amiiboJsonString; } - return amiiboJsonString; - } - else - { Logger.Error?.Print(LogClass.Application, $"Failed to download amiibo data. Response status code: {response.StatusCode}"); - - GtkDialog.CreateInfoDialog($"Amiibo API", "An error occured while fetching information from the API."); - - Close(); + } + catch (HttpRequestException exception) + { + Logger.Error?.Print(LogClass.Application, $"Failed to request amiibo data: {exception}"); } - return DefaultJson; + GtkDialog.CreateInfoDialog("Amiibo API", "An error occured while fetching information from the API."); + + return null; } private async Task UpdateAmiiboPreview(string imageUrl) @@ -227,7 +280,7 @@ namespace Ryujinx.Ui.Windows if (response.IsSuccessStatusCode) { byte[] amiiboPreviewBytes = await response.Content.ReadAsByteArrayAsync(); - Gdk.Pixbuf amiiboPreview = new(amiiboPreviewBytes); + Pixbuf amiiboPreview = new(amiiboPreviewBytes); float ratio = Math.Min((float)_amiiboImage.AllocatedWidth / amiiboPreview.Width, (float)_amiiboImage.AllocatedHeight / amiiboPreview.Height); @@ -235,7 +288,7 @@ namespace Ryujinx.Ui.Windows int resizeHeight = (int)(amiiboPreview.Height * ratio); int resizeWidth = (int)(amiiboPreview.Width * ratio); - _amiiboImage.Pixbuf = amiiboPreview.ScaleSimple(resizeWidth, resizeHeight, Gdk.InterpType.Bilinear); + _amiiboImage.Pixbuf = amiiboPreview.ScaleSimple(resizeWidth, resizeHeight, InterpType.Bilinear); } else { @@ -245,7 +298,7 @@ namespace Ryujinx.Ui.Windows private static void ShowInfoDialog() { - GtkDialog.CreateInfoDialog($"Amiibo API", "Unable to connect to Amiibo API server. The service may be down or you may need to verify your internet connection is online."); + GtkDialog.CreateInfoDialog("Amiibo API", "Unable to connect to Amiibo API server. The service may be down or you may need to verify your internet connection is online."); } // @@ -301,7 +354,7 @@ namespace Ryujinx.Ui.Windows { AmiiboId = _amiiboCharsComboBox.ActiveId; - _amiiboImage.Pixbuf = new Gdk.Pixbuf(_amiiboLogoBytes); + _amiiboImage.Pixbuf = new Pixbuf(_amiiboLogoBytes); string imageUrl = _amiiboList.Find(amiibo => amiibo.Head + amiibo.Tail == _amiiboCharsComboBox.ActiveId).Image; @@ -341,7 +394,7 @@ namespace Ryujinx.Ui.Windows private void ShowAllCheckBox_Clicked(object sender, EventArgs e) { - _amiiboImage.Pixbuf = new Gdk.Pixbuf(_amiiboLogoBytes); + _amiiboImage.Pixbuf = new Pixbuf(_amiiboLogoBytes); _amiiboSeriesComboBox.Changed -= SeriesComboBox_Changed; _amiiboCharsComboBox.Changed -= CharacterComboBox_Changed; @@ -352,7 +405,7 @@ namespace Ryujinx.Ui.Windows _scanButton.Sensitive = false; _randomUuidCheckBox.Sensitive = false; - new Task(() => ParseAmiiboData()).Start(); + new Task(ParseAmiiboData).Start(); } private void ScanButton_Pressed(object sender, EventArgs args) diff --git a/src/Ryujinx/Ui/Windows/AvatarWindow.cs b/src/Ryujinx/Ui/Windows/AvatarWindow.cs index 826b0e056..3d3ff7c3c 100644 --- a/src/Ryujinx/Ui/Windows/AvatarWindow.cs +++ b/src/Ryujinx/Ui/Windows/AvatarWindow.cs @@ -1,4 +1,4 @@ -using Gtk; +using Gtk; using LibHac.Common; using LibHac.Fs; using LibHac.Fs.Fsa; diff --git a/src/Ryujinx/Ui/Windows/CheatWindow.cs b/src/Ryujinx/Ui/Windows/CheatWindow.cs index 1eca732b2..afccec53c 100644 --- a/src/Ryujinx/Ui/Windows/CheatWindow.cs +++ b/src/Ryujinx/Ui/Windows/CheatWindow.cs @@ -31,7 +31,7 @@ namespace Ryujinx.Ui.Windows _buildIdTextView.Buffer.Text = $"BuildId: {ApplicationData.GetApplicationBuildId(virtualFileSystem, titlePath)}"; string modsBasePath = ModLoader.GetModsBasePath(); - string titleModsPath = ModLoader.GetTitleDir(modsBasePath, titleId.ToString("X16")); + string titleModsPath = ModLoader.GetApplicationDir(modsBasePath, titleId.ToString("X16")); _enabledCheatsPath = System.IO.Path.Combine(titleModsPath, "cheats", "enabled.txt"); diff --git a/src/Ryujinx/Ui/Windows/UserProfilesManagerWindow.cs b/src/Ryujinx/Ui/Windows/UserProfilesManagerWindow.cs index c2ca010c7..3d503f64e 100644 --- a/src/Ryujinx/Ui/Windows/UserProfilesManagerWindow.cs +++ b/src/Ryujinx/Ui/Windows/UserProfilesManagerWindow.cs @@ -1,4 +1,4 @@ -using Gtk; +using Gtk; using Ryujinx.Common.Memory; using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.HOS.Services.Account.Acc; diff --git a/src/Spv.Generator/ConstantKey.cs b/src/Spv.Generator/ConstantKey.cs index 9fd255988..5359c24d6 100644 --- a/src/Spv.Generator/ConstantKey.cs +++ b/src/Spv.Generator/ConstantKey.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics.CodeAnalysis; namespace Spv.Generator diff --git a/src/Spv.Generator/DeterministicHashCode.cs b/src/Spv.Generator/DeterministicHashCode.cs index 1bf0b4684..ee7ad1de0 100644 --- a/src/Spv.Generator/DeterministicHashCode.cs +++ b/src/Spv.Generator/DeterministicHashCode.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Numerics; using System.Runtime.CompilerServices; diff --git a/src/Spv.Generator/DeterministicStringKey.cs b/src/Spv.Generator/DeterministicStringKey.cs index 398aa6c8c..7ed14c33c 100644 --- a/src/Spv.Generator/DeterministicStringKey.cs +++ b/src/Spv.Generator/DeterministicStringKey.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Spv.Generator { diff --git a/src/Spv.Generator/GeneratorPool.cs b/src/Spv.Generator/GeneratorPool.cs index e4266eee9..3c16586c9 100644 --- a/src/Spv.Generator/GeneratorPool.cs +++ b/src/Spv.Generator/GeneratorPool.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace Spv.Generator { diff --git a/src/Spv.Generator/IOperand.cs b/src/Spv.Generator/IOperand.cs index bda2ed694..8809b606d 100644 --- a/src/Spv.Generator/IOperand.cs +++ b/src/Spv.Generator/IOperand.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; namespace Spv.Generator diff --git a/src/Spv.Generator/Instruction.cs b/src/Spv.Generator/Instruction.cs index 27250e0f9..45492033f 100644 --- a/src/Spv.Generator/Instruction.cs +++ b/src/Spv.Generator/Instruction.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; diff --git a/src/Spv.Generator/InstructionOperands.cs b/src/Spv.Generator/InstructionOperands.cs index dfabe3071..de74f1127 100644 --- a/src/Spv.Generator/InstructionOperands.cs +++ b/src/Spv.Generator/InstructionOperands.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; diff --git a/src/Spv.Generator/LiteralInteger.cs b/src/Spv.Generator/LiteralInteger.cs index 4d5f801e3..013ca3b94 100644 --- a/src/Spv.Generator/LiteralInteger.cs +++ b/src/Spv.Generator/LiteralInteger.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; namespace Spv.Generator diff --git a/src/Spv.Generator/LiteralString.cs b/src/Spv.Generator/LiteralString.cs index 1ced040a0..ed20d0e8f 100644 --- a/src/Spv.Generator/LiteralString.cs +++ b/src/Spv.Generator/LiteralString.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Text; diff --git a/src/Spv.Generator/Module.cs b/src/Spv.Generator/Module.cs index 193284106..fb02cc966 100644 --- a/src/Spv.Generator/Module.cs +++ b/src/Spv.Generator/Module.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Diagnostics; using System.IO; using static Spv.Specification; diff --git a/src/Spv.Generator/OperandType.cs b/src/Spv.Generator/OperandType.cs index 06e8e1fb3..ddbdc89db 100644 --- a/src/Spv.Generator/OperandType.cs +++ b/src/Spv.Generator/OperandType.cs @@ -1,4 +1,4 @@ -namespace Spv.Generator +namespace Spv.Generator { public enum OperandType { diff --git a/src/Spv.Generator/TypeDeclarationKey.cs b/src/Spv.Generator/TypeDeclarationKey.cs index 1f59331f0..aaaf4fd31 100644 --- a/src/Spv.Generator/TypeDeclarationKey.cs +++ b/src/Spv.Generator/TypeDeclarationKey.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics.CodeAnalysis; namespace Spv.Generator diff --git a/src/Spv.Generator/spirv.cs b/src/Spv.Generator/spirv.cs index bbcda330b..7844c9708 100644 --- a/src/Spv.Generator/spirv.cs +++ b/src/Spv.Generator/spirv.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2020 The Khronos Group Inc. +// Copyright (c) 2014-2020 The Khronos Group Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and/or associated documentation files (the "Materials"),