diff --git a/.editorconfig b/.editorconfig
index ae4c97662..1eaf77ae6 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -17,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/labeler.yml b/.github/labeler.yml
index 027448437..b967cc776 100644
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -20,7 +20,7 @@ gpu:
gui:
- changed-files:
- - any-glob-to-any-file: ['src/Ryujinx/**', 'src/Ryujinx.Ui.Common/**', 'src/Ryujinx.Ui.LocaleGenerator/**', 'src/Ryujinx.Ava/**']
+ - any-glob-to-any-file: ['src/Ryujinx/**', 'src/Ryujinx.UI.Common/**', 'src/Ryujinx.UI.LocaleGenerator/**', 'src/Ryujinx.Ava/**']
horizon:
- changed-files:
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index cf4fdf051..598f23c5e 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -10,28 +10,17 @@ env:
jobs:
build:
- name: ${{ matrix.OS_NAME }} (${{ matrix.configuration }})
- runs-on: ${{ matrix.os }}
+ name: ${{ matrix.platform.name }} (${{ matrix.configuration }})
+ runs-on: ${{ matrix.platform.os }}
timeout-minutes: 45
strategy:
matrix:
- os: [ubuntu-latest, macOS-latest, windows-latest]
configuration: [Debug, Release]
- include:
- - os: ubuntu-latest
- OS_NAME: Linux x64
- DOTNET_RUNTIME_IDENTIFIER: linux-x64
- RELEASE_ZIP_OS_NAME: linux_x64
-
- - os: macOS-latest
- OS_NAME: macOS x64
- DOTNET_RUNTIME_IDENTIFIER: osx-x64
- RELEASE_ZIP_OS_NAME: osx_x64
-
- - os: windows-latest
- OS_NAME: Windows x64
- DOTNET_RUNTIME_IDENTIFIER: win-x64
- RELEASE_ZIP_OS_NAME: win_x64
+ platform:
+ - { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
+ - { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
+ - { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
+ - { name: osx-x64, os: macOS-latest, zip_os_name: osx_x64 }
fail-fast: false
steps:
@@ -40,7 +29,7 @@ jobs:
- 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 +38,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.platform.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.platform.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
@@ -58,46 +57,47 @@ jobs:
commands: dotnet test --no-build -c "${{ matrix.configuration }}"
timeout-minutes: 10
retry-codes: 139
+ if: matrix.platform.name != 'linux-arm64'
- name: Publish Ryujinx
- run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained true
- if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
+ run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained true
+ if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
- name: Publish Ryujinx.Headless.SDL2
- run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_sdl2_headless -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Headless.SDL2 --self-contained true
- if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
+ run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Headless.SDL2 --self-contained true
+ if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
- name: Publish Ryujinx.Ava
- run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_ava -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Ava --self-contained true
- if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
+ run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish_ava -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Ava --self-contained true
+ if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
- name: Set executable bit
run: |
chmod +x ./publish/Ryujinx ./publish/Ryujinx.sh
chmod +x ./publish_sdl2_headless/Ryujinx.Headless.SDL2 ./publish_sdl2_headless/Ryujinx.sh
chmod +x ./publish_ava/Ryujinx.Ava ./publish_ava/Ryujinx.sh
- if: github.event_name == 'pull_request' && matrix.os == 'ubuntu-latest'
+ if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest'
- name: Upload Ryujinx artifact
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 }}
+ name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}
path: publish
- if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
+ if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
- name: Upload Ryujinx.Headless.SDL2 artifact
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 }}
+ name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}
path: publish_sdl2_headless
- if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
+ if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
- name: Upload Ryujinx.Ava artifact
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 }}
+ name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}
path: publish_ava
- if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
+ if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
build_macos:
name: macOS Universal (${{ matrix.configuration }})
@@ -135,6 +135,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"
diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml
index 5311a67f6..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:
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 93aa89626..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@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 7a4b13d7d..ac598684f 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -10,7 +10,7 @@ on:
- '*.yml'
- '*.json'
- '*.config'
- - 'README.md'
+ - '*.md'
concurrency: release
@@ -45,22 +45,15 @@ jobs:
})
release:
- name: Release ${{ matrix.OS_NAME }}
- runs-on: ${{ matrix.os }}
+ name: Release for ${{ matrix.platform.name }}
+ runs-on: ${{ matrix.platform.os }}
timeout-minutes: ${{ fromJSON(vars.JOB_TIMEOUT) }}
strategy:
matrix:
- os: [ ubuntu-latest, windows-latest ]
- include:
- - os: ubuntu-latest
- OS_NAME: Linux x64
- DOTNET_RUNTIME_IDENTIFIER: linux-x64
- RELEASE_ZIP_OS_NAME: linux_x64
-
- - os: windows-latest
- OS_NAME: Windows x64
- DOTNET_RUNTIME_IDENTIFIER: win-x64
- RELEASE_ZIP_OS_NAME: win_x64
+ platform:
+ - { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
+ - { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
+ - { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
steps:
- uses: actions/checkout@v4
@@ -85,6 +78,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
@@ -92,42 +86,42 @@ jobs:
- name: Publish
run: |
- dotnet publish -c Release -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_gtk/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained true
- dotnet publish -c Release -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_sdl2_headless/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained true
- dotnet publish -c Release -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Ava --self-contained true
+ dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_gtk/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained true
+ dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained true
+ dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Ava --self-contained true
- name: Packing Windows builds
- if: matrix.os == 'windows-latest'
+ if: matrix.platform.os == 'windows-latest'
run: |
pushd publish_gtk
- 7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip publish
+ 7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
popd
pushd publish_sdl2_headless
- 7z a ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-win_x64.zip publish
+ 7z a ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
popd
pushd publish_ava
- 7z a ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip publish
+ 7z a ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
popd
shell: bash
- name: Packing Linux builds
- if: matrix.os == 'ubuntu-latest'
+ if: matrix.platform.os == 'ubuntu-latest'
run: |
pushd publish_gtk
chmod +x publish/Ryujinx.sh publish/Ryujinx
- tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz publish
+ tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
popd
pushd publish_sdl2_headless
chmod +x publish/Ryujinx.sh publish/Ryujinx.Headless.SDL2
- tar -czvf ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz publish
+ tar -czvf ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
popd
pushd publish_ava
chmod +x publish/Ryujinx.sh publish/Ryujinx.Ava
- tar -czvf ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz publish
+ tar -czvf ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
popd
shell: bash
@@ -186,6 +180,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 4c573e157..3fa3bfe2c 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -3,40 +3,39 @@
true
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
-
+
-
-
-
-
+
+
+
+
-
+
-
+
@@ -45,10 +44,10 @@
-
-
+
+
-
\ 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
(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/Ryujinx.sln b/Ryujinx.sln
index bb196cabc..47a5c714c 100644
--- a/Ryujinx.sln
+++ b/Ryujinx.sln
@@ -71,7 +71,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.FFmp
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Ava", "src\Ryujinx.Ava\Ryujinx.Ava.csproj", "{7C1B2721-13DA-4B62-B046-C626605ECCE6}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Ui.Common", "src\Ryujinx.Ui.Common\Ryujinx.Ui.Common.csproj", "{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.UI.Common", "src\Ryujinx.UI.Common\Ryujinx.UI.Common.csproj", "{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Generators", "src\Ryujinx.Horizon.Generators\Ryujinx.Horizon.Generators.csproj", "{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}"
EndProject
@@ -79,7 +79,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Vulkan", "
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spv.Generator", "src\Spv.Generator\Spv.Generator.csproj", "{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Ui.LocaleGenerator", "src\Ryujinx.Ui.LocaleGenerator\Ryujinx.Ui.LocaleGenerator.csproj", "{77D01AD9-2C98-478E-AE1D-8F7100738FB4}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.UI.LocaleGenerator", "src\Ryujinx.UI.LocaleGenerator\Ryujinx.UI.LocaleGenerator.csproj", "{77D01AD9-2C98-478E-AE1D-8F7100738FB4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Common", "src\Ryujinx.Horizon.Common\Ryujinx.Horizon.Common.csproj", "{77F96ECE-4952-42DB-A528-DED25572A573}"
EndProject
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..6cce4d213
--- a/distribution/linux/Ryujinx.sh
+++ b/distribution/linux/Ryujinx.sh
@@ -1,14 +1,21 @@
#!/bin/sh
SCRIPT_DIR=$(dirname "$(realpath "$0")")
-RYUJINX_BIN="Ryujinx"
+
+if [ -f "$SCRIPT_DIR/Ryujinx.Headless.SDL2" ]; then
+ RYUJINX_BIN="Ryujinx.Headless.SDL2"
+fi
if [ -f "$SCRIPT_DIR/Ryujinx.Ava" ]; then
RYUJINX_BIN="Ryujinx.Ava"
fi
-if [ -f "$SCRIPT_DIR/Ryujinx.Headless.SDL2" ]; then
- RYUJINX_BIN="Ryujinx.Headless.SDL2"
+if [ -f "$SCRIPT_DIR/Ryujinx" ]; then
+ RYUJINX_BIN="Ryujinx"
+fi
+
+if [ -z "$RYUJINX_BIN" ]; then
+ exit 1
fi
COMMAND="env DOTNET_EnableAlternateStackCheck=1"
@@ -17,4 +24,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
+exec $COMMAND "$SCRIPT_DIR/$RYUJINX_BIN" "$@"
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/Common/AddressTable.cs b/src/ARMeilleure/Common/AddressTable.cs
index c9b0062b5..fcab3a202 100644
--- a/src/ARMeilleure/Common/AddressTable.cs
+++ b/src/ARMeilleure/Common/AddressTable.cs
@@ -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/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/InstEmitSimdCvt32.cs b/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs
index 630e114c4..8eef6b14d 100644
--- a/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs
+++ b/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs
@@ -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/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/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/Memory/IJitMemoryAllocator.cs b/src/ARMeilleure/Memory/IJitMemoryAllocator.cs
index 171bfd2f1..ff64bf13e 100644
--- a/src/ARMeilleure/Memory/IJitMemoryAllocator.cs
+++ b/src/ARMeilleure/Memory/IJitMemoryAllocator.cs
@@ -4,7 +4,5 @@ namespace ARMeilleure.Memory
{
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 cd49f314a..c103fe8d1 100644
--- a/src/ARMeilleure/Memory/IJitMemoryBlock.cs
+++ b/src/ARMeilleure/Memory/IJitMemoryBlock.cs
@@ -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/MemoryManagerType.cs b/src/ARMeilleure/Memory/MemoryManagerType.cs
index 1e656ba27..b1cdbb069 100644
--- a/src/ARMeilleure/Memory/MemoryManagerType.cs
+++ b/src/ARMeilleure/Memory/MemoryManagerType.cs
@@ -31,7 +31,7 @@ namespace ARMeilleure.Memory
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 d0ffa8f1b..3870d4c84 100644
--- a/src/ARMeilleure/Memory/ReservedRegion.cs
+++ b/src/ARMeilleure/Memory/ReservedRegion.cs
@@ -2,7 +2,7 @@ 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 62%
rename from src/ARMeilleure/Signal/NativeSignalHandler.cs
rename to src/ARMeilleure/Signal/NativeSignalHandlerGenerator.cs
index 31ec16cb1..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.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/WindowsPartialUnmapHandler.cs b/src/ARMeilleure/Signal/WindowsPartialUnmapHandler.cs
index 27a9ea83c..3bf6a4498 100644
--- a/src/ARMeilleure/Signal/WindowsPartialUnmapHandler.cs
+++ b/src/ARMeilleure/Signal/WindowsPartialUnmapHandler.cs
@@ -2,7 +2,7 @@ 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 5444da0ca..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/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/TranslatorStubs.cs b/src/ARMeilleure/Translation/TranslatorStubs.cs
index bbe48c165..d80823a8b 100644
--- a/src/ARMeilleure/Translation/TranslatorStubs.cs
+++ b/src/ARMeilleure/Translation/TranslatorStubs.cs
@@ -1,3 +1,4 @@
+using ARMeilleure.Common;
using ARMeilleure.Instructions;
using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.State;
@@ -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/Ryujinx.Audio.Backends.SoundIo/Ryujinx.Audio.Backends.SoundIo.csproj b/src/Ryujinx.Audio.Backends.SoundIo/Ryujinx.Audio.Backends.SoundIo.csproj
index 1d92d9d2e..5c9423463 100644
--- a/src/Ryujinx.Audio.Backends.SoundIo/Ryujinx.Audio.Backends.SoundIo.csproj
+++ b/src/Ryujinx.Audio.Backends.SoundIo/Ryujinx.Audio.Backends.SoundIo.csproj
@@ -11,15 +11,15 @@
-
+
PreserveNewest
libsoundio.dll
-
+
PreserveNewest
libsoundio.dylib
-
+
PreserveNewest
libsoundio.so
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.Ava/App.axaml.cs b/src/Ryujinx.Ava/App.axaml.cs
index c1a3ab3e2..387a6dc14 100644
--- a/src/Ryujinx.Ava/App.axaml.cs
+++ b/src/Ryujinx.Ava/App.axaml.cs
@@ -8,11 +8,10 @@ using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Common;
using Ryujinx.Common.Logging;
-using Ryujinx.Ui.Common.Configuration;
-using Ryujinx.Ui.Common.Helper;
+using Ryujinx.UI.Common.Configuration;
+using Ryujinx.UI.Common.Helper;
using System;
using System.Diagnostics;
-using System.IO;
namespace Ryujinx.Ava
{
@@ -43,9 +42,9 @@ namespace Ryujinx.Ava
{
ApplyConfiguredTheme();
- ConfigurationState.Instance.Ui.BaseStyle.Event += ThemeChanged_Event;
- ConfigurationState.Instance.Ui.CustomThemePath.Event += ThemeChanged_Event;
- ConfigurationState.Instance.Ui.EnableCustomTheme.Event += CustomThemeChanged_Event;
+ ConfigurationState.Instance.UI.BaseStyle.Event += ThemeChanged_Event;
+ ConfigurationState.Instance.UI.CustomThemePath.Event += ThemeChanged_Event;
+ ConfigurationState.Instance.UI.EnableCustomTheme.Event += CustomThemeChanged_Event;
}
}
@@ -89,15 +88,13 @@ namespace Ryujinx.Ava
{
try
{
- string baseStyle = ConfigurationState.Instance.Ui.BaseStyle;
- string themePath = ConfigurationState.Instance.Ui.CustomThemePath;
- bool enableCustomTheme = ConfigurationState.Instance.Ui.EnableCustomTheme;
+ string baseStyle = ConfigurationState.Instance.UI.BaseStyle;
if (string.IsNullOrWhiteSpace(baseStyle))
{
- ConfigurationState.Instance.Ui.BaseStyle.Value = "Dark";
+ ConfigurationState.Instance.UI.BaseStyle.Value = "Dark";
- baseStyle = ConfigurationState.Instance.Ui.BaseStyle;
+ baseStyle = ConfigurationState.Instance.UI.BaseStyle;
}
RequestedThemeVariant = baseStyle switch
@@ -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 2fd9ce00d..04cec9579 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;
@@ -35,10 +34,10 @@ using Ryujinx.HLE.HOS.Services.Account.Acc;
using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.Input;
using Ryujinx.Input.HLE;
-using Ryujinx.Ui.App.Common;
-using Ryujinx.Ui.Common;
-using Ryujinx.Ui.Common.Configuration;
-using Ryujinx.Ui.Common.Helper;
+using Ryujinx.UI.App.Common;
+using Ryujinx.UI.Common;
+using Ryujinx.UI.Common.Configuration;
+using Ryujinx.UI.Common.Helper;
using Silk.NET.Vulkan;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Png;
@@ -916,7 +915,6 @@ namespace Ryujinx.Ava
{
Device.Gpu.SetGpuThread();
Device.Gpu.InitializeShaderCache(_gpuCancellationTokenSource.Token);
- Translator.IsReadyForTranslation.Set();
_renderer.Window.ChangeVSyncMode(Device.EnableDeviceVsync);
@@ -980,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()
@@ -1072,7 +1070,7 @@ namespace Ryujinx.Ava
case KeyboardHotkeyState.Screenshot:
ScreenshotRequested = true;
break;
- case KeyboardHotkeyState.ShowUi:
+ case KeyboardHotkeyState.ShowUI:
_viewModel.ShowMenuAndStatusBar = !_viewModel.ShowMenuAndStatusBar;
break;
case KeyboardHotkeyState.Pause:
@@ -1162,9 +1160,9 @@ namespace Ryujinx.Ava
{
state = KeyboardHotkeyState.Screenshot;
}
- else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ShowUi))
+ else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ShowUI))
{
- state = KeyboardHotkeyState.ShowUi;
+ state = KeyboardHotkeyState.ShowUI;
}
else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.Pause))
{
diff --git a/src/Ryujinx.Ava/Assets/Locales/en_US.json b/src/Ryujinx.Ava/Assets/Locales/en_US.json
index 75327185a..ee8b38832 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,11 @@
"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",
+ "GameListContextMenuOpenModsDirectory": "Open Mods Directory",
+ "GameListContextMenuOpenModsDirectoryToolTip": "Opens the directory which contains Application's Mods",
+ "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.",
"StatusBarGamesLoaded": "{0}/{1} Games Loaded",
"StatusBarSystemVersion": "System Version: {0}",
"LinuxVmMaxMapCountDialogTitle": "Low limit for memory mappings detected",
@@ -294,13 +297,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",
@@ -387,7 +386,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?",
@@ -398,6 +400,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",
@@ -432,6 +436,7 @@
"DlcManagerRemoveAllButton": "Remove All",
"DlcManagerEnableAllButton": "Enable All",
"DlcManagerDisableAllButton": "Disable All",
+ "ModManagerDeleteAllButton": "Delete All",
"MenuBarOptionsChangeLanguage": "Change Language",
"MenuBarShowFileTypes": "Show File Types",
"CommonSort": "Sort",
@@ -506,6 +511,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?",
@@ -517,8 +524,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",
@@ -590,12 +595,14 @@
"Writable": "Writable",
"SelectDlcDialogTitle": "Select DLC files",
"SelectUpdateDialogTitle": "Select update files",
+ "SelectModDialogTitle": "Select mod directory",
"UserProfileWindowTitle": "User Profiles Manager",
"DlcWindowTitle": "Manage Downloadable Content for {0} ({1})",
"UpdateWindowTitle": "Title Update Manager",
"CheatWindowHeading": "Manage Cheats for {0} ({1})",
"BuildId": "Build ID:",
"DlcWindowHeading": "{0} Downloadable Content(s)",
+ "ModWindowHeading": "{0} Mod(s)",
"UserProfilesEditProfile": "Edit Selected",
"Cancel": "Cancel",
"Save": "Save",
diff --git a/src/Ryujinx.Ava/Common/ApplicationHelper.cs b/src/Ryujinx.Ava/Common/ApplicationHelper.cs
index 91ca8f4d5..622a6a024 100644
--- a/src/Ryujinx.Ava/Common/ApplicationHelper.cs
+++ b/src/Ryujinx.Ava/Common/ApplicationHelper.cs
@@ -18,8 +18,8 @@ using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Services.Account.Acc;
-using Ryujinx.Ui.App.Common;
-using Ryujinx.Ui.Common.Helper;
+using Ryujinx.UI.App.Common;
+using Ryujinx.UI.Common.Helper;
using System;
using System.Buffers;
using System.IO;
diff --git a/src/Ryujinx.Ava/Common/KeyboardHotkeyState.cs b/src/Ryujinx.Ava/Common/KeyboardHotkeyState.cs
index b24016404..6e4920988 100644
--- a/src/Ryujinx.Ava/Common/KeyboardHotkeyState.cs
+++ b/src/Ryujinx.Ava/Common/KeyboardHotkeyState.cs
@@ -5,7 +5,7 @@ namespace Ryujinx.Ava.Common
None,
ToggleVSync,
Screenshot,
- ShowUi,
+ ShowUI,
Pause,
ToggleMute,
ResScaleUp,
diff --git a/src/Ryujinx.Ava/Common/Locale/LocaleManager.cs b/src/Ryujinx.Ava/Common/Locale/LocaleManager.cs
index 0e613838d..b2f3e7ab9 100644
--- a/src/Ryujinx.Ava/Common/Locale/LocaleManager.cs
+++ b/src/Ryujinx.Ava/Common/Locale/LocaleManager.cs
@@ -1,7 +1,7 @@
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Common;
using Ryujinx.Common.Utilities;
-using Ryujinx.Ui.Common.Configuration;
+using Ryujinx.UI.Common.Configuration;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -38,9 +38,9 @@ namespace Ryujinx.Ava.Common.Locale
// If the view is loaded with the UI Previewer detached, then override it with the saved one or default.
if (Program.PreviewerDetached)
{
- if (!string.IsNullOrEmpty(ConfigurationState.Instance.Ui.LanguageCode.Value))
+ if (!string.IsNullOrEmpty(ConfigurationState.Instance.UI.LanguageCode.Value))
{
- localeLanguageCode = ConfigurationState.Instance.Ui.LanguageCode.Value;
+ localeLanguageCode = ConfigurationState.Instance.UI.LanguageCode.Value;
}
else
{
diff --git a/src/Ryujinx.Ava/Modules/Updater/Updater.cs b/src/Ryujinx.Ava/Modules/Updater/Updater.cs
index af7608d34..bd211fa5b 100644
--- a/src/Ryujinx.Ava/Modules/Updater/Updater.cs
+++ b/src/Ryujinx.Ava/Modules/Updater/Updater.cs
@@ -10,8 +10,8 @@ using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities;
-using Ryujinx.Ui.Common.Helper;
-using Ryujinx.Ui.Common.Models.Github;
+using Ryujinx.UI.Common.Helper;
+using Ryujinx.UI.Common.Models.Github;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -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..7751bb520 100644
--- a/src/Ryujinx.Ava/Program.cs
+++ b/src/Ryujinx.Ava/Program.cs
@@ -9,10 +9,10 @@ using Ryujinx.Common.Logging;
using Ryujinx.Common.SystemInterop;
using Ryujinx.Modules;
using Ryujinx.SDL2.Common;
-using Ryujinx.Ui.Common;
-using Ryujinx.Ui.Common.Configuration;
-using Ryujinx.Ui.Common.Helper;
-using Ryujinx.Ui.Common.SystemInfo;
+using Ryujinx.UI.Common;
+using Ryujinx.UI.Common.Configuration;
+using Ryujinx.UI.Common.Helper;
+using Ryujinx.UI.Common.SystemInfo;
using System;
using System.IO;
using System.Runtime.InteropServices;
@@ -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 b6d37a2f1..91c2744f0 100644
--- a/src/Ryujinx.Ava/Ryujinx.Ava.csproj
+++ b/src/Ryujinx.Ava/Ryujinx.Ava.csproj
@@ -43,14 +43,13 @@
-
-
+
-
+
@@ -74,12 +73,12 @@
-
-
+
+
-
+
Always
alsoft.ini
@@ -93,7 +92,7 @@
-
+
Always
@@ -104,7 +103,7 @@
-
+
Designer
diff --git a/src/Ryujinx.Ava/UI/Applet/AvaHostUiHandler.cs b/src/Ryujinx.Ava/UI/Applet/AvaHostUIHandler.cs
similarity index 94%
rename from src/Ryujinx.Ava/UI/Applet/AvaHostUiHandler.cs
rename to src/Ryujinx.Ava/UI/Applet/AvaHostUIHandler.cs
index e11939104..4bcc35a7a 100644
--- a/src/Ryujinx.Ava/UI/Applet/AvaHostUiHandler.cs
+++ b/src/Ryujinx.Ava/UI/Applet/AvaHostUIHandler.cs
@@ -8,26 +8,26 @@ using Ryujinx.Ava.UI.Windows;
using Ryujinx.HLE;
using Ryujinx.HLE.HOS.Applets;
using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.Types;
-using Ryujinx.HLE.Ui;
+using Ryujinx.HLE.UI;
using System;
using System.Threading;
namespace Ryujinx.Ava.UI.Applet
{
- internal class AvaHostUiHandler : IHostUiHandler
+ internal class AvaHostUIHandler : IHostUIHandler
{
private readonly MainWindow _parent;
- public IHostUiTheme HostUiTheme { get; }
+ public IHostUITheme HostUITheme { get; }
- public AvaHostUiHandler(MainWindow parent)
+ public AvaHostUIHandler(MainWindow parent)
{
_parent = parent;
- HostUiTheme = new AvaloniaHostUiTheme(parent);
+ HostUITheme = new AvaloniaHostUITheme(parent);
}
- public bool DisplayMessageDialog(ControllerAppletUiArgs args)
+ public bool DisplayMessageDialog(ControllerAppletUIArgs args)
{
ManualResetEvent dialogCloseEvent = new(false);
@@ -110,7 +110,7 @@ namespace Ryujinx.Ava.UI.Applet
return okPressed;
}
- public bool DisplayInputDialog(SoftwareKeyboardUiArgs args, out string userText)
+ public bool DisplayInputDialog(SoftwareKeyboardUIArgs args, out string userText)
{
ManualResetEvent dialogCloseEvent = new(false);
diff --git a/src/Ryujinx.Ava/UI/Applet/AvaloniaDynamicTextInputHandler.cs b/src/Ryujinx.Ava/UI/Applet/AvaloniaDynamicTextInputHandler.cs
index 2411659f7..531d00611 100644
--- a/src/Ryujinx.Ava/UI/Applet/AvaloniaDynamicTextInputHandler.cs
+++ b/src/Ryujinx.Ava/UI/Applet/AvaloniaDynamicTextInputHandler.cs
@@ -5,7 +5,7 @@ using Avalonia.Threading;
using Ryujinx.Ava.Input;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Windows;
-using Ryujinx.HLE.Ui;
+using Ryujinx.HLE.UI;
using System;
using System.Threading;
using HidKey = Ryujinx.Common.Configuration.Hid.Key;
diff --git a/src/Ryujinx.Ava/UI/Applet/AvaloniaHostUiTheme.cs b/src/Ryujinx.Ava/UI/Applet/AvaloniaHostUITheme.cs
similarity index 92%
rename from src/Ryujinx.Ava/UI/Applet/AvaloniaHostUiTheme.cs
rename to src/Ryujinx.Ava/UI/Applet/AvaloniaHostUITheme.cs
index 4ee177d72..016fb4842 100644
--- a/src/Ryujinx.Ava/UI/Applet/AvaloniaHostUiTheme.cs
+++ b/src/Ryujinx.Ava/UI/Applet/AvaloniaHostUITheme.cs
@@ -1,13 +1,13 @@
using Avalonia.Media;
using Ryujinx.Ava.UI.Windows;
-using Ryujinx.HLE.Ui;
+using Ryujinx.HLE.UI;
using System;
namespace Ryujinx.Ava.UI.Applet
{
- class AvaloniaHostUiTheme : IHostUiTheme
+ class AvaloniaHostUITheme : IHostUITheme
{
- public AvaloniaHostUiTheme(MainWindow parent)
+ public AvaloniaHostUITheme(MainWindow parent)
{
FontFamily = OperatingSystem.IsWindows() && OperatingSystem.IsWindowsVersionAtLeast(10, 0, 22000) ? "Segoe UI Variable" : parent.FontFamily.Name;
DefaultBackgroundColor = BrushToThemeColor(parent.Background);
diff --git a/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs b/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs
index 34de5223b..279af07c3 100644
--- a/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs
@@ -9,6 +9,7 @@ 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;
@@ -35,7 +36,7 @@ namespace Ryujinx.Ava.UI.Applet
private readonly MainWindow _mainWindow;
- public ControllerAppletDialog(MainWindow mainWindow, ControllerAppletUiArgs args)
+ public ControllerAppletDialog(MainWindow mainWindow, ControllerAppletUIArgs args)
{
if (args.PlayerCountMin == args.PlayerCountMax)
{
@@ -68,7 +69,7 @@ namespace Ryujinx.Ava.UI.Applet
InitializeComponent();
}
- public static async Task ShowControllerAppletDialog(MainWindow window, ControllerAppletUiArgs args)
+ public static async Task ShowControllerAppletDialog(MainWindow window, ControllerAppletUIArgs args)
{
ContentDialog contentDialog = new();
UserResult result = UserResult.Cancel;
@@ -103,7 +104,7 @@ namespace Ryujinx.Ava.UI.Applet
if (!string.IsNullOrWhiteSpace(path))
{
- SvgSource source = new();
+ SvgSource source = new(default(Uri));
source.Load(EmbeddedResources.GetStream(path));
diff --git a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml b/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml
index 6186b7d93..51f370519 100644
--- a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml
+++ b/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml
@@ -34,7 +34,7 @@
Height="80"
MinWidth="50"
Margin="5,10,20,10"
- Source="resm:Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.Ui.Common" />
+ Source="resm:Ryujinx.UI.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.UI.Common" />
+ Source="resm:Ryujinx.UI.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.UI.Common" />
ShowInputDialog(string title, SoftwareKeyboardUiArgs args)
+ public static async Task<(UserResult Result, string Input)> ShowInputDialog(string title, SoftwareKeyboardUIArgs args)
{
ContentDialog contentDialog = new();
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml b/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml
index b8fe7e76f..dd0926fc9 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}}" />
+
+
-
+ VerticalAlignment="Top"
+ Orientation="Horizontal" />
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs b/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs
index 821d6fd9f..ee15bc8d5 100644
--- a/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs
@@ -3,7 +3,7 @@ using Avalonia.Input;
using Avalonia.Interactivity;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.Ui.App.Common;
+using Ryujinx.UI.App.Common;
using System;
namespace Ryujinx.Ava.UI.Controls
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs
index dd60503af..8681158ff 100644
--- a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs
@@ -3,7 +3,7 @@ using Avalonia.Input;
using Avalonia.Interactivity;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.Ui.App.Common;
+using Ryujinx.UI.App.Common;
using System;
namespace Ryujinx.Ava.UI.Controls
diff --git a/src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml b/src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml
index c5041230d..09fa04045 100644
--- a/src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml
+++ b/src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml
@@ -26,7 +26,7 @@
Height="70"
MinWidth="50"
Margin="5,10,20,10"
- Source="resm:Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.Ui.Common" />
+ Source="resm:Ryujinx.UI.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.UI.Common" />
-
\ No newline at end of file
+
diff --git a/src/Ryujinx.Ava/UI/Helpers/ApplicationOpenedEventArgs.cs b/src/Ryujinx.Ava/UI/Helpers/ApplicationOpenedEventArgs.cs
index cd63a99b0..bc5622b54 100644
--- a/src/Ryujinx.Ava/UI/Helpers/ApplicationOpenedEventArgs.cs
+++ b/src/Ryujinx.Ava/UI/Helpers/ApplicationOpenedEventArgs.cs
@@ -1,5 +1,5 @@
using Avalonia.Interactivity;
-using Ryujinx.Ui.App.Common;
+using Ryujinx.UI.App.Common;
namespace Ryujinx.Ava.UI.Helpers
{
diff --git a/src/Ryujinx.Ava/UI/Helpers/ContentDialogHelper.cs b/src/Ryujinx.Ava/UI/Helpers/ContentDialogHelper.cs
index a57deb1a0..15b7ddd14 100644
--- a/src/Ryujinx.Ava/UI/Helpers/ContentDialogHelper.cs
+++ b/src/Ryujinx.Ava/UI/Helpers/ContentDialogHelper.cs
@@ -336,6 +336,11 @@ namespace Ryujinx.Ava.UI.Helpers
void OverlayOnPositionChanged(object sender, PixelPointEventArgs e)
{
+ if (_contentDialogOverlayWindow is null)
+ {
+ return;
+ }
+
_contentDialogOverlayWindow.Position = parent.PointToScreen(new Point());
}
@@ -378,7 +383,7 @@ namespace Ryujinx.Ava.UI.Helpers
{
result = ContentDialogResult.None;
- Logger.Warning?.Print(LogClass.Ui, "Content dialog overlay failed to populate. Default value has been returned.");
+ Logger.Warning?.Print(LogClass.UI, "Content dialog overlay failed to populate. Default value has been returned.");
}
return result;
@@ -388,6 +393,7 @@ namespace Ryujinx.Ava.UI.Helpers
{
_contentDialogOverlayWindow.Content = null;
_contentDialogOverlayWindow.Close();
+ _contentDialogOverlayWindow = null;
}
return result;
diff --git a/src/Ryujinx.Ava/UI/Helpers/LocalizedNeverConverter.cs b/src/Ryujinx.Ava/UI/Helpers/LocalizedNeverConverter.cs
index b61a924f4..26fe36c4c 100644
--- a/src/Ryujinx.Ava/UI/Helpers/LocalizedNeverConverter.cs
+++ b/src/Ryujinx.Ava/UI/Helpers/LocalizedNeverConverter.cs
@@ -1,7 +1,7 @@
using Avalonia.Data.Converters;
using Avalonia.Markup.Xaml;
using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ui.Common.Helper;
+using Ryujinx.UI.Common.Helper;
using System;
using System.Globalization;
diff --git a/src/Ryujinx.Ava/UI/Helpers/LoggerAdapter.cs b/src/Ryujinx.Ava/UI/Helpers/LoggerAdapter.cs
index 0b1789880..fc7145410 100644
--- a/src/Ryujinx.Ava/UI/Helpers/LoggerAdapter.cs
+++ b/src/Ryujinx.Ava/UI/Helpers/LoggerAdapter.cs
@@ -39,12 +39,12 @@ namespace Ryujinx.Ava.UI.Helpers
public void Log(AvaLogLevel level, string area, object source, string messageTemplate)
{
- GetLog(level)?.PrintMsg(RyuLogClass.Ui, Format(level, area, messageTemplate, source, null));
+ GetLog(level)?.PrintMsg(RyuLogClass.UI, Format(level, area, messageTemplate, source, null));
}
public void Log(AvaLogLevel level, string area, object source, string messageTemplate, params object[] propertyValues)
{
- GetLog(level)?.PrintMsg(RyuLogClass.Ui, Format(level, area, messageTemplate, source, propertyValues));
+ GetLog(level)?.PrintMsg(RyuLogClass.UI, Format(level, area, messageTemplate, source, propertyValues));
}
private static string Format(AvaLogLevel level, string area, string template, object source, object[] v)
diff --git a/src/Ryujinx.Ava/UI/Helpers/UserErrorDialog.cs b/src/Ryujinx.Ava/UI/Helpers/UserErrorDialog.cs
index fc82bd6b1..9a44b862b 100644
--- a/src/Ryujinx.Ava/UI/Helpers/UserErrorDialog.cs
+++ b/src/Ryujinx.Ava/UI/Helpers/UserErrorDialog.cs
@@ -1,6 +1,6 @@
using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ui.Common;
-using Ryujinx.Ui.Common.Helper;
+using Ryujinx.UI.Common;
+using Ryujinx.UI.Common.Helper;
using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Helpers
diff --git a/src/Ryujinx.Ava/UI/Models/Generic/LastPlayedSortComparer.cs b/src/Ryujinx.Ava/UI/Models/Generic/LastPlayedSortComparer.cs
index 8340d39df..224f78f45 100644
--- a/src/Ryujinx.Ava/UI/Models/Generic/LastPlayedSortComparer.cs
+++ b/src/Ryujinx.Ava/UI/Models/Generic/LastPlayedSortComparer.cs
@@ -1,4 +1,4 @@
-using Ryujinx.Ui.App.Common;
+using Ryujinx.UI.App.Common;
using System;
using System.Collections.Generic;
diff --git a/src/Ryujinx.Ava/UI/Models/Generic/TimePlayedSortComparer.cs b/src/Ryujinx.Ava/UI/Models/Generic/TimePlayedSortComparer.cs
index d53ff566f..f0fb035d1 100644
--- a/src/Ryujinx.Ava/UI/Models/Generic/TimePlayedSortComparer.cs
+++ b/src/Ryujinx.Ava/UI/Models/Generic/TimePlayedSortComparer.cs
@@ -1,4 +1,4 @@
-using Ryujinx.Ui.App.Common;
+using Ryujinx.UI.App.Common;
using System;
using System.Collections.Generic;
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/SaveModel.cs b/src/Ryujinx.Ava/UI/Models/SaveModel.cs
index 7b476932b..d6dea2f69 100644
--- a/src/Ryujinx.Ava/UI/Models/SaveModel.cs
+++ b/src/Ryujinx.Ava/UI/Models/SaveModel.cs
@@ -3,8 +3,8 @@ using LibHac.Ncm;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.HLE.FileSystem;
-using Ryujinx.Ui.App.Common;
-using Ryujinx.Ui.Common.Helper;
+using Ryujinx.UI.App.Common;
+using Ryujinx.UI.Common.Helper;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
diff --git a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs b/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs
index fa55c8d3f..3bf19b43e 100644
--- a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs
+++ b/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs
@@ -3,8 +3,8 @@ using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Platform;
using Ryujinx.Common.Configuration;
-using Ryujinx.Ui.Common.Configuration;
-using Ryujinx.Ui.Common.Helper;
+using Ryujinx.UI.Common.Configuration;
+using Ryujinx.UI.Common.Helper;
using SPB.Graphics;
using SPB.Platform;
using SPB.Platform.GLX;
diff --git a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowOpenGL.cs b/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowOpenGL.cs
index 769a1c91a..3842301de 100644
--- a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowOpenGL.cs
+++ b/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowOpenGL.cs
@@ -3,7 +3,7 @@ using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.OpenGL;
-using Ryujinx.Ui.Common.Configuration;
+using Ryujinx.UI.Common.Configuration;
using SPB.Graphics;
using SPB.Graphics.Exceptions;
using SPB.Graphics.OpenGL;
@@ -75,7 +75,7 @@ namespace Ryujinx.Ava.UI.Renderer
throw;
}
- Logger.Warning?.Print(LogClass.Ui, $"Failed to {(!unbind ? "bind" : "unbind")} OpenGL context: {e}");
+ Logger.Warning?.Print(LogClass.UI, $"Failed to {(!unbind ? "bind" : "unbind")} OpenGL context: {e}");
}
}
diff --git a/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml.cs b/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml.cs
index 12c18e4a7..d055d9ea4 100644
--- a/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml.cs
@@ -1,7 +1,7 @@
using Avalonia;
using Avalonia.Controls;
using Ryujinx.Common.Configuration;
-using Ryujinx.Ui.Common.Configuration;
+using Ryujinx.UI.Common.Configuration;
using System;
namespace Ryujinx.Ava.UI.Renderer
diff --git a/src/Ryujinx.Ava/UI/Renderer/SPBOpenGLContext.cs b/src/Ryujinx.Ava/UI/Renderer/SPBOpenGLContext.cs
index 5ff756f24..63bf6cf7c 100644
--- a/src/Ryujinx.Ava/UI/Renderer/SPBOpenGLContext.cs
+++ b/src/Ryujinx.Ava/UI/Renderer/SPBOpenGLContext.cs
@@ -29,6 +29,8 @@ namespace Ryujinx.Ava.UI.Renderer
_context.MakeCurrent(_window);
}
+ public bool HasContext() => _context.IsCurrent;
+
public static SPBOpenGLContext CreateBackgroundContext(OpenGLContextBase sharedContext)
{
OpenGLContextBase context = PlatformHelper.CreateOpenGLContext(FramebufferFormat.Default, 3, 3, OpenGLContextFlags.Compat, true, sharedContext);
diff --git a/src/Ryujinx.Ava/UI/ViewModels/AboutWindowViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/AboutWindowViewModel.cs
index 70ede4c12..6020f40e0 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/AboutWindowViewModel.cs
+++ b/src/Ryujinx.Ava/UI/ViewModels/AboutWindowViewModel.cs
@@ -3,7 +3,7 @@ using Avalonia.Platform;
using Avalonia.Threading;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Common.Utilities;
-using Ryujinx.Ui.Common.Configuration;
+using Ryujinx.UI.Common.Configuration;
using System;
using System.Net.Http;
using System.Net.NetworkInformation;
@@ -87,19 +87,19 @@ namespace Ryujinx.Ava.UI.ViewModels
{
Version = Program.Version;
- if (ConfigurationState.Instance.Ui.BaseStyle.Value == "Light")
+ if (ConfigurationState.Instance.UI.BaseStyle.Value == "Light")
{
- GithubLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_GitHub_Light.png?assembly=Ryujinx.Ui.Common")));
- DiscordLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_Discord_Light.png?assembly=Ryujinx.Ui.Common")));
- PatreonLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_Patreon_Light.png?assembly=Ryujinx.Ui.Common")));
- TwitterLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_Twitter_Light.png?assembly=Ryujinx.Ui.Common")));
+ GithubLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_GitHub_Light.png?assembly=Ryujinx.UI.Common")));
+ DiscordLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Discord_Light.png?assembly=Ryujinx.UI.Common")));
+ PatreonLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Patreon_Light.png?assembly=Ryujinx.UI.Common")));
+ TwitterLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Twitter_Light.png?assembly=Ryujinx.UI.Common")));
}
else
{
- GithubLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_GitHub_Dark.png?assembly=Ryujinx.Ui.Common")));
- DiscordLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_Discord_Dark.png?assembly=Ryujinx.Ui.Common")));
- PatreonLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_Patreon_Dark.png?assembly=Ryujinx.Ui.Common")));
- TwitterLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_Twitter_Dark.png?assembly=Ryujinx.Ui.Common")));
+ GithubLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_GitHub_Dark.png?assembly=Ryujinx.UI.Common")));
+ DiscordLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Discord_Dark.png?assembly=Ryujinx.UI.Common")));
+ PatreonLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Patreon_Dark.png?assembly=Ryujinx.UI.Common")));
+ TwitterLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Twitter_Dark.png?assembly=Ryujinx.UI.Common")));
}
Dispatcher.UIThread.InvokeAsync(DownloadPatronsJson);
diff --git a/src/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs
index 0e0d858a4..8f09568a6 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs
+++ b/src/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs
@@ -9,7 +9,7 @@ using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities;
-using Ryujinx.Ui.Common.Models.Amiibo;
+using Ryujinx.UI.Common.Models.Amiibo;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@@ -65,7 +65,7 @@ namespace Ryujinx.Ava.UI.ViewModels
_amiiboSeries = new ObservableCollection();
_amiibos = new AvaloniaList();
- _amiiboLogoBytes = EmbeddedResources.Read("Ryujinx.Ui.Common/Resources/Logo_Amiibo.png");
+ _amiiboLogoBytes = EmbeddedResources.Read("Ryujinx.UI.Common/Resources/Logo_Amiibo.png");
_ = LoadContentAsync();
}
diff --git a/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs
index c0c625321..71ad2c127 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs
+++ b/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs
@@ -19,7 +19,7 @@ using Ryujinx.Common.Configuration.Hid.Keyboard;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities;
using Ryujinx.Input;
-using Ryujinx.Ui.Common.Configuration;
+using Ryujinx.UI.Common.Configuration;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@@ -35,10 +35,10 @@ namespace Ryujinx.Ava.UI.ViewModels
public class ControllerInputViewModel : BaseModel, IDisposable
{
private const string Disabled = "disabled";
- private const string ProControllerResource = "Ryujinx.Ui.Common/Resources/Controller_ProCon.svg";
- private const string JoyConPairResource = "Ryujinx.Ui.Common/Resources/Controller_JoyConPair.svg";
- private const string JoyConLeftResource = "Ryujinx.Ui.Common/Resources/Controller_JoyConLeft.svg";
- private const string JoyConRightResource = "Ryujinx.Ui.Common/Resources/Controller_JoyConRight.svg";
+ private const string ProControllerResource = "Ryujinx.UI.Common/Resources/Controller_ProCon.svg";
+ private const string JoyConPairResource = "Ryujinx.UI.Common/Resources/Controller_JoyConPair.svg";
+ private const string JoyConLeftResource = "Ryujinx.UI.Common/Resources/Controller_JoyConLeft.svg";
+ private const string JoyConRightResource = "Ryujinx.UI.Common/Resources/Controller_JoyConRight.svg";
private const string KeyboardString = "keyboard";
private const string ControllerString = "controller";
private readonly MainWindow _mainWindow;
@@ -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 7146dfd7c..17bd69b14 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs
+++ b/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs
@@ -25,13 +25,13 @@ using Ryujinx.HLE;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS;
using Ryujinx.HLE.HOS.Services.Account.Acc;
-using Ryujinx.HLE.Ui;
+using Ryujinx.HLE.UI;
using Ryujinx.Input.HLE;
using Ryujinx.Modules;
-using Ryujinx.Ui.App.Common;
-using Ryujinx.Ui.Common;
-using Ryujinx.Ui.Common.Configuration;
-using Ryujinx.Ui.Common.Helper;
+using Ryujinx.UI.App.Common;
+using Ryujinx.UI.Common;
+using Ryujinx.UI.Common.Configuration;
+using Ryujinx.UI.Common.Helper;
using SixLabors.ImageSharp.PixelFormats;
using System;
using System.Collections.Generic;
@@ -138,7 +138,7 @@ namespace Ryujinx.Ava.UI.ViewModels
InputManager inputManager,
UserChannelPersistence userChannelPersistence,
LibHacHorizonManager libHacHorizonManager,
- IHostUiHandler uiHandler,
+ IHostUIHandler uiHandler,
Action showLoading,
Action switchToGameControl,
Action setMainContent,
@@ -357,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
{
@@ -685,10 +685,10 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool StartGamesInFullscreen
{
- get => ConfigurationState.Instance.Ui.StartFullscreen;
+ get => ConfigurationState.Instance.UI.StartFullscreen;
set
{
- ConfigurationState.Instance.Ui.StartFullscreen.Value = value;
+ ConfigurationState.Instance.UI.StartFullscreen.Value = value;
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
@@ -698,10 +698,10 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool ShowConsole
{
- get => ConfigurationState.Instance.Ui.ShowConsole;
+ get => ConfigurationState.Instance.UI.ShowConsole;
set
{
- ConfigurationState.Instance.Ui.ShowConsole.Value = value;
+ ConfigurationState.Instance.UI.ShowConsole.Value = value;
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
@@ -743,10 +743,10 @@ namespace Ryujinx.Ava.UI.ViewModels
public Glyph Glyph
{
- get => (Glyph)ConfigurationState.Instance.Ui.GameListViewMode.Value;
+ get => (Glyph)ConfigurationState.Instance.UI.GameListViewMode.Value;
set
{
- ConfigurationState.Instance.Ui.GameListViewMode.Value = (int)value;
+ ConfigurationState.Instance.UI.GameListViewMode.Value = (int)value;
OnPropertyChanged();
OnPropertyChanged(nameof(IsGrid));
@@ -758,9 +758,9 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool ShowNames
{
- get => ConfigurationState.Instance.Ui.ShowNames && ConfigurationState.Instance.Ui.GridSize > 1; set
+ get => ConfigurationState.Instance.UI.ShowNames && ConfigurationState.Instance.UI.GridSize > 1; set
{
- ConfigurationState.Instance.Ui.ShowNames.Value = value;
+ ConfigurationState.Instance.UI.ShowNames.Value = value;
OnPropertyChanged();
OnPropertyChanged(nameof(GridSizeScale));
@@ -772,10 +772,10 @@ namespace Ryujinx.Ava.UI.ViewModels
internal ApplicationSort SortMode
{
- get => (ApplicationSort)ConfigurationState.Instance.Ui.ApplicationSort.Value;
+ get => (ApplicationSort)ConfigurationState.Instance.UI.ApplicationSort.Value;
private set
{
- ConfigurationState.Instance.Ui.ApplicationSort.Value = (int)value;
+ ConfigurationState.Instance.UI.ApplicationSort.Value = (int)value;
OnPropertyChanged();
OnPropertyChanged(nameof(SortName));
@@ -788,7 +788,7 @@ namespace Ryujinx.Ava.UI.ViewModels
{
get
{
- return ConfigurationState.Instance.Ui.GridSize.Value switch
+ return ConfigurationState.Instance.UI.GridSize.Value switch
{
1 => 78,
2 => 100,
@@ -803,7 +803,7 @@ namespace Ryujinx.Ava.UI.ViewModels
{
get
{
- return ConfigurationState.Instance.Ui.GridSize.Value switch
+ return ConfigurationState.Instance.UI.GridSize.Value switch
{
1 => 120,
2 => ShowNames ? 210 : 150,
@@ -816,10 +816,10 @@ namespace Ryujinx.Ava.UI.ViewModels
public int GridSizeScale
{
- get => ConfigurationState.Instance.Ui.GridSize;
+ get => ConfigurationState.Instance.UI.GridSize;
set
{
- ConfigurationState.Instance.Ui.GridSize.Value = value;
+ ConfigurationState.Instance.UI.GridSize.Value = value;
if (value < 2)
{
@@ -860,10 +860,10 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool IsAscending
{
- get => ConfigurationState.Instance.Ui.IsAscendingOrder;
+ get => ConfigurationState.Instance.UI.IsAscendingOrder;
private set
{
- ConfigurationState.Instance.Ui.IsAscendingOrder.Value = value;
+ ConfigurationState.Instance.UI.IsAscendingOrder.Value = value;
OnPropertyChanged();
OnPropertyChanged(nameof(SortMode));
@@ -919,7 +919,7 @@ namespace Ryujinx.Ava.UI.ViewModels
public RendererHost RendererHostControl { get; private set; }
public bool IsClosing { get; set; }
public LibHacHorizonManager LibHacHorizonManager { get; internal set; }
- public IHostUiHandler UiHandler { get; internal set; }
+ public IHostUIHandler UiHandler { get; internal set; }
public bool IsSortedByFavorite => SortMode == ApplicationSort.Favorite;
public bool IsSortedByTitle => SortMode == ApplicationSort.Title;
public bool IsSortedByDeveloper => SortMode == ApplicationSort.Developer;
@@ -928,10 +928,10 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool IsSortedByType => SortMode == ApplicationSort.FileType;
public bool IsSortedBySize => SortMode == ApplicationSort.FileSize;
public bool IsSortedByPath => SortMode == ApplicationSort.Path;
- public bool IsGridSmall => ConfigurationState.Instance.Ui.GridSize == 1;
- public bool IsGridMedium => ConfigurationState.Instance.Ui.GridSize == 2;
- public bool IsGridLarge => ConfigurationState.Instance.Ui.GridSize == 3;
- public bool IsGridHuge => ConfigurationState.Instance.Ui.GridSize == 4;
+ public bool IsGridSmall => ConfigurationState.Instance.UI.GridSize == 1;
+ public bool IsGridMedium => ConfigurationState.Instance.UI.GridSize == 2;
+ public bool IsGridLarge => ConfigurationState.Instance.UI.GridSize == 3;
+ public bool IsGridHuge => ConfigurationState.Instance.UI.GridSize == 4;
#endregion
@@ -1245,7 +1245,7 @@ namespace Ryujinx.Ava.UI.ViewModels
public void LoadConfigurableHotKeys()
{
- if (AvaloniaKeyboardMappingHelper.TryGetAvaKey((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ShowUi, out var showUiKey))
+ if (AvaloniaKeyboardMappingHelper.TryGetAvaKey((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ShowUI, out var showUiKey))
{
ShowUiKey = new KeyGesture(showUiKey);
}
@@ -1350,11 +1350,11 @@ namespace Ryujinx.Ava.UI.ViewModels
public void OpenLogsFolder()
{
- string logPath = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "Logs");
-
- new DirectoryInfo(logPath).Create();
-
- OpenHelper.OpenFolder(logPath);
+ string logPath = AppDataManager.GetOrCreateLogsDir();
+ if (!string.IsNullOrEmpty(logPath))
+ {
+ OpenHelper.OpenFolder(logPath);
+ }
}
public void ToggleDockMode()
@@ -1385,7 +1385,7 @@ namespace Ryujinx.Ava.UI.ViewModels
if (Program.PreviewerDetached)
{
- ConfigurationState.Instance.Ui.LanguageCode.Value = (string)languageCode;
+ ConfigurationState.Instance.UI.LanguageCode.Value = (string)languageCode;
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
}
}
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 604e34067..bcaa08600 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs
+++ b/src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs
@@ -16,8 +16,8 @@ using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Vulkan;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Services.Time.TimeZone;
-using Ryujinx.Ui.Common.Configuration;
-using Ryujinx.Ui.Common.Configuration.System;
+using Ryujinx.UI.Common.Configuration;
+using Ryujinx.UI.Common.Configuration.System;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@@ -48,7 +48,6 @@ namespace Ryujinx.Ava.UI.ViewModels
private readonly List _gpuIds = new();
private KeyboardHotkeys _keyboardHotkeys;
private int _graphicsBackendIndex;
- private string _customThemePath;
private int _scalingFilter;
private int _scalingFilterLevel;
@@ -160,7 +159,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;
@@ -170,20 +168,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; }
@@ -424,11 +408,9 @@ namespace Ryujinx.Ava.UI.ViewModels
HideCursor = (int)config.HideCursor.Value;
GameDirectories.Clear();
- GameDirectories.AddRange(config.Ui.GameDirs.Value);
+ GameDirectories.AddRange(config.UI.GameDirs.Value);
- EnableCustomTheme = config.Ui.EnableCustomTheme;
- CustomThemePath = config.Ui.CustomThemePath;
- BaseStyleIndex = config.Ui.BaseStyle == "Light" ? 0 : 1;
+ BaseStyleIndex = config.UI.BaseStyle == "Light" ? 0 : 1;
// Input
EnableDockedMode = config.System.EnableDockedMode;
@@ -512,12 +494,10 @@ namespace Ryujinx.Ava.UI.ViewModels
if (_directoryChanged)
{
List gameDirs = new(GameDirectories);
- config.Ui.GameDirs.Value = gameDirs;
+ config.UI.GameDirs.Value = gameDirs;
}
- config.Ui.EnableCustomTheme.Value = EnableCustomTheme;
- config.Ui.CustomThemePath.Value = CustomThemePath;
- config.Ui.BaseStyle.Value = BaseStyleIndex == 0 ? "Light" : "Dark";
+ config.UI.BaseStyle.Value = BaseStyleIndex == 0 ? "Light" : "Dark";
// Input
config.System.EnableDockedMode.Value = EnableDockedMode;
diff --git a/src/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs
index 5090a8c70..5989ce09a 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs
+++ b/src/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs
@@ -17,7 +17,7 @@ using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities;
using Ryujinx.HLE.FileSystem;
-using Ryujinx.Ui.App.Common;
+using Ryujinx.UI.App.Common;
using System;
using System.Collections.Generic;
using System.IO;
@@ -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/Views/Main/MainMenuBarView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs
index 439c6fcc6..0fdad7679 100644
--- a/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs
@@ -10,9 +10,9 @@ using Ryujinx.Ava.UI.Windows;
using Ryujinx.Common;
using Ryujinx.Common.Utilities;
using Ryujinx.Modules;
-using Ryujinx.Ui.Common;
-using Ryujinx.Ui.Common.Configuration;
-using Ryujinx.Ui.Common.Helper;
+using Ryujinx.UI.Common;
+using Ryujinx.UI.Common.Configuration;
+using Ryujinx.UI.Common.Helper;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -44,7 +44,7 @@ namespace Ryujinx.Ava.UI.Views.Main
checkBoxes.Add(new CheckBox
{
Content = $".{fileName}",
- IsChecked = ((FileTypes)item).GetConfigValue(ConfigurationState.Instance.Ui.ShownFileTypes),
+ IsChecked = ((FileTypes)item).GetConfigValue(ConfigurationState.Instance.UI.ShownFileTypes),
Command = MiniCommand.Create(() => Window.ToggleFileType(fileName)),
});
}
diff --git a/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml.cs
index 822045d44..239a7cbfc 100644
--- a/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml.cs
@@ -5,7 +5,7 @@ using Avalonia.Interactivity;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
-using Ryujinx.Ui.Common.Configuration;
+using Ryujinx.UI.Common.Configuration;
using System;
namespace Ryujinx.Ava.UI.Views.Main
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml
index a53c1dfe4..b4eae01ef 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml
@@ -45,7 +45,7 @@
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml
index b7471d385..6504637e6 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml
@@ -36,7 +36,7 @@
-
+
@@ -54,6 +54,22 @@
+
+
+
+
+
+
+
+
+
+
+
@@ -106,64 +122,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml.cs
index 6d9299dda..996d15cdb 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml.cs
@@ -61,29 +61,5 @@ namespace Ryujinx.Ava.UI.Views.Settings
GameList.SelectedIndex = oldIndex < GameList.ItemCount ? oldIndex : 0;
}
}
-
- public async void BrowseTheme(object sender, RoutedEventArgs e)
- {
- var window = this.GetVisualRoot() as Window;
- var result = await window.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
- {
- Title = LocaleManager.Instance[LocaleKeys.SettingsSelectThemeFileDialogTitle],
- AllowMultiple = false,
- FileTypeFilter = new List
- {
- new("xml")
- {
- Patterns = new[] { "*.xaml" },
- AppleUniformTypeIdentifiers = new[] { "com.ryujinx.xaml" },
- MimeTypes = new[] { "application/xaml+xml" },
- },
- },
- });
-
- if (result.Count > 0)
- {
- ViewModel.CustomThemePath = result[0].Path.LocalPath;
- }
- }
}
}
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml b/src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml
index 818a21d69..3a9de3039 100644
--- a/src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml
@@ -4,7 +4,6 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:flex="clr-namespace:Avalonia.Flexbox;assembly=Avalonia.Flexbox"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
xmlns:models="clr-namespace:Ryujinx.Ava.UI.Models"
@@ -40,11 +39,10 @@
ItemsSource="{Binding Profiles}">
-
+
@@ -161,4 +159,4 @@
Content="{locale:Locale UserProfilesClose}" />
-
\ No newline at end of file
+
diff --git a/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml b/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml
index a0fd2a1ac..69fa82517 100644
--- a/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml
+++ b/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml
@@ -3,7 +3,6 @@
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:flex="clr-namespace:Avalonia.Flexbox;assembly=Avalonia.Flexbox"
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
@@ -45,33 +44,37 @@
-
-
-
+
+
-
-
+ Orientation="Vertical">
+
+
+
+
- {
- 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);
@@ -331,13 +319,13 @@ namespace Ryujinx.Ava.UI.Windows
private void SetWindowSizePosition()
{
- PixelPoint savedPoint = new(ConfigurationState.Instance.Ui.WindowStartup.WindowPositionX,
- ConfigurationState.Instance.Ui.WindowStartup.WindowPositionY);
+ PixelPoint savedPoint = new(ConfigurationState.Instance.UI.WindowStartup.WindowPositionX,
+ ConfigurationState.Instance.UI.WindowStartup.WindowPositionY);
- ViewModel.WindowHeight = ConfigurationState.Instance.Ui.WindowStartup.WindowSizeHeight * Program.WindowScaleFactor;
- ViewModel.WindowWidth = ConfigurationState.Instance.Ui.WindowStartup.WindowSizeWidth * Program.WindowScaleFactor;
+ ViewModel.WindowHeight = ConfigurationState.Instance.UI.WindowStartup.WindowSizeHeight * Program.WindowScaleFactor;
+ ViewModel.WindowWidth = ConfigurationState.Instance.UI.WindowStartup.WindowSizeWidth * Program.WindowScaleFactor;
- ViewModel.WindowState = ConfigurationState.Instance.Ui.WindowStartup.WindowMaximized.Value ? WindowState.Maximized : WindowState.Normal;
+ ViewModel.WindowState = ConfigurationState.Instance.UI.WindowStartup.WindowMaximized.Value ? WindowState.Maximized : WindowState.Normal;
if (CheckScreenBounds(savedPoint))
{
@@ -365,13 +353,13 @@ namespace Ryujinx.Ava.UI.Windows
private void SaveWindowSizePosition()
{
- ConfigurationState.Instance.Ui.WindowStartup.WindowSizeHeight.Value = (int)Height;
- ConfigurationState.Instance.Ui.WindowStartup.WindowSizeWidth.Value = (int)Width;
+ ConfigurationState.Instance.UI.WindowStartup.WindowSizeHeight.Value = (int)Height;
+ ConfigurationState.Instance.UI.WindowStartup.WindowSizeWidth.Value = (int)Width;
- ConfigurationState.Instance.Ui.WindowStartup.WindowPositionX.Value = Position.X;
- ConfigurationState.Instance.Ui.WindowStartup.WindowPositionY.Value = Position.Y;
+ ConfigurationState.Instance.UI.WindowStartup.WindowPositionX.Value = Position.X;
+ ConfigurationState.Instance.UI.WindowStartup.WindowPositionY.Value = Position.Y;
- ConfigurationState.Instance.Ui.WindowStartup.WindowMaximized.Value = WindowState == WindowState.Maximized;
+ ConfigurationState.Instance.UI.WindowStartup.WindowMaximized.Value = WindowState == WindowState.Maximized;
MainWindowViewModel.SaveConfig();
}
@@ -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)
@@ -522,12 +512,12 @@ namespace Ryujinx.Ava.UI.Windows
_ = fileType switch
{
#pragma warning disable IDE0055 // Disable formatting
- "NSP" => ConfigurationState.Instance.Ui.ShownFileTypes.NSP.Value = !ConfigurationState.Instance.Ui.ShownFileTypes.NSP,
- "PFS0" => ConfigurationState.Instance.Ui.ShownFileTypes.PFS0.Value = !ConfigurationState.Instance.Ui.ShownFileTypes.PFS0,
- "XCI" => ConfigurationState.Instance.Ui.ShownFileTypes.XCI.Value = !ConfigurationState.Instance.Ui.ShownFileTypes.XCI,
- "NCA" => ConfigurationState.Instance.Ui.ShownFileTypes.NCA.Value = !ConfigurationState.Instance.Ui.ShownFileTypes.NCA,
- "NRO" => ConfigurationState.Instance.Ui.ShownFileTypes.NRO.Value = !ConfigurationState.Instance.Ui.ShownFileTypes.NRO,
- "NSO" => ConfigurationState.Instance.Ui.ShownFileTypes.NSO.Value = !ConfigurationState.Instance.Ui.ShownFileTypes.NSO,
+ "NSP" => ConfigurationState.Instance.UI.ShownFileTypes.NSP.Value = !ConfigurationState.Instance.UI.ShownFileTypes.NSP,
+ "PFS0" => ConfigurationState.Instance.UI.ShownFileTypes.PFS0.Value = !ConfigurationState.Instance.UI.ShownFileTypes.PFS0,
+ "XCI" => ConfigurationState.Instance.UI.ShownFileTypes.XCI.Value = !ConfigurationState.Instance.UI.ShownFileTypes.XCI,
+ "NCA" => ConfigurationState.Instance.UI.ShownFileTypes.NCA.Value = !ConfigurationState.Instance.UI.ShownFileTypes.NCA,
+ "NRO" => ConfigurationState.Instance.UI.ShownFileTypes.NRO.Value = !ConfigurationState.Instance.UI.ShownFileTypes.NRO,
+ "NSO" => ConfigurationState.Instance.UI.ShownFileTypes.NSO.Value = !ConfigurationState.Instance.UI.ShownFileTypes.NSO,
_ => throw new ArgumentOutOfRangeException(fileType),
#pragma warning restore IDE0055
};
@@ -547,7 +537,7 @@ namespace Ryujinx.Ava.UI.Windows
Thread applicationLibraryThread = new(() =>
{
- ApplicationLibrary.LoadApplications(ConfigurationState.Instance.Ui.GameDirs, ConfigurationState.Instance.System.Language);
+ ApplicationLibrary.LoadApplications(ConfigurationState.Instance.UI.GameDirs, ConfigurationState.Instance.System.Language);
_isLoading = false;
})
diff --git a/src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml b/src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml
new file mode 100644
index 000000000..0ed05ce3f
--- /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..d9ae0d4f3
--- /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/StyleableWindow.cs b/src/Ryujinx.Ava/UI/Windows/StyleableWindow.cs
index 3cd12bc8c..a12d2b3e8 100644
--- a/src/Ryujinx.Ava/UI/Windows/StyleableWindow.cs
+++ b/src/Ryujinx.Ava/UI/Windows/StyleableWindow.cs
@@ -4,7 +4,7 @@ using Avalonia.Media;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ui.Common.Configuration;
+using Ryujinx.UI.Common.Configuration;
using System.IO;
using System.Reflection;
@@ -19,7 +19,7 @@ namespace Ryujinx.Ava.UI.Windows
WindowStartupLocation = WindowStartupLocation.CenterOwner;
TransparencyLevelHint = new[] { WindowTransparencyLevel.None };
- using Stream stream = Assembly.GetAssembly(typeof(ConfigurationState)).GetManifestResourceStream("Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png");
+ using Stream stream = Assembly.GetAssembly(typeof(ConfigurationState)).GetManifestResourceStream("Ryujinx.UI.Common.Resources.Logo_Ryujinx.png");
Icon = new WindowIcon(stream);
stream.Position = 0;
diff --git a/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml.cs b/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml.cs
index 7ece63355..f3ac69600 100644
--- a/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml.cs
@@ -7,7 +7,7 @@ using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.HLE.FileSystem;
-using Ryujinx.Ui.Common.Helper;
+using Ryujinx.UI.Common.Helper;
using System.Threading.Tasks;
using Button = Avalonia.Controls.Button;
diff --git a/src/Ryujinx.Common/Configuration/AppDataManager.cs b/src/Ryujinx.Common/Configuration/AppDataManager.cs
index 2b4a594d3..f3df0fc9d 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";
@@ -29,6 +30,8 @@ namespace Ryujinx.Common.Configuration
public static string KeysDirPath { get; private set; }
public static string KeysDirPathUser { get; }
+ public static string LogsDirPath { get; private set; }
+
public const string DefaultNandDir = "bis";
public const string DefaultSdcardDir = "sdcard";
private const string DefaultModsDir = "mods";
@@ -45,15 +48,7 @@ namespace Ryujinx.Common.Configuration
public static void Initialize(string baseDirPath)
{
- string appDataPath;
- if (OperatingSystem.IsMacOS())
- {
- appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Library", "Application Support");
- }
- else
- {
- appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
- }
+ string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
if (appDataPath.Length == 0)
{
@@ -63,6 +58,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 +104,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);
}
}
@@ -107,50 +112,139 @@ namespace Ryujinx.Common.Configuration
SetupBasePaths();
}
+ public static string GetOrCreateLogsDir()
+ {
+ if (Directory.Exists(LogsDirPath))
+ {
+ return LogsDirPath;
+ }
+
+ Logger.Notice.Print(LogClass.Application, "Logging directory not found; attempting to create new logging directory.");
+ LogsDirPath = SetUpLogsDir();
+
+ return LogsDirPath;
+ }
+
+ private static string SetUpLogsDir()
+ {
+ string logDir = "";
+
+ if (Mode == LaunchMode.Portable)
+ {
+ logDir = Path.Combine(BaseDirPath, "Logs");
+ try
+ {
+ Directory.CreateDirectory(logDir);
+ }
+ catch
+ {
+ Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
+
+ return null;
+ }
+ }
+ else
+ {
+ if (OperatingSystem.IsMacOS())
+ {
+ // NOTE: Should evaluate to "~/Library/Logs/Ryujinx/".
+ logDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Library", "Logs", DefaultBaseDir);
+ try
+ {
+ Directory.CreateDirectory(logDir);
+ }
+ catch
+ {
+ Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
+ logDir = "";
+ }
+
+ if (string.IsNullOrEmpty(logDir))
+ {
+ // NOTE: Should evaluate to "~/Library/Application Support/Ryujinx/Logs".
+ logDir = Path.Combine(BaseDirPath, "Logs");
+
+ try
+ {
+ Directory.CreateDirectory(logDir);
+ }
+ catch
+ {
+ Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
+
+ return null;
+ }
+ }
+ }
+ else if (OperatingSystem.IsWindows())
+ {
+ // NOTE: Should evaluate to a "Logs" directory in whatever directory Ryujinx was launched from.
+ logDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
+ try
+ {
+ Directory.CreateDirectory(logDir);
+ }
+ catch
+ {
+ Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
+ logDir = "";
+ }
+
+ if (string.IsNullOrEmpty(logDir))
+ {
+ // NOTE: Should evaluate to "C:\Users\user\AppData\Roaming\Ryujinx\Logs".
+ logDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), DefaultBaseDir, "Logs");
+
+ try
+ {
+ Directory.CreateDirectory(logDir);
+ }
+ catch
+ {
+ Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
+
+ return null;
+ }
+ }
+ }
+ else if (OperatingSystem.IsLinux())
+ {
+ // NOTE: Should evaluate to "~/.config/Ryujinx/Logs".
+ logDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), DefaultBaseDir, "Logs");
+
+ try
+ {
+ Directory.CreateDirectory(logDir);
+ }
+ catch
+ {
+ Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
+
+ return null;
+ }
+ }
+ }
+
+ return logDir;
+ }
+
private static void SetupBasePaths()
{
Directory.CreateDirectory(BaseDirPath);
+ LogsDirPath = SetUpLogsDir();
Directory.CreateDirectory(GamesDirPath = Path.Combine(BaseDirPath, GamesDir));
Directory.CreateDirectory(ProfilesDirPath = Path.Combine(BaseDirPath, ProfilesDir));
Directory.CreateDirectory(KeysDirPath = Path.Combine(BaseDirPath, KeysDir));
}
// 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/Hid/KeyboardHotkeys.cs b/src/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs
index b4f2f9468..e9c163cf2 100644
--- a/src/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs
+++ b/src/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs
@@ -6,7 +6,7 @@ namespace Ryujinx.Common.Configuration.Hid
{
public Key ToggleVsync { get; set; }
public Key Screenshot { get; set; }
- public Key ShowUi { get; set; }
+ public Key ShowUI { get; set; }
public Key Pause { get; set; }
public Key ToggleMute { get; set; }
public Key ResScaleUp { get; set; }
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/Logging/LogClass.cs b/src/Ryujinx.Common/Logging/LogClass.cs
index f277dd06d..1b404a06a 100644
--- a/src/Ryujinx.Common/Logging/LogClass.cs
+++ b/src/Ryujinx.Common/Logging/LogClass.cs
@@ -70,7 +70,7 @@ namespace Ryujinx.Common.Logging
ServiceVi,
SurfaceFlinger,
TamperMachine,
- Ui,
+ UI,
Vic,
}
}
diff --git a/src/Ryujinx.Common/Logging/Logger.cs b/src/Ryujinx.Common/Logging/Logger.cs
index f03a7fd8f..db46739ac 100644
--- a/src/Ryujinx.Common/Logging/Logger.cs
+++ b/src/Ryujinx.Common/Logging/Logger.cs
@@ -3,6 +3,7 @@ using Ryujinx.Common.SystemInterop;
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.IO;
using System.Runtime.CompilerServices;
using System.Threading;
@@ -22,6 +23,9 @@ namespace Ryujinx.Common.Logging
public readonly struct Log
{
+ private static readonly string _homeDir = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
+ private static readonly string _homeDirRedacted = Path.Combine(Directory.GetParent(_homeDir).FullName, "[redacted]");
+
internal readonly LogLevel Level;
internal Log(LogLevel level)
@@ -100,7 +104,12 @@ namespace Ryujinx.Common.Logging
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static string FormatMessage(LogClass logClass, string caller, string message) => $"{logClass} {caller}: {message}";
+ private static string FormatMessage(LogClass logClass, string caller, string message)
+ {
+ message = message.Replace(_homeDir, _homeDirRedacted);
+
+ return $"{logClass} {caller}: {message}";
+ }
}
public static Log? Debug { get; private set; }
diff --git a/src/Ryujinx.Common/Logging/Targets/FileLogTarget.cs b/src/Ryujinx.Common/Logging/Targets/FileLogTarget.cs
index 8aa2a26b9..8d4ede96c 100644
--- a/src/Ryujinx.Common/Logging/Targets/FileLogTarget.cs
+++ b/src/Ryujinx.Common/Logging/Targets/FileLogTarget.cs
@@ -13,31 +13,82 @@ 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;
+ try
+ {
+ logDir = new DirectoryInfo(path);
+ }
+ catch (ArgumentException exception)
+ {
+ Logger.Warning?.Print(LogClass.Application, $"Logging directory path ('{path}') was invalid: {exception}");
+
+ return null;
+ }
+
+ 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/Memory/StructArrayHelpers.cs b/src/Ryujinx.Common/Memory/StructArrayHelpers.cs
index 94ce8d2f5..762c73889 100644
--- a/src/Ryujinx.Common/Memory/StructArrayHelpers.cs
+++ b/src/Ryujinx.Common/Memory/StructArrayHelpers.cs
@@ -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 3b0666628..79b7d681a 100644
--- a/src/Ryujinx.Common/Memory/StructByteArrayHelpers.cs
+++ b/src/Ryujinx.Common/Memory/StructByteArrayHelpers.cs
@@ -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/ReleaseInformation.cs b/src/Ryujinx.Common/ReleaseInformation.cs
index ab65a98f3..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/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.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/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/Jit/JitCpuContext.cs b/src/Ryujinx.Cpu/Jit/JitCpuContext.cs
index 24bc1e595..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.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 529a1a808..06c11b7b9 100644
--- a/src/Ryujinx.Cpu/Jit/JitMemoryAllocator.cs
+++ b/src/Ryujinx.Cpu/Jit/JitMemoryAllocator.cs
@@ -5,9 +5,14 @@ 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 bcacd116a..bd07d349c 100644
--- a/src/Ryujinx.Cpu/Jit/JitMemoryBlock.cs
+++ b/src/Ryujinx.Cpu/Jit/JitMemoryBlock.cs
@@ -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/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..c4568995c
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Block.cs
@@ -0,0 +1,106 @@
+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 HasHostCallSkipContext;
+ 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 hasHostCallSkipContext,
+ 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;
+ HasHostCallSkipContext = hasHostCallSkipContext;
+ 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,
+ HasHostCallSkipContext,
+ false,
+ false,
+ IsThumb);
+
+ Block rightBlock = new(
+ address,
+ EndAddress,
+ Instructions.GetRange(splitIndex, splitCount),
+ EndsWithBranch,
+ HasHostCall,
+ HasHostCallSkipContext,
+ 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..8a2b389ad
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Decoder.cs
@@ -0,0 +1,556 @@
+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 hasHostCallSkipContext = 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())
+ {
+ if (!hasHostCall)
+ {
+ hasHostCall = InstEmitSystem.NeedsCall(meta.Name);
+ }
+
+ if (!hasHostCallSkipContext)
+ {
+ hasHostCallSkipContext = meta.Name.IsCall() || InstEmitSystem.NeedsCallSkipContext(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))
+ {
+ isLoopEnd = true;
+ hasHostCallSkipContext = true;
+ }
+
+ return new(
+ startAddress,
+ address,
+ insts,
+ !isTruncated,
+ hasHostCall,
+ hasHostCallSkipContext,
+ 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..ca25057fe
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/MultiBlock.cs
@@ -0,0 +1,34 @@
+using System.Collections.Generic;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ class MultiBlock
+ {
+ public readonly List Blocks;
+ public readonly bool HasHostCall;
+ public readonly bool HasHostCallSkipContext;
+ public readonly bool IsTruncated;
+
+ public MultiBlock(List blocks)
+ {
+ Blocks = blocks;
+
+ Block block = blocks[0];
+
+ HasHostCall = block.HasHostCall;
+ HasHostCallSkipContext = block.HasHostCallSkipContext;
+
+ for (int index = 1; index < blocks.Count; index++)
+ {
+ block = blocks[index];
+
+ HasHostCall |= block.HasHostCall;
+ HasHostCallSkipContext |= block.HasHostCallSkipContext;
+ }
+
+ 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..4a3f03b8a
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/RegisterAllocator.cs
@@ -0,0 +1,170 @@
+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;
+ UsedGprsMask |= 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..a668b5777
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/Compiler.cs
@@ -0,0 +1,808 @@
+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);
+ }
+
+ int reservedStackSize = 0;
+
+ if (multiBlock.HasHostCall)
+ {
+ reservedStackSize = CalculateStackSizeForCallSpill(regAlloc.UsedGprsMask, regAlloc.UsedFpSimdMask, UsablePStateMask);
+ }
+ else if (multiBlock.HasHostCallSkipContext)
+ {
+ reservedStackSize = 2 * sizeof(ulong); // Context and page table pointers.
+ }
+
+ RegisterSaveRestore rsr = new(
+ regAlloc.UsedGprsMask & AbiConstants.GprCalleeSavedRegsMask,
+ regAlloc.UsedFpSimdMask & AbiConstants.FpSimdCalleeSavedRegsMask,
+ OperandType.FP64,
+ multiBlock.HasHostCall || multiBlock.HasHostCallSkipContext,
+ reservedStackSize);
+
+ 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 ||
+ name == InstName.Pop)
+ {
+ // 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,
+ ref asm,
+ context.RegisterAllocator,
+ context.TailMerger,
+ context.GetReservedStackOffset(),
+ context.StoreToContext,
+ context.LoadFromContext);
+ 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..3b1ff5a2a
--- /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);
+ }
+ }
+
+ public static void WriteSpillSkipContext(ref Assembler asm, RegisterAllocator regAlloc, int spillOffset)
+ {
+ WriteSpillOrFillSkipContext(ref asm, regAlloc, spillOffset, spill: true);
+ }
+
+ public 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..07f9f86a8
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitSystem.cs
@@ -0,0 +1,660 @@
+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.
+
+ return name == InstName.Mrrc;
+ }
+
+ public static bool NeedsCallSkipContext(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.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, 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, 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, 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,
+ ref Assembler asm,
+ RegisterAllocator regAlloc,
+ TailMerger tailMerger,
+ int spillBaseOffset,
+ Action storeToContext = null,
+ Action loadFromContext = null)
+ {
+ 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);
+
+ storeToContext?.Invoke();
+ WriteSpill(ref asm, regAlloc, 1u << tempRegister, skipContext: true, 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: true, spillBaseOffset, tempRegister);
+ loadFromContext?.Invoke();
+
+ 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)
+ {
+ if (skipContext)
+ {
+ InstEmitFlow.WriteSpillSkipContext(ref asm, regAlloc, spillOffset);
+ }
+ else
+ {
+ WriteSpillOrFill(ref asm, regAlloc, exceptMask, spillOffset, tempRegister, spill: true);
+ }
+ }
+
+ private static void WriteFill(ref Assembler asm, RegisterAllocator regAlloc, uint exceptMask, bool skipContext, int spillOffset, int tempRegister)
+ {
+ if (skipContext)
+ {
+ InstEmitFlow.WriteFillSkipContext(ref asm, regAlloc, spillOffset);
+ }
+ else
+ {
+ 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.UsedGprsMask & ~(AbiConstants.GprCalleeSavedRegsMask | exceptMask);
+
+ 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;
+
+ 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