Compare commits

...

55 Commits

Author SHA1 Message Date
WilliamWsyHK
a1d44ec496 Update translation for Traditional Chinese (ryubing/ryujinx!61)
See merge request ryubing/ryujinx!61
2025-06-14 20:06:12 -05:00
GreemDev
bab3beb0ac [ci skip] Forgot closing / lol 2025-06-13 15:51:23 -05:00
GreemDev
aa9e74339b Add support for notifying the update server when a new update has been pushed instead of relying on periodic refreshes 2025-06-13 01:57:54 -05:00
GreemDev
908273d848 [ci skip] UpdateClient package source
https://git.ryujinx.app/ryubing/update-server/-/packages
2025-06-13 01:57:54 -05:00
shinyoyo
b51ad11574 Updated Simplified Chinese translation (ryubing/ryujinx!58)
See merge request ryubing/ryujinx!58
2025-06-11 19:43:50 -05:00
MrKev
ea027d65a7 Structural and Memory Safety Improvements, Analyzer Cleanup (ryubing/ryujinx!47)
See merge request ryubing/ryujinx!47
2025-06-11 17:58:27 -05:00
Coxxs
d03ae9c164 fix: socket blocking flag is inverted when setting it (ryubing/ryujinx!57)
See merge request ryubing/ryujinx!57
2025-06-11 16:44:07 -05:00
Hack茶ん
90e9492f6c Update Korean translation (ryubing/ryujinx!56)
See merge request ryubing/ryujinx!56
2025-06-11 15:37:48 -05:00
mqudsi
512120db04 Work around Escape hotkey race with exit confirmation dialog
See merge request ryubing/ryujinx!54
2025-06-10 22:52:08 -05:00
rockingdice
90582e9e93 fix: crash caused by cursor overflow
See merge request ryubing/ryujinx!53
2025-06-10 16:34:12 -05:00
rockingdice
b97fae08b5 fix: use the correct font family for CJK characters
See merge request ryubing/ryujinx!52
2025-06-10 15:41:39 -05:00
GreemDev
eed6ef632d infra: [ci skip] update CHANGELOG.md 2025-06-09 19:57:31 -05:00
GreemDev
0409c15903 Remove GitHub updater support. 2025-06-09 19:51:53 -05:00
GreemDev
c58272ac20 infra: CI: Remove GitHub release uploading from Stable workflow. 2025-06-09 18:56:28 -05:00
GreemDev
9d83dfd19c misc: [ci skip] Missed the property part of _chosenProfile 2025-06-09 17:59:40 -05:00
GreemDev
ce31a47934 misc: Code styling changes & cleanups 2025-06-09 17:57:26 -05:00
Goodfeat
d31d1f91cf Added the ability to switch between local and global input in the user configuration
See merge request ryubing/ryujinx!8
2025-06-09 17:24:24 -05:00
Goodfeat
ef02194a77 Update: Compatibility list
See merge request ryubing/ryujinx!29
2025-06-09 02:54:45 -05:00
Goodfeat
a16764d191 Moved "Graphics Backend Multitreading" item to Graphics API & Optimization section
See merge request ryubing/ryujinx!13
2025-06-09 02:37:49 -05:00
GreemDev
5108ab790f UI: RPC: [ci skip] Add BL2, BLTPS, and Minecraft Dungeons RPC images 2025-06-09 01:47:57 -05:00
GreemDev
71dc71fee8 infra: [ci skip] Remove duplicate GLI install in canary CI 2025-06-08 22:37:21 -05:00
GreemDev
c95bf748b2 infra: Update to Ryujinx.LibHac 0.20.0
This is identical to the previous version, it's just on NuGet.org so we can comment out the LibHacAlpha source in nuget.config.
2025-06-08 22:31:32 -05:00
GreemDev
b5e9acc50b misc: [ci skip] Cause GitHub fallback properly 2025-06-08 21:06:34 -05:00
GreemDev
e3fba4e32f docs: compat: further clarify the issue with 'FANTASY LIFE i: The Girl Who Steals Time' with 'crash' and 'vulkan-backend-bug' labels. 2025-06-08 20:44:01 -05:00
GreemDev
efa25d471e docs: compat: ingame: FANTASY LIFE i: The Girl Who Steals Time 2025-06-08 20:41:51 -05:00
GreemDev
b37aa61e47 infra: Remove GitHub uploading from Canary CI workflows 2025-06-08 17:55:36 -05:00
GreemDev
8feeb977b7 infra: [ci skip] fix canary changelog generation 2025-06-08 17:47:45 -05:00
GreemDev
b761a2c86d infra: Custom Update server instead of direct GitLab API calls
This reduces the amount of requests for an update from 3 if an update is needed, or 2 if not; to 1 if an update is needed, and none if an update is not. The difference comes from using this update server to check if an update is needed, and not GETing a snippet content for the release channels.
2025-06-08 17:37:34 -05:00
GreemDev
693837dca7 infra: [ci skip] make the canary release notes look nicer 2025-06-05 23:07:02 -05:00
GreemDev
70abff072b canary CI: checkout code before trying to get current revision 2025-06-05 20:56:17 -05:00
GreemDev
1e861b99a9 misc: Update LibHac
See merge request ryubing/libhac!3
2025-06-05 20:45:35 -05:00
GreemDev
13e404bde0 infra: [ci skip] Move tag creation to the end of the build process in CI 2025-06-05 01:57:21 -05:00
KeatonTheBot
04561a0cd3 Vulkan: Use compute shader for non-indirect unsupported topology index buffer conversions
See merge request ryubing/ryujinx!5
2025-06-05 01:19:44 -05:00
GreemDev
0652d7e740 misc: readme: stable and canary release channels from gitlab 2025-06-04 23:18:44 -05:00
GreemDev
f2aea4fb22 misc: [ci skip] fix typo in comment & rename CheckForUpdateAsync 2025-06-04 21:05:54 -05:00
GreemDev
3950e8adff infra: Embed milestone description in stable release description in CI 2025-06-04 21:05:35 -05:00
GreemDev
0e84f2b1f0 infra: Send a Discord webhook message when a new build is available 2025-06-04 04:31:58 -05:00
TheToid
051c794cc4 Use rcodesign for dylib signing where avaiilable and clear out all "._" files...
See merge request ryubing/ryujinx!14
2025-06-03 23:26:49 -05:00
LotP
053a9cb549 fix: use accurate length for enumerating
See merge request ryubing/ryujinx!49
2025-06-03 23:20:55 -05:00
GreemDev
d688fed7d2 missed the projects/ API endpoint part 2025-06-03 18:38:22 -05:00
GreemDev
8f5102aa2a infra: Add functionality to the CI to upload artifacts to this GitLab and make releases based on all files uploaded.
See merge request ryubing/ryujinx!48
2025-06-03 18:28:59 -05:00
GreemDev
379e9ab622 stable release test workflow for gitlab releases 2025-06-03 04:04:41 -05:00
LotP
af2575b40e Update LibHac
See merge request ryubing/ryujinx!45
2025-06-01 01:28:21 -05:00
MrKev
361d0c5632 Fix ~3500 analyser issues
See merge request ryubing/ryujinx!44
2025-05-30 17:08:34 -05:00
Hack茶ん
417df486b1 Update Korean translation
See merge request ryubing/ryujinx!43
2025-05-29 19:09:03 -05:00
GreemDev
813d05bdf7 misc: Remove internal release channel constants 2025-05-29 17:36:24 -05:00
GreemDev
3429361a5d UI: RPC: Remove release channel from RPC logo hover 2025-05-29 17:35:43 -05:00
GreemDev
92b2947f04 fix invalid link in canary release message & change stable too 2025-05-29 16:14:51 -05:00
GreemDev
4c281062ba test new canary release channel repo 2025-05-29 15:53:01 -05:00
GreemDev
84686d50cd Revert "PPTC: fix rare EndOfStreamException in ContainsBlacklistedFunctions"
This reverts commit 1156307ef913b1cd86ee083b7c8a0526c68c9567
2025-05-29 02:37:52 -05:00
GreemDev
81412c7dd5 misc: fix duplicated code (oops), reorder the commands in-code to match the UI 2025-05-29 02:09:21 -05:00
GreemDev
960421a7c1 misc: Swap the context menu actions to Commands 2025-05-29 01:58:05 -05:00
GreemDev
9233fe86b0 [ci skip] infra: After a quick test, ARMeilleure didn't even use anything from Ryujinx.Common. 2025-05-28 23:52:06 -05:00
GreemDev
1156307ef9 PPTC: fix rare EndOfStreamException in ContainsBlacklistedFunctions 2025-05-28 23:35:52 -05:00
KeatonTheBot
a32a87e0c9 Workaround undefined behavior in bad dual source blend states
See merge request ryubing/ryujinx!4
2025-05-28 05:59:16 -05:00
845 changed files with 6140 additions and 4993 deletions

View File

@ -16,6 +16,17 @@ tab_width = 4
# New line preferences # New line preferences
end_of_line = lf end_of_line = lf
insert_final_newline = true insert_final_newline = true
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_auto_properties = true:silent
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
dotnet_style_operator_placement_when_wrapping = beginning_of_line
dotnet_style_explicit_tuple_names = true:suggestion
# Markdown, JSON, YAML, props and csproj files # Markdown, JSON, YAML, props and csproj files
[*.{md,json,yml,props,csproj}] [*.{md,json,yml,props,csproj}]
@ -34,10 +45,10 @@ dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = false dotnet_sort_system_directives_first = false
# this. and Me. preferences # this. and Me. preferences
dotnet_style_qualification_for_event = false:silent dotnet_style_qualification_for_event = false:suggestion
dotnet_style_qualification_for_field = false:silent dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_method = false:silent dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_property = false:silent dotnet_style_qualification_for_property = false:suggestion
# Language keywords vs BCL types preferences # Language keywords vs BCL types preferences
dotnet_style_predefined_type_for_locals_parameters_members = true:silent dotnet_style_predefined_type_for_locals_parameters_members = true:silent
@ -106,7 +117,7 @@ csharp_style_conditional_delegate_call = true:suggestion
csharp_prefer_static_local_function = true:suggestion csharp_prefer_static_local_function = true:suggestion
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent
csharp_style_prefer_readonly_struct = true csharp_style_prefer_readonly_struct = true
csharp_style_prefer_method_group_conversion = true csharp_style_prefer_method_group_conversion = true:silent
# Code-block preferences # Code-block preferences
csharp_prefer_braces = true:silent csharp_prefer_braces = true:silent
@ -177,9 +188,9 @@ csharp_preserve_single_line_statements = false
# Naming rules # Naming rules
dotnet_naming_rule.interfaces_should_be_prefixed_with_I.severity = suggestion dotnet_naming_rule.interfaces_should_be_prefixed_with_i.severity = suggestion
dotnet_naming_rule.interfaces_should_be_prefixed_with_I.symbols = interface dotnet_naming_rule.interfaces_should_be_prefixed_with_I.symbols = interface
dotnet_naming_rule.interfaces_should_be_prefixed_with_I.style = IPascalCase dotnet_naming_rule.interfaces_should_be_prefixed_with_i.style = IPascalCase
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types dotnet_naming_rule.types_should_be_pascal_case.symbols = types
@ -236,28 +247,24 @@ dotnet_naming_style.IPascalCase.required_suffix =
dotnet_naming_style.IPascalCase.word_separator = dotnet_naming_style.IPascalCase.word_separator =
dotnet_naming_style.IPascalCase.capitalization = pascal_case dotnet_naming_style.IPascalCase.capitalization = pascal_case
# TODO: # Other settings
# .NET 8 migration (new warnings are caused by the NET 8 C# compiler and analyzer) csharp_style_prefer_top_level_statements = true:suggestion
# The following info messages might need to be fixed in the source code instead of hiding the actual message csharp_style_prefer_primary_constructors = false:suggestion
# Without the following lines, dotnet format would fail csharp_prefer_system_threading_lock = true:suggestion
# Disable "Collection initialization can be simplified"
# Analyzers
dotnet_diagnostic.CA1069.severity = none # CA1069: Enums values should not be duplicated
# Disable Collection initialization can be simplified
dotnet_diagnostic.IDE0028.severity = none dotnet_diagnostic.IDE0028.severity = none
dotnet_diagnostic.IDE0079.severity = none # IDE0079: Remove unnecessary suppression
dotnet_diagnostic.IDE0130.severity = none # IDE0130: Namespace does not match folder structure
dotnet_diagnostic.IDE0300.severity = none dotnet_diagnostic.IDE0300.severity = none
dotnet_diagnostic.IDE0301.severity = none dotnet_diagnostic.IDE0301.severity = none
dotnet_diagnostic.IDE0302.severity = none dotnet_diagnostic.IDE0302.severity = none
dotnet_diagnostic.IDE0305.severity = none dotnet_diagnostic.IDE0305.severity = none
# Disable "'new' expression can be simplified" dotnet_diagnostic.CS9113.severity = none # CS9113: Parameter 'value' is unread
dotnet_diagnostic.IDE0090.severity = none dotnet_diagnostic.CS0649.severity = none # CS0649: Field is never assigned to, and will always have its default value
# Disable "Use primary constructor"
dotnet_diagnostic.IDE0290.severity = none
# Disable "Member '' does not access instance data and can be marked as static"
dotnet_diagnostic.CA1822.severity = none
# Disable "Change type of field '' from '' to '' for improved performance"
dotnet_diagnostic.CA1859.severity = none
# Disable "Prefer 'static readonly' fields over constant array arguments if the called method is called repeatedly and is not mutating the passed array"
dotnet_diagnostic.CA1861.severity = none
# Disable "Prefer using 'string.Equals(string, StringComparison)' to perform a case-insensitive comparison, but keep in mind that this might cause subtle changes in behavior, so make sure to conduct thorough testing after applying the suggestion, or if culturally sensitive comparison is not required, consider using 'StringComparison.OrdinalIgnoreCase'"
dotnet_diagnostic.CA1862.severity = none
[src/Ryujinx/UI/ViewModels/**.cs] [src/Ryujinx/UI/ViewModels/**.cs]
# Disable "mark members as static" rule for ViewModels # Disable "mark members as static" rule for ViewModels

View File

@ -21,60 +21,9 @@ env:
DOTNET_CLI_TELEMETRY_OPTOUT: 1 DOTNET_CLI_TELEMETRY_OPTOUT: 1
RYUJINX_BASE_VERSION: "1.3" RYUJINX_BASE_VERSION: "1.3"
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "canary" RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "canary"
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "Ryubing"
RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO: "Ryujinx"
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Canary-Releases"
RELEASE: 1 RELEASE: 1
jobs: jobs:
tag:
name: Create tag
runs-on: ubuntu-24.04
steps:
- name: Get version info
id: version_info
run: |
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
shell: bash
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create GitLab tag
run: gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=CreateTag "Canary-${{ steps.version_info.outputs.build_version }}|master"
- name: Create release
uses: ncipollo/release-action@v1
with:
name: "Canary ${{ steps.version_info.outputs.build_version }}"
tag: ${{ steps.version_info.outputs.build_version }}
body: |
# Canary builds:
These builds are experimental and may sometimes not work, use [regular builds](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/Stable-Releases/releases/latest) instead if that sounds like something you don't want to deal with.
| Platform | Artifact |
|--|--|
| Windows 64-bit | [Canary Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
| Windows ARM 64-bit | [Canary Windows ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_arm64.zip) |
| Linux 64-bit | [Canary Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
| Linux ARM 64-bit | [Canary Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
| macOS | [Canary macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
**[Full Changelog](https://git.ryujinx.app/ryubing/ryujinx/-/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }})**
omitBodyDuringUpdate: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
token: ${{ secrets.RELEASE_TOKEN }}
release: release:
name: Release for ${{ matrix.platform.name }} name: Release for ${{ matrix.platform.name }}
runs-on: ${{ matrix.platform.os }} runs-on: ${{ matrix.platform.os }}
@ -82,7 +31,7 @@ jobs:
matrix: matrix:
platform: platform:
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 } - { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 } #- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 }
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 } - { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 } - { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
steps: steps:
@ -108,11 +57,8 @@ jobs:
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
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_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_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place '/^Name=Ryujinx$/s/Name=Ryujinx/Name=Ryujinx-Canary/' distribution/linux/Ryujinx.desktop sed -r --in-place '/^Name=Ryujinx$/s/Name=Ryujinx/Name=Ryujinx-Canary/' distribution/linux/Ryujinx.desktop
shell: bash shell: bash
- name: Create output dir - name: Create output dir
@ -129,7 +75,24 @@ jobs:
rm libarmeilleure-jitsupport.dylib rm libarmeilleure-jitsupport.dylib
7z a ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish 7z a ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
popd popd
gh release download -R GreemDev/GLI -O gli.exe -p 'GitLabCli-win_x64.exe'
./gli.exe --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip"
shell: bash shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install GitLabCli
if: matrix.platform.os == 'ubuntu-latest'
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Packing Linux builds - name: Packing Linux builds
if: matrix.platform.os == 'ubuntu-latest' if: matrix.platform.os == 'ubuntu-latest'
@ -139,6 +102,8 @@ jobs:
chmod +x Ryujinx.sh Ryujinx chmod +x Ryujinx.sh Ryujinx
tar -czvf ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish tar -czvf ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
popd popd
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz"
shell: bash shell: bash
- name: Build AppImage (Linux) - name: Build AppImage (Linux)
@ -169,41 +134,17 @@ jobs:
exit 1 exit 1
fi fi
export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|Canary-Releases|latest|*-$ARCH_NAME.AppImage.zsync" export UFLAG="gh-releases-zsync|${{ secrets.RC_OWNER }}${{ secrets.RC_CANARY_NAME }}|latest|*-$ARCH_NAME.AppImage.zsync"
BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
pushd publish_appimage pushd publish_appimage
mv Ryujinx.AppImage ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage mv Ryujinx.AppImage ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage
mv Ryujinx.AppImage.zsync ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync mv Ryujinx.AppImage.zsync ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
popd popd
shell: bash
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage"
- name: Pushing new release gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
uses: ncipollo/release-action@v1 shell: bash
with:
name: ${{ steps.version_info.outputs.build_version }}
artifacts: "release_output/*.tar.gz,release_output/*.zip,release_output/*AppImage*"
tag: ${{ steps.version_info.outputs.build_version }}
body: |
# Canary builds:
These builds are experimental and may sometimes not work, use [regular builds](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/latest) instead if that sounds like something you don't want to deal with.
| Platform | Artifact |
|--|--|
| Windows 64-bit | [Canary Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
| Windows ARM 64-bit | [Canary Windows ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_arm64.zip) |
| Linux 64-bit | [Canary Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
| Linux ARM 64-bit | [Canary Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
| macOS | [Canary macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
**[Full Changelog](https://git.ryujinx.app/ryubing/ryujinx/-/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }})**
omitBodyDuringUpdate: true
allowUpdates: true
replacesArtifacts: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
token: ${{ secrets.RELEASE_TOKEN }}
macos_release: macos_release:
name: Release MacOS universal name: Release MacOS universal
@ -220,6 +161,16 @@ jobs:
wget https://apt.llvm.org/llvm.sh wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh chmod +x llvm.sh
sudo ./llvm.sh 17 sudo ./llvm.sh 17
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install rcodesign - name: Install rcodesign
run: | run: |
@ -246,24 +197,53 @@ 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_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_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_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/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 shell: bash
- name: Publish macOS Ryujinx - name: Publish macOS Ryujinx
run: | run: |
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 1 ./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 1
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|publish_ava/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz"
- name: Pushing new release create_gitlab_release:
uses: ncipollo/release-action@v1 name: Create GitLab Release
with: runs-on: ubuntu-24.04
name: "Canary ${{ steps.version_info.outputs.build_version }}" needs:
artifacts: "publish_ava/*.tar.gz" - macos_release
tag: ${{ steps.version_info.outputs.build_version }} - release
body: "" steps:
omitBodyDuringUpdate: true - uses: actions/checkout@v4
allowUpdates: true
replacesArtifacts: true - name: Get version info
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }} id: version_info
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }} run: |
token: ${{ secrets.RELEASE_TOKEN }} echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
shell: bash
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create tag
run: |
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=CreateTag "Canary-${{ steps.version_info.outputs.build_version }}|${{ steps.version_info.outputs.git_short_hash }}"
- name: Create release
run: |
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=CreateReleaseFromGenericPackageFiles "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|main|Canary ${{ steps.version_info.outputs.build_version }}|**Full Changelog:** [${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}](https://git.ryujinx.app/ryubing/ryujinx/-/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }})"
- name: Send notification webhook
run: |
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=SendUpdateMessage "${{ steps.version_info.outputs.build_version }}|FF4500|${{ secrets.CANARY_DISCORD_WEBHOOK }}|https://avatars.githubusercontent.com/u/192939710?s=200&v=4|false"
- name: Notify update server of new builds
run: |
curl 'https://update.ryujinx.app/api/v1/admin/refresh_cache?rc=canary' -X PATCH -H 'accept: */*' -H 'Authorization: ${{ secrets.UPDATE_SERVER_ADMIN_TOKEN }}'

224
.github/workflows/debug_release.yml vendored Normal file
View File

@ -0,0 +1,224 @@
name: Release job (Debug)
on:
workflow_dispatch:
inputs: {}
concurrency: release
env:
POWERSHELL_TELEMETRY_OPTOUT: 1
DOTNET_CLI_TELEMETRY_OPTOUT: 1
RYUJINX_BASE_VERSION: "1.3"
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release"
RELEASE: 1
jobs:
release:
name: Release for ${{ matrix.platform.name }}
runs-on: ${{ matrix.platform.os }}
strategy:
matrix:
platform:
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
#- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 }
- { 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
- uses: actions/setup-dotnet@v4
with:
global-json-file: global.json
- name: Overwrite csc problem matcher
run: echo "::add-matcher::.github/csc.json"
- name: Get version info
id: version_info
run: |
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} + 10))" >> $GITHUB_OUTPUT
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
shell: bash
- name: Configure for release
run: |
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
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_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash
- name: Create output dir
run: "mkdir release_output"
- name: Publish
run: |
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./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
- name: Packing Windows builds
if: matrix.platform.os == 'windows-latest'
run: |
pushd publish
rm libarmeilleure-jitsupport.dylib
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
popd
gh release download -R GreemDev/GLI -O gli.exe -p 'GitLabCli-win_x64.exe'
./gli.exe --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip"
shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install GitLabCli
if: matrix.platform.os == 'ubuntu-latest'
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Packing Linux builds
if: matrix.platform.os == 'ubuntu-latest'
run: |
pushd publish
rm libarmeilleure-jitsupport.dylib
chmod +x Ryujinx.sh Ryujinx
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
popd
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz"
shell: bash
- name: Build AppImage (Linux)
if: matrix.platform.os == 'ubuntu-latest'
run: |
BUILD_VERSION="${{ steps.version_info.outputs.build_version }}"
PLATFORM_NAME="${{ matrix.platform.name }}"
sudo apt install -y zsync desktop-file-utils appstream
mkdir -p tools
export PATH="$PATH:$(readlink -f tools)"
# Setup appimagetool
wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
chmod +x tools/appimagetool
chmod +x distribution/linux/appimage/build-appimage.sh
# Explicitly set $ARCH for appimagetool ($ARCH_NAME is for the file name)
if [ "$PLATFORM_NAME" = "linux-x64" ]; then
ARCH_NAME=x64
export ARCH=x86_64
elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then
ARCH_NAME=arm64
export ARCH=aarch64
else
echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME""
exit 1
fi
export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|*-$ARCH_NAME.AppImage.zsync"
BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
pushd publish_appimage
mv Ryujinx.AppImage ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage
mv Ryujinx.AppImage.zsync ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
popd
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage"
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
shell: bash
macos_release:
name: Release MacOS universal
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
global-json-file: global.json
- name: Setup LLVM 17
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 17
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install rcodesign
run: |
mkdir -p $HOME/.bin
gh release download -R indygreg/apple-platform-rs -O apple-codesign.tar.gz -p 'apple-codesign-*-x86_64-unknown-linux-musl.tar.gz'
tar -xzvf apple-codesign.tar.gz --wildcards '*/rcodesign' --strip-components=1
rm apple-codesign.tar.gz
mv rcodesign $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Get version info
id: version_info
run: |
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} + 10))" >> $GITHUB_OUTPUT
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
- name: Configure for release
run: |
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
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_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash
- name: Publish macOS Ryujinx
run: |
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|publish/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz"
create_gitlab_release:
name: Create GitLab Release
runs-on: ubuntu-24.04
needs:
- macos_release
- release
steps:
- uses: actions/checkout@v4
- name: Get version info
id: version_info
run: |
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} + 10))" >> $GITHUB_OUTPUT
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
shell: bash
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create release
run: |
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=CreateReleaseFromGenericPackageFiles "Ryubing|${{ steps.version_info.outputs.build_version }}|${{ steps.version_info.outputs.git_short_hash }}|test|THIS IS NOT INTENDED FOR END USER USAGE"

View File

@ -11,57 +11,9 @@ env:
DOTNET_CLI_TELEMETRY_OPTOUT: 1 DOTNET_CLI_TELEMETRY_OPTOUT: 1
RYUJINX_BASE_VERSION: "1.3" RYUJINX_BASE_VERSION: "1.3"
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release" RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release"
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "Ryubing"
RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO: "Ryujinx"
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Stable-Releases"
RELEASE: 1 RELEASE: 1
jobs: jobs:
tag:
name: Create tag
runs-on: ubuntu-24.04
steps:
- name: Get version info
id: version_info
run: |
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
shell: bash
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create GitLab tag
run: gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=CreateTag "${{ steps.version_info.outputs.build_version }}|master"
- name: Create release
uses: ncipollo/release-action@v1
with:
name: ${{ steps.version_info.outputs.build_version }}
tag: ${{ steps.version_info.outputs.build_version }}
body: |
# Stable builds:
| Platform | Artifact |
|--|--|
| Windows 64-bit | [Stable Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
| Windows ARM 64-bit | [Stable Windows ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_arm64.zip) |
| Linux 64-bit | [Stable Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
| Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
| macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
**[Full Changelog](https://git.ryujinx.app/ryubing/ryujinx/-/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }})**
omitBodyDuringUpdate: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
token: ${{ secrets.RELEASE_TOKEN }}
release: release:
name: Release for ${{ matrix.platform.name }} name: Release for ${{ matrix.platform.name }}
runs-on: ${{ matrix.platform.os }} runs-on: ${{ matrix.platform.os }}
@ -69,7 +21,7 @@ jobs:
matrix: matrix:
platform: platform:
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 } - { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 } #- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 }
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 } - { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 } - { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
steps: steps:
@ -95,9 +47,6 @@ jobs:
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
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_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_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/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 shell: bash
@ -115,7 +64,24 @@ jobs:
rm libarmeilleure-jitsupport.dylib rm libarmeilleure-jitsupport.dylib
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish 7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
popd popd
gh release download -R GreemDev/GLI -O gli.exe -p 'GitLabCli-win_x64.exe'
./gli.exe --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip"
shell: bash shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install GitLabCli
if: matrix.platform.os == 'ubuntu-latest'
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Packing Linux builds - name: Packing Linux builds
if: matrix.platform.os == 'ubuntu-latest' if: matrix.platform.os == 'ubuntu-latest'
@ -125,7 +91,11 @@ jobs:
chmod +x Ryujinx.sh Ryujinx chmod +x Ryujinx.sh Ryujinx
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
popd popd
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz"
shell: bash shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build AppImage (Linux) - name: Build AppImage (Linux)
if: matrix.platform.os == 'ubuntu-latest' if: matrix.platform.os == 'ubuntu-latest'
@ -162,32 +132,11 @@ jobs:
mv Ryujinx.AppImage ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage mv Ryujinx.AppImage ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage
mv Ryujinx.AppImage.zsync ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync mv Ryujinx.AppImage.zsync ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
popd popd
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage"
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
shell: bash shell: bash
- name: Pushing new release
uses: ncipollo/release-action@v1
with:
name: ${{ steps.version_info.outputs.build_version }}
artifacts: "release_output/*.tar.gz,release_output/*.zip,release_output/*AppImage*"
tag: ${{ steps.version_info.outputs.build_version }}
body: |
# Stable builds:
| Platform | Artifact |
|--|--|
| Windows 64-bit | [Stable Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
| Windows ARM 64-bit | [Stable Windows ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_arm64.zip) |
| Linux 64-bit | [Stable Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
| Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
| macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
**[Full Changelog](https://git.ryujinx.app/ryubing/ryujinx/-/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }})**
omitBodyDuringUpdate: true
allowUpdates: true
replacesArtifacts: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
token: ${{ secrets.RELEASE_TOKEN }}
macos_release: macos_release:
name: Release MacOS universal name: Release MacOS universal
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
@ -203,6 +152,16 @@ jobs:
wget https://apt.llvm.org/llvm.sh wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh chmod +x llvm.sh
sudo ./llvm.sh 17 sudo ./llvm.sh 17
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install rcodesign - name: Install rcodesign
run: | run: |
@ -227,26 +186,49 @@ jobs:
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
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_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_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/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 shell: bash
- name: Publish macOS Ryujinx - name: Publish macOS Ryujinx
run: | run: |
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0 ./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|publish/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz"
create_gitlab_release:
name: Create GitLab Release
runs-on: ubuntu-24.04
needs:
- macos_release
- release
steps:
- uses: actions/checkout@v4
- name: Get version info
id: version_info
run: |
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
shell: bash
- name: Pushing new release - name: Install GitLabCli
uses: ncipollo/release-action@v1 run: |
with: mkdir -p $HOME/.bin
name: ${{ steps.version_info.outputs.build_version }} gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
artifacts: "publish/*.tar.gz" chmod +x gli
tag: ${{ steps.version_info.outputs.build_version }} mv gli $HOME/.bin/
body: "" echo "$HOME/.bin" >> $GITHUB_PATH
omitBodyDuringUpdate: true env:
allowUpdates: true GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
replacesArtifacts: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }} - name: Create release
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }} run: |
token: ${{ secrets.RELEASE_TOKEN }} gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=CreateReleaseFromGenericPackageFiles "Ryubing|${{ steps.version_info.outputs.build_version }}|${{ steps.version_info.outputs.git_short_hash }}|${{ steps.version_info.outputs.build_version }}|msd:${{ steps.version_info.outputs.build_version }}"
- name: Send notification webhook
run: |
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=SendUpdateMessage "${{ steps.version_info.outputs.build_version }}|32cd32|${{ secrets.STABLE_DISCORD_WEBHOOK }}|https://avatars.githubusercontent.com/u/192939710?s=200&v=4|false"
- name: Notify update server of new builds
run: |
curl 'https://update.ryujinx.app/api/v1/admin/refresh_cache?rc=stable' -X PATCH -H 'accept: */*' -H 'Authorization: ${{ secrets.UPDATE_SERVER_ADMIN_TOKEN }}'

View File

@ -13,7 +13,6 @@ rm -rf pkgs
mkdir pkgs mkdir pkgs
package ARMeilleure package ARMeilleure
package Ryujinx.Common
package Ryujinx.Memory package Ryujinx.Memory
dotnet nuget push pkgs/*.nupkg --source RyubingPkgs dotnet nuget push pkgs/*.nupkg --source RyubingPkgs

View File

@ -2,20 +2,17 @@
All updates to this Ryujinx branch will be documented in this file. All updates to this Ryujinx branch will be documented in this file.
## [1.3.2](<https://git.ryujinx.app/ryubing/ryujinx/-/releases/1.3.2>) - 2025-06-09
## [1.3.1](<https://git.ryujinx.app/ryubing/ryujinx/-/releases/1.3.1>) - 2025-04-23 ## [1.3.1](<https://git.ryujinx.app/ryubing/ryujinx/-/releases/1.3.1>) - 2025-04-23
A list of notable changes can be found on the release linked in the version number above.
## [1.2.86](<https://github.com/Ryubing/Stable-Releases/releases/tag/1.2.86>) - 2025-03-13 ## [1.2.86](<https://github.com/Ryubing/Stable-Releases/releases/tag/1.2.86>) - 2025-03-13
A list of notable changes can be found on the release linked in the version number above.
## [1.2.82](<https://web.archive.org/web/20250312010534/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.82>) - 2025-02-16 ## [1.2.82](<https://web.archive.org/web/20250312010534/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.82>) - 2025-02-16
A list of notable changes can be found on the release linked in the version number above.
## [1.2.80-81](<https://web.archive.org/web/20250302064257/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.81>) - 2025-01-22 ## [1.2.80-81](<https://web.archive.org/web/20250302064257/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.81>) - 2025-01-22
A list of notable changes can be found on the release linked in the version number above.
## [1.2.78](<https://web.archive.org/web/20250301174537/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.78>) - 2024-12-19 ## [1.2.78](<https://web.archive.org/web/20250301174537/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.78>) - 2024-12-19
A list of notable changes can be found on the release linked in the version number above.
## [1.2.73-1.2.76](<https://web.archive.org/web/20250209202612/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.76>) - 2024-11-19 ## [1.2.73-1.2.76](<https://web.archive.org/web/20250209202612/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.76>) - 2024-11-19
A list of notable changes can be found on the release linked in the version number above. A list of notable changes can be found on the release linked in the version number above.
@ -254,4 +251,4 @@ Added Low-power PPTC mode strings to the translation files.
- Autoload DLC/Updates from dir ([#12](https://github.com/GreemDev/Ryujinx/pull/12)). - Autoload DLC/Updates from dir ([#12](https://github.com/GreemDev/Ryujinx/pull/12)).
- Changed executable icon to rainbow logo. - Changed executable icon to rainbow logo.
- Extract Data > Logo now also extracts the square thumbnail you see for the game in the UI. - Extract Data > Logo now also extracts the square thumbnail you see for the game in the UI.
- The "use random UUID hack" checkbox in the Amiibo screen now remembers its last state when you reopen the window in a given session. - The "use random UUID hack" checkbox in the Amiibo screen now remembers its last state when you reopen the window in a given session.

View File

@ -40,7 +40,7 @@
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" /> <PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.AllArch" Version="6.1.2-build3" /> <PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.AllArch" Version="6.1.2-build3" />
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" /> <PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
<PackageVersion Include="Ryujinx.LibHac" Version="0.20.0-alpha.103" /> <PackageVersion Include="Ryujinx.LibHac" Version="0.20.0" />
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" /> <PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
<PackageVersion Include="Gommon" Version="2.7.1.1" /> <PackageVersion Include="Gommon" Version="2.7.1.1" />
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" /> <PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />

View File

@ -7,8 +7,8 @@
# Ryujinx # Ryujinx
[![Latest release](https://img.shields.io/github/v/release/Ryubing/Stable-Releases?label=stable)](https://github.com/Ryubing/Stable-Releases/releases/latest) [![Latest release](https://img.shields.io/gitlab/v/release/ryubing%2Fryujinx?gitlab_url=https%3A%2F%2Fgit.ryujinx.app&label=stable&color=32cd32)](https://git.ryujinx.app/ryubing/ryujinx/-/releases)
[![Latest canary release](https://img.shields.io/github/v/release/Ryubing/Canary-Releases?label=canary)](https://github.com/Ryubing/Canary-Releases/releases/latest) [![Latest canary release](https://img.shields.io/gitlab/v/release/ryubing%2Fcanary?gitlab_url=https%3A%2F%2Fgit.ryujinx.app&label=canary&color=FF4500)](https://git.ryujinx.app/ryubing/canary/-/releases)
<br> <br>
<a href="https://discord.gg/PEuzjrFXUA"> <a href="https://discord.gg/PEuzjrFXUA">
<img src="https://img.shields.io/discord/1294443224030511104?color=5865F2&label=Ryubing&logo=discord&logoColor=white" alt="Discord"> <img src="https://img.shields.io/discord/1294443224030511104?color=5865F2&label=Ryubing&logo=discord&logoColor=white" alt="Discord">
@ -31,7 +31,7 @@
<br> <br>
This is not a Ryujinx revival project. This is not a Phoenix project. This is not a Ryujinx revival project. This is not a Phoenix project.
<br> <br>
Guides and documentation can be found on the <a href="https://git.ryujinx.app/ryubing/ryujinx/-/wikis/home">Wiki tab</a>. Guides and documentation can be found on the <a href="https://git.ryujinx.app/groups/ryubing/-/wikis/home">Wiki tab</a>.
</p> </p>
<p align="center"> <p align="center">
@ -49,13 +49,13 @@ Stable builds are made every so often, based on the `master` branch, that then g
These stable builds exist so that the end user can get a more **enjoyable and stable experience**. These stable builds exist so that the end user can get a more **enjoyable and stable experience**.
They are released every month or so, to ensure consistent updates, while not being an annoying amount of individual updates to download over the course of that month. They are released every month or so, to ensure consistent updates, while not being an annoying amount of individual updates to download over the course of that month.
You can find the latest stable release [here](https://github.com/Ryubing/Stable-Releases/releases/latest). You can find the stable releases [here](https://git.ryujinx.app/ryubing/ryujinx/-/releases).
Canary builds are compiled automatically for each commit on the `master` branch. Canary 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, these builds **may be unstable or completely broken**. While we strive to ensure optimal stability and performance prior to pushing an update, these builds **may be unstable or completely broken**.
These canary builds are only recommended for experienced users. These canary builds are only recommended for experienced users.
You can find the latest canary release [here](https://github.com/Ryubing/Canary-Releases/releases/latest). You can find the canary releases [here](https://git.ryujinx.app/ryubing/canary/-/releases).
## Documentation ## Documentation
@ -111,7 +111,7 @@ See [LICENSE.txt](LICENSE.txt) and [THIRDPARTY.md](distribution/legal/THIRDPARTY
## Credits ## Credits
- [LibHac](https://github.com/Thealexbarney/LibHac) is used for our file-system. - [LibHac](https://git.ryujinx.app/ryubing/libhac) is used for our file-system.
- [AmiiboAPI](https://www.amiiboapi.com) is used in our Amiibo emulation. - [AmiiboAPI](https://www.amiiboapi.com) is used in our Amiibo emulation.
- [ldn_mitm](https://github.com/spacemeowx2/ldn_mitm) is used for one of our available multiplayer modes. - [ldn_mitm](https://github.com/spacemeowx2/ldn_mitm) is used for one of our available multiplayer modes.
- [ShellLink](https://github.com/securifybv/ShellLink) is used for Windows shortcut generation. - [ShellLink](https://github.com/securifybv/ShellLink) is used for Windows shortcut generation.

View File

@ -1847,6 +1847,131 @@
"zh_TW": "路徑" "zh_TW": "路徑"
} }
}, },
{
"ID": "GameListSortStatusNameAscending",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "Όνομα: A-Z",
"en_US": "Title: A-Z",
"es_ES": "Título: A-Z",
"fr_FR": "Titre : A-Z",
"he_IL": "",
"it_IT": "Titolo: A-Z",
"ja_JP": "タイトルA-Z",
"ko_KR": "제목: A-Z",
"no_NO": "Tittel: A-Z",
"pl_PL": "Tytuł: A-Z",
"pt_BR": "Título: A-Z",
"ru_RU": "Название: А-Z",
"sv_SE": "Titel: A-Z",
"th_TH": "ชื่อเรื่อง: A-Z",
"tr_TR": "Başlık: A-Z",
"uk_UA": "Назва: A-Z",
"zh_CN": "标题A-Z",
"zh_TW": "標題A-Z"
}
},
{
"ID": "GameListSortStatusNameDescending",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "Τίτλος: Z-A",
"en_US": "Title: Z-A",
"es_ES": "Título: Z-A",
"fr_FR": "Titre : Z-A",
"he_IL": "",
"it_IT": "Titolo: Z-A",
"ja_JP": "タイトルZ-A",
"ko_KR": "제목: Z-A",
"no_NO": "Tittel: Z-A",
"pl_PL": "Tytuł: Z-A",
"pt_BR": "Título: Z-A",
"ru_RU": "Название: Z-A",
"sv_SE": "Titel: Z-A",
"th_TH": "ชื่อเรื่อง: Z-A",
"tr_TR": "Başlık: Z-A",
"uk_UA": "Назва: Z-A",
"zh_CN": "标题Z-A",
"zh_TW": "標題Z-A"
}
},
{
"ID": "GameListSortStatusDisable",
"Translations": {
"ar_SA": "",
"de_DE": "Status: Deaktiviert",
"el_GR": "Κατάσταση: Απενεργοποιημένο",
"en_US": "Status: Disabled",
"es_ES": "Estado: Desactivado",
"fr_FR": "Statut : Désactivé",
"he_IL": "",
"it_IT": "Stato: Disabilitato",
"ja_JP": "ステータス:無効",
"ko_KR": "상태: 비활성화됨",
"no_NO": "Status: Deaktivert",
"pl_PL": "Status: Wyłączony",
"pt_BR": "Status: Desativado",
"ru_RU": "Статус: Отключено",
"sv_SE": "Status: Inaktiverad",
"th_TH": "",
"tr_TR": "Durum: Devre Dışı",
"uk_UA": "Статус: Вимкнено",
"zh_CN": "状态:禁用",
"zh_TW": "狀態:停用"
}
},
{
"ID": "GameListSortStatusAscending",
"Translations": {
"ar_SA": "الحالة: تصاعدي",
"de_DE": "Status: Aufsteigend",
"el_GR": "Κατάσταση: Αναγόμενη",
"en_US": "Status: Ascending",
"es_ES": "",
"fr_FR": "Statut : Croissant",
"he_IL": "סטטוס: עולה",
"it_IT": "Stato: Crescente",
"ja_JP": "ステータス:昇順",
"ko_KR": "상태: 오름차순",
"no_NO": "Status: Stigende",
"pl_PL": "Stan: Rosnący",
"pt_BR": "Status: Crescente",
"ru_RU": "Статус: По возрастанию",
"sv_SE": "Status: Stigande",
"th_TH": "สถานะ: เพิ่มขึ้น",
"tr_TR": "Durum: Artan",
"uk_UA": "Статус: Зростання",
"zh_CN": "状态:升序",
"zh_TW": "狀態:遞增"
}
},
{
"ID": "GameListSortStatusDescending",
"Translations": {
"ar_SA": "الحالة: تنازلي",
"de_DE": "Status: Absteigend",
"el_GR": "Κατάσταση: Καθοδική",
"en_US": "Status: Descending",
"es_ES": "",
"fr_FR": "Statut : Décroissant",
"he_IL": "סטטוס: יורד",
"it_IT": "Stato: Decrescente",
"ja_JP": "ステータス:降順",
"ko_KR": "상태: 내림차순",
"no_NO": "Status: Synkende",
"pl_PL": "Stan: Malejący",
"pt_BR": "Status: Decrescente",
"ru_RU": "Статус: По Убыванию",
"sv_SE": "Status: Fallande",
"th_TH": "สถานะ: ลดลง",
"tr_TR": "Durum: Azalan",
"uk_UA": "Статус: Зменшення",
"zh_CN": "状态:降序",
"zh_TW": "狀態:遞減"
}
},
{ {
"ID": "GameListHeaderCompatibilityStatus", "ID": "GameListHeaderCompatibilityStatus",
"Translations": { "Translations": {
@ -1969,7 +2094,7 @@
"tr_TR": "Toplam Oyun Süresi: {0}", "tr_TR": "Toplam Oyun Süresi: {0}",
"uk_UA": "", "uk_UA": "",
"zh_CN": "总游戏时间: {0}", "zh_CN": "总游戏时间: {0}",
"zh_TW": "" "zh_TW": "總遊戲時間: {0}"
} }
}, },
{ {
@ -3159,7 +3284,7 @@
"he_IL": "{1}/{0} משחקים נטענו", "he_IL": "{1}/{0} משחקים נטענו",
"it_IT": "{0}/{1} giochi caricati", "it_IT": "{0}/{1} giochi caricati",
"ja_JP": "{0}/{1} ゲーム", "ja_JP": "{0}/{1} ゲーム",
"ko_KR": "{0}/{1}개의 게임 확인", "ko_KR": "{0}/{1}개의 게임 타이틀",
"no_NO": "{0}/{1} Spill Lastet", "no_NO": "{0}/{1} Spill Lastet",
"pl_PL": "{0}/{1} Załadowane gry", "pl_PL": "{0}/{1} Załadowane gry",
"pt_BR": "{0}/{1} Jogos Carregados", "pt_BR": "{0}/{1} Jogos Carregados",
@ -5450,26 +5575,26 @@
{ {
"ID": "SettingsTabGraphicsAPI", "ID": "SettingsTabGraphicsAPI",
"Translations": { "Translations": {
"ar_SA": "API الرسومات ", "ar_SA": "API الرسومات و تحسين",
"de_DE": "Grafik-API", "de_DE": "Grafik-API & Optimierung",
"el_GR": "API Γραφικά", "el_GR": "API Γραφικά & Βελτιστοποίηση",
"en_US": "Graphics API", "en_US": "Graphics API & Optimization",
"es_ES": "API de gráficos", "es_ES": "API de gráficos & Optimización",
"fr_FR": "API Graphique", "fr_FR": "API Graphique & Optimisation",
"he_IL": "ממשק גראפי", "he_IL": "ממשק גראפי & אופטימיזציה",
"it_IT": "API grafica", "it_IT": "API grafica & Ottimizzazione",
"ja_JP": "グラフィックスAPI", "ja_JP": "グラフィックスAPI&最適化",
"ko_KR": "그래픽 API", "ko_KR": "그래픽 API & 최적화",
"no_NO": "Grafikk API", "no_NO": "Grafikk-API & Optimalisering",
"pl_PL": "Graficzne API", "pl_PL": "Graficzne API & Optymalizacja",
"pt_BR": "API gráfica", "pt_BR": "API gráfica & Otimização",
"ru_RU": "Графические API", "ru_RU": "Графический API & Оптимизация",
"sv_SE": "Grafik-API", "sv_SE": "Grafik-API & Optimering",
"th_TH": "API กราฟฟิก", "th_TH": "API กราฟฟิก & การเพิ่มประสิทธิภาพ",
"tr_TR": "Grafikler API", "tr_TR": "Grafikler API & Optimizasyon",
"uk_UA": "Графічний API", "uk_UA": "Графічний API & Оптимізація",
"zh_CN": "图形 API", "zh_CN": "图形 API & 优化",
"zh_TW": "圖形 API" "zh_TW": "圖形 API & 優化"
} }
}, },
{ {
@ -6547,6 +6672,31 @@
"zh_TW": "輸入" "zh_TW": "輸入"
} }
}, },
{
"ID": "SettingsTabInputUseGlobalInput",
"Translations": {
"ar_SA": "إدخال عالمي",
"de_DE": "Globale Eingabe",
"el_GR": "Παγκόσμια εισαγωγή",
"en_US": "Global Input",
"es_ES": "Entrada Global",
"fr_FR": "Saisie Globale",
"he_IL": "קלט גלובלי",
"it_IT": "Input Globale",
"ja_JP": "グローバル入力",
"ko_KR": "글로벌 입력",
"no_NO": "Global Inndata",
"pl_PL": "Globalny Wpis",
"pt_BR": "Entrada Global",
"ru_RU": "Глобальный Ввод",
"sv_SE": "Global Input",
"th_TH": "การป้อนข้อมูลแบบโกลบอล",
"tr_TR": "Küresel Girdi",
"uk_UA": "Глобальний Ввід",
"zh_CN": "全局输入",
"zh_TW": "全域輸入"
}
},
{ {
"ID": "SettingsTabInputEnableDockedMode", "ID": "SettingsTabInputEnableDockedMode",
"Translations": { "Translations": {
@ -7069,7 +7219,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "发现配置:\n\n名称:\t{0}\nGUID:\t{1}\n\n 正在等待控制器连接...", "zh_CN": "发现配置:\n\n名称:\t{0}\nGUID:\t{1}\n\n 正在等待控制器连接...",
"zh_TW": "" "zh_TW": "找到控制器的配置:\n\n名稱:\t{0}\nGUID:\t{1}\n\n 正在等待控制器連線..."
} }
}, },
{ {
@ -7109,7 +7259,7 @@
"he_IL": "מושבת", "he_IL": "מושבת",
"it_IT": "Disabilitato", "it_IT": "Disabilitato",
"ja_JP": "無効", "ja_JP": "無効",
"ko_KR": "비활성화", "ko_KR": "비활성화",
"no_NO": "Deaktivert", "no_NO": "Deaktivert",
"pl_PL": "Wyłączone", "pl_PL": "Wyłączone",
"pt_BR": "Desabilitado", "pt_BR": "Desabilitado",
@ -12973,53 +13123,28 @@
} }
}, },
{ {
"ID": "DialogUpdaterFailedToGetVersionMessage", "ID": "DialogUpdaterConvertFailedServerMessage",
"Translations": { "Translations": {
"ar_SA": "حدث خطأ أثناء محاولة الحصول على معلومات الإصدار من إصدار غيت هاب. يمكن أن يحدث هذا إذا تم تجميع إصدار جديد بواسطة إجراءات غيت هاب. جرب مجددا بعد دقائق.", "ar_SA": "",
"de_DE": "Beim Versuch, Veröffentlichungs-Info von GitHub Release zu erhalten, ist ein Fehler aufgetreten. Dies kann aufgrund einer neuen Veröffentlichung, die gerade von GitHub Actions kompiliert wird, verursacht werden.", "de_DE": "",
"el_GR": "Προέκυψε ένα σφάλμα στη λήψη πληροφοριών έκδοσης από τα GitHub Releases. Αυτό δύναται να συμβεί αν μία έκδοση χτίζεται αυτή τη στιγμή στα GitHub Actions. Παρακαλούμε προσπαθήστε αργότερα.", "el_GR": "",
"en_US": "An error occurred while trying to retrieve release information from GitHub. This may happen if a new release is currently being compiled by GitHub Actions. Please try again in a few minutes.", "en_US": "Failed to convert the Ryujinx version received from the update server.",
"es_ES": "Se ha producido un error al intentar obtener información de liberación de GitHub Release. Esto puede ser causado si una nueva versión está siendo compilada por GitHub Actions. Inténtalo de nuevo en unos minutos.", "es_ES": "",
"fr_FR": "Une erreur s'est produite lors de la tentative d'obtention des informations de publication de la version GitHub. Cela peut survenir lorsqu'une nouvelle version est en cours de compilation par GitHub Actions. Réessayez dans quelques minutes.", "fr_FR": "La conversion de la version de Ryujinx reçue du serveur a échoué.",
"he_IL": "אירעה שגיאה בעת ניסיון לקבל עדכונים מ-גיטהב. זה יכול להיגרם אם הגרסה המעודכנת האחרונה נוצרה על ידי פעולות של גיטהב. נסה שוב בעוד מספר דקות.", "he_IL": "",
"it_IT": "Si è verificato un errore durante il tentativo di recuperare le informazioni sulla versione da GitHub Release. Ciò può verificarsi se una nuova versione è in fase di compilazione da GitHub Actions. Riprova tra qualche minuto.", "it_IT": "",
"ja_JP": "Github からのリリース情報取得時にエラーが発生しました. Github Actions でリリースファイルを作成中かもしれません. 後ほどもう一度試してみてください.", "ja_JP": "",
"ko_KR": "GitHub에서 릴리스 정보를 검색하는 동안 오류가 발생했습니다. 현재 GitHub Actions에서 새 릴리스를 컴파일하는 중일 때 발생할 수 있습니다. 몇 분 후에 다시 시도해 주세요.", "ko_KR": "업데이트 서버에서 받은 Ryujinx 버전을 변환하는 데 실패했습니다.",
"no_NO": "En feil oppstod ved forsøk på å få utgivelsesinformasjon fra GitHub Utgivelse. Dette kan forårsakes hvis en ny utgave blir samlet av GitHub Handlinger. Prøv igjen om noen minutter.", "no_NO": "Kunne ikke konvertere Ryujinx-versjonen som ble mottatt fra oppdateringsserveren.",
"pl_PL": "Wystąpił błąd podczas próby uzyskania informacji o obecnej wersji z GitHub Release. Może to być spowodowane nową wersją kompilowaną przez GitHub Actions. Spróbuj ponownie za kilka minut.", "pl_PL": "",
"pt_BR": "Ocorreu um erro ao tentar obter as informações de atualização do GitHub Release. Isso pode ser causado se uma nova versão estiver sendo compilado pelas Ações do GitHub. Tente novamente em alguns minutos.", "pt_BR": "Falha em atualizar a versão do Ryujinx recebida do servidor de atualização.",
"ru_RU": "Произошла ошибка при попытке получить информацию о выпуске от GitHub Release. Это может быть вызвано тем, что в данный момент в GitHub Actions компилируется новый релиз. Повторите попытку позже.", "ru_RU": "",
"sv_SE": "Ett fel inträffade vid försök att hämta information om utgåvan från GitHub. Detta kan hända om en ny utgåva har kompilerats av GitHub Actions. Försök igen om några minuter.", "sv_SE": "",
"th_TH": "เกิดข้อผิดพลาดขณะพยายามรับข้อมูลเวอร์ชั่นจาก GitHub Release ปัญหานี้อาจเกิดขึ้นได้หากมีการรวบรวมเวอร์ชั่นใหม่โดย GitHub โปรดลองอีกครั้งในอีกไม่กี่นาทีข้างหน้า", "th_TH": "",
"tr_TR": "GitHub tarafından sürüm bilgileri alınırken bir hata oluştu. Eğer yeni sürüm için hazırlıklar yapılıyorsa bu hatayı almanız olasıdır. Lütfen birkaç dakika sonra tekrar deneyiniz.", "tr_TR": "",
"uk_UA": "Під час спроби отримати інформацію про випуск із GitHub Release сталася помилка. Це може бути спричинено, якщо новий випуск компілюється GitHub Actions. Повторіть спробу через кілька хвилин.", "uk_UA": "",
"zh_CN": "尝试从 Github 获取版本信息时无效,可能由于 GitHub Actions 正在编译新版本。\n请过一会再试。", "zh_CN": "无法转换从更新服务器接收的 Ryujinx 版本。",
"zh_TW": "嘗試從 GitHub Release 取得發布資訊時發生錯誤。如果 GitHub Actions 正在編譯新版本,則可能會出現這種情況。請幾分鐘後再試一次。" "zh_TW": "無法轉換從更新何服器接收的 Ryujinx 版本。"
}
},
{
"ID": "DialogUpdaterConvertFailedGithubMessage",
"Translations": {
"ar_SA": "فشل تحويل إصدار ريوجينكس المستلم من إصدار غيت هاب.",
"de_DE": "Fehler beim Konvertieren der erhaltenen Ryujinx-Version von GitHub Release.",
"el_GR": "Αποτυχία μετατροπής της ληφθείσας έκδοσης Ryujinx από την έκδοση GitHub.",
"en_US": "Failed to convert the Ryujinx version received from GitHub.",
"es_ES": "No se pudo convertir la versión de Ryujinx recibida de GitHub Release.",
"fr_FR": "Impossible de convertir la version reçue de Ryujinx depuis GitHub Release.",
"he_IL": "המרת גרסת ריוג'ינקס שהתקבלה מ-עדכון הגרסאות של גיטהב נכשלה.",
"it_IT": "La conversione della versione di Ryujinx ricevuta da GitHub Release è fallita.",
"ja_JP": "Github から取得した Ryujinx バージョンの変換に失敗しました.",
"ko_KR": "GitHub에서 받은 Ryujinx 버전을 변환하지 못했습니다.",
"no_NO": "Kan ikke konvertere mottatt Ryujinx-versjon fra GitHub Utgivelse.",
"pl_PL": "Nie udało się przekonwertować otrzymanej wersji Ryujinx z Github Release.",
"pt_BR": "Falha ao converter a versão Ryujinx recebida do GitHub.",
"ru_RU": "Не удалось преобразовать полученную версию Ryujinx из GitHub Release.",
"sv_SE": "Misslyckades med att konvertera mottagen Ryujinx-version från GitHub.",
"th_TH": "ไม่สามารถแปลงเวอร์ชั่น Ryujinx ที่ได้รับจาก GitHub Release",
"tr_TR": "Github Release'den alınan Ryujinx sürümü dönüştürülemedi.",
"uk_UA": "Не вдалося конвертувати отриману версію Ryujinx із випуску GitHub.",
"zh_CN": "无法切换至从 GitHub 接收到的新版 Ryujinx 模拟器。",
"zh_TW": "無法轉換從 GitHub Release 接收到的 Ryujinx 版本。"
} }
}, },
{ {
@ -16422,6 +16547,31 @@
"zh_TW": "瀏覽自訂 GUI 佈景主題" "zh_TW": "瀏覽自訂 GUI 佈景主題"
} }
}, },
{
"ID": "UseGlobalInputTooltip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "If this option is enabled in custom settings, the global input configuration will be used.\n\nIn the global settings: you can enable or disable it as needed; this setting will be inherited by any new custom configurations created.",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "사용자 지정 설정에서 이 옵션을 활성화하면 전역 입력 구성이 사용됩니다.\n\n전역 설정에서 필요에 따라 활성화하거나 비활성화할 수 있습니다. 이 설정은 새로 생성된 모든 사용자 지정 구성에 상속됩니다.",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "Если эта опция включена в пользовательских настройках, будет использована глобальная конфигурация ввода.\n\nВ глобальных настройках: переключите эту опцию по своему усмотрению, это будет унаследовано для вновь созданых пользовательских конфигураций",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "如果在自定义设置中启用了此选项,则将使用全局输入配置。\n\n在全局设置中: 您可以根据需要启用或禁用它;之后创建的任何自定义配置都将继承此设置。",
"zh_TW": "如果在自訂設定啟用了此選項,則將使用全域輸入配置。\n\n在全域設定中你可以根據需要啟用或停用它之後建立的任何自訂配置都將繼承此設定。"
}
},
{ {
"ID": "DockModeToggleTooltip", "ID": "DockModeToggleTooltip",
"Translations": { "Translations": {
@ -18394,7 +18544,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "{0} FPS ({1}毫秒)", "zh_CN": "{0} FPS ({1}毫秒)",
"zh_TW": "" "zh_TW": "{0} FPS ({1}毫秒)"
} }
}, },
{ {
@ -19684,7 +19834,7 @@
"he_IL": "מוריד עדכון...", "he_IL": "מוריד עדכון...",
"it_IT": "Download dell'aggiornamento...", "it_IT": "Download dell'aggiornamento...",
"ja_JP": "アップデートをダウンロード中...", "ja_JP": "アップデートをダウンロード中...",
"ko_KR": "업데이트 내려받 중...", "ko_KR": "업데이트 내려받 중...",
"no_NO": "Laster ned oppdatering...", "no_NO": "Laster ned oppdatering...",
"pl_PL": "Pobieranie Aktualizacji...", "pl_PL": "Pobieranie Aktualizacji...",
"pt_BR": "Baixando Atualização...", "pt_BR": "Baixando Atualização...",
@ -23294,7 +23444,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "查看更新日志", "zh_CN": "查看更新日志",
"zh_TW": "" "zh_TW": "檢視更新日誌"
} }
}, },
{ {
@ -23409,7 +23559,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "Disabilitato", "it_IT": "Disabilitato",
"ja_JP": "無効", "ja_JP": "無効",
"ko_KR": "비활성화", "ko_KR": "비활성화",
"no_NO": "Deaktivert", "no_NO": "Deaktivert",
"pl_PL": "Wyłączone", "pl_PL": "Wyłączone",
"pt_BR": "Desativado", "pt_BR": "Desativado",
@ -24372,6 +24522,106 @@
"zh_TW": "開啟相容性列表" "zh_TW": "開啟相容性列表"
} }
}, },
{
"ID": "CompatibilityListGamesAndApplications",
"Translations": {
"ar_SA": "",
"de_DE": "Spiele & Anwendungen",
"el_GR": "Παιχνίδια και Εφαρμογές",
"en_US": "Games & Applications",
"es_ES": "Juegos y Aplicaciones",
"fr_FR": "Jeux et Applications",
"he_IL": "משחקים ואפליקציות",
"it_IT": "Giochi e Applicazioni",
"ja_JP": "ゲームとアプリケーション",
"ko_KR": "게임 및 애플리케이션",
"no_NO": "Spill og Applikasjoner",
"pl_PL": "Gry i Aplikacje",
"pt_BR": "Jogos e Aplicativos",
"ru_RU": "Игры и Приложения",
"sv_SE": "Spel och Applikationer",
"th_TH": "",
"tr_TR": "Oyunlar ve Uygulamalar",
"uk_UA": "Ігри та Додатки",
"zh_CN": "游戏和应用程序",
"zh_TW": "遊戲與應用程式"
}
},
{
"ID": "CompatibilityListStatus",
"Translations": {
"ar_SA": "الحالة",
"de_DE": "",
"el_GR": "Κατάσταση",
"en_US": "Status",
"es_ES": "Estado",
"fr_FR": "Statut",
"he_IL": "מצב",
"it_IT": "Stato",
"ja_JP": "状況",
"ko_KR": "상태",
"no_NO": "",
"pl_PL": "Stan",
"pt_BR": "Estado",
"ru_RU": "Статус",
"sv_SE": "",
"th_TH": "สถานะ",
"tr_TR": "Durum",
"uk_UA": "Статус",
"zh_CN": "状态",
"zh_TW": "狀態"
}
},
{
"ID": "CompatibilityListDescription",
"Translations": {
"ar_SA": "",
"de_DE": "Probleme und Merkmale",
"el_GR": "Προβλήματα και Χαρακτηριστικά",
"en_US": "Issues & Features",
"es_ES": "Problemas y Características",
"fr_FR": "Problèmes et Caractéristiques",
"he_IL": "",
"it_IT": "Problemi e Caratteristiche",
"ja_JP": "問題点と特徴",
"ko_KR": "문제점 및 특징",
"no_NO": "Problemer og Egenskaper",
"pl_PL": "Problemy i Cechy",
"pt_BR": "Problemas e Características",
"ru_RU": "Проблемы и Особенности",
"sv_SE": "Problem och Egenskaper",
"th_TH": "",
"tr_TR": "Sorunlar ve Özellikler",
"uk_UA": "Проблеми та Особливості",
"zh_CN": "问题和特性",
"zh_TW": "問題與特性"
}
},
{
"ID": "CompatibilityListInfo",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "Πληροφορίες",
"en_US": "Info",
"es_ES": "Información",
"fr_FR": "",
"he_IL": "מידע",
"it_IT": "",
"ja_JP": "情報",
"ko_KR": "정보",
"no_NO": "",
"pl_PL": "Informacja",
"pt_BR": "",
"ru_RU": "Инфо",
"sv_SE": "",
"th_TH": "",
"tr_TR": "Bilgi",
"uk_UA": "Інфо",
"zh_CN": "信息",
"zh_TW": "資訊"
}
},
{ {
"ID": "CompatibilityListOnlyShowOwnedGames", "ID": "CompatibilityListOnlyShowOwnedGames",
"Translations": { "Translations": {
@ -24534,7 +24784,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "어떠한 충돌이나 GPU 버그 없이 부팅 및 플레이가 가능하며, 일반 PC에서 충분히 즐길 수 있을 만큼 빠른 속도입니다.", "ko_KR": "어떠한 충돌이나 GPU 버그 없이 부팅 및 플레이가 가능하며, 일반 PC에서 충분히 즐길 수 있을 만큼 쾌적한 속도입니다.",
"no_NO": "Starter opp og spiller uten krasj eller GPU-feil av noe slag, og med en hastighet som er rask nok til å ha rimelig glede av på en gjennomsnittlig PC.", "no_NO": "Starter opp og spiller uten krasj eller GPU-feil av noe slag, og med en hastighet som er rask nok til å ha rimelig glede av på en gjennomsnittlig PC.",
"pl_PL": "", "pl_PL": "",
"pt_BR": "Inicializa e roda sem travamentos ou bugs de GPU de qualquer tipo, e em uma velocidade rápida o suficiente para ser aproveitado em um PC comum.", "pt_BR": "Inicializa e roda sem travamentos ou bugs de GPU de qualquer tipo, e em uma velocidade rápida o suficiente para ser aproveitado em um PC comum.",
@ -24559,7 +24809,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "부팅하고 게임에 들어가지만 충돌, 교착 상태, GPU 버그, 방해가 될 정도로 나쁜 오디오 또는 너무 느린 문제 중 하나 이상으로 인해 문제가 발생합니다. 게임은 여전히 ​​가능할 수 있습니다.", "ko_KR": "부팅하고 게임에 진입하지만 충돌, 교착, GPU 버그, 오디오에 문제가 있거나 버벅임 중 하나 이상으로 인해 문제가 발생합니다. 게임은 어쨌든 진행할 수 있습니다.",
"no_NO": "Starter og går i gang i spillet, men lider av ett eller flere av følgende: krasjer, fastlåser, GPU-feil, distraherende dårlig lyd eller er rett og slett for tregt. Spillet kan fortsatt spilles helt til ende, men ikke slik det er ment å spilles.", "no_NO": "Starter og går i gang i spillet, men lider av ett eller flere av følgende: krasjer, fastlåser, GPU-feil, distraherende dårlig lyd eller er rett og slett for tregt. Spillet kan fortsatt spilles helt til ende, men ikke slik det er ment å spilles.",
"pl_PL": "", "pl_PL": "",
"pt_BR": "Inicializa e entra no jogo, mas sofre de um ou mais dos seguintes: travamentos, deadlocks, bugs de GPU, áudio ruim que distrai ou é simplesmente muito lento. O jogo ainda pode ser jogado até o fim, mas não da forma como foi criado para ser jogado.", "pt_BR": "Inicializa e entra no jogo, mas sofre de um ou mais dos seguintes: travamentos, deadlocks, bugs de GPU, áudio ruim que distrai ou é simplesmente muito lento. O jogo ainda pode ser jogado até o fim, mas não da forma como foi criado para ser jogado.",
@ -24634,7 +24884,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "부팅되지 않거나 활동 흔적이 보이지 않습니다.", "ko_KR": "부팅되지 않거나 동작하지 않습니다.",
"no_NO": "Starter ikke opp eller viser ingen tegn til aktivitet.", "no_NO": "Starter ikke opp eller viser ingen tegn til aktivitet.",
"pl_PL": "", "pl_PL": "",
"pt_BR": "Não inicializa ou não mostra sinais de atividade.", "pt_BR": "Não inicializa ou não mostra sinais de atividade.",

View File

@ -33,23 +33,29 @@ echo -n "APPL????" > "$APP_BUNDLE_DIRECTORY/Contents/PkgInfo"
echo "Running bundle fix up python script" echo "Running bundle fix up python script"
python3 bundle_fix_up.py "$APP_BUNDLE_DIRECTORY" MacOS/Ryujinx python3 bundle_fix_up.py "$APP_BUNDLE_DIRECTORY" MacOS/Ryujinx
# Resign all dyplib files as ad-hoc after changing them
find "$APP_BUNDLE_DIRECTORY/Contents/Frameworks" -type f -name "*.dylib" -exec codesign --force --sign - {} \;
# Now sign it # Now sign it
echo "Starting signing process" echo "Starting signing process"
if ! [ -x "$(command -v codesign)" ]; if ! [ -x "$(command -v codesign)" ];
then then
if ! [ -x "$(command -v rcodesign)" ]; if ! [ -x "$(command -v rcodesign)" ];
then then
echo "Cannot find rcodesign on your system, please install rcodesign." echo "Cannot find rcodesign on your system, please install rcodesign and ensure it is in your search path."
exit 1 exit 1
fi fi
# cargo install apple-codesign
echo "Using rcodesign for ad-hoc signing" echo "Using rcodesign for ad-hoc signing"
echo "Resigning all frameworks dylib files as ad-hoc"
find "$APP_BUNDLE_DIRECTORY/Contents/Frameworks" -type f -name "*.dylib" -exec rcodesign sign {} \;
echo "Signing app bundle as ad-hoc"
rcodesign sign --entitlements-xml-path "$ENTITLEMENTS_FILE_PATH" "$APP_BUNDLE_DIRECTORY" rcodesign sign --entitlements-xml-path "$ENTITLEMENTS_FILE_PATH" "$APP_BUNDLE_DIRECTORY"
else else
echo "Using codesign for ad-hoc signing" echo "Using codesign for ad-hoc signing"
echo "Resigning all frameworks dylib files as ad-hoc"
find "$APP_BUNDLE_DIRECTORY/Contents/Frameworks" -type f -name "*.dylib" -exec codesign --force --sign - {} \;
echo "Signing app bundle as ad-hoc"
codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f -s - "$APP_BUNDLE_DIRECTORY" codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f -s - "$APP_BUNDLE_DIRECTORY"
fi fi

View File

@ -20,6 +20,18 @@ SOURCE_REVISION_ID=$6
CONFIGURATION=$7 CONFIGURATION=$7
CANARY=$8 CANARY=$8
if [[ "$(uname)" == "Darwin" ]]; then
echo "Clearing xattr on all dot undercsore files"
find "$BASE_DIR" -type f -name "._*" -exec sh -c '
for f; do
dir=$(dirname "$f")
base=$(basename "$f")
orig="$dir/${base#._}"
[ -f "$orig" ] && xattr -c "$orig" || true
done
' sh {} +
fi
if [ "$CANARY" == "1" ]; then if [ "$CANARY" == "1" ]; then
RELEASE_TAR_FILE_NAME=ryujinx-canary-$VERSION-macos_universal.app.tar RELEASE_TAR_FILE_NAME=ryujinx-canary-$VERSION-macos_universal.app.tar
elif [ "$VERSION" == "1.1.0" ]; then elif [ "$VERSION" == "1.1.0" ]; then

View File

@ -20,6 +20,18 @@ SOURCE_REVISION_ID=$6
CONFIGURATION=$7 CONFIGURATION=$7
CANARY=$8 CANARY=$8
if [[ "$(uname)" == "Darwin" ]]; then
echo "Clearing xattr on all dot undercsore files"
find "$BASE_DIR" -type f -name "._*" -exec sh -c '
for f; do
dir=$(dirname "$f")
base=$(basename "$f")
orig="$dir/${base#._}"
[ -f "$orig" ] && xattr -c "$orig" || true
done
' sh {} +
fi
if [ "$CANARY" == "1" ]; then if [ "$CANARY" == "1" ]; then
RELEASE_TAR_FILE_NAME=nogui-ryujinx-canary-$VERSION-macos_universal.tar RELEASE_TAR_FILE_NAME=nogui-ryujinx-canary-$VERSION-macos_universal.tar
elif [ "$VERSION" == "1.1.0" ]; then elif [ "$VERSION" == "1.1.0" ]; then

View File

@ -1125,6 +1125,7 @@
0100034012606000,"Family Mysteries: Poisonous Promises",audio;crash,menus,2021-11-26 12:35:06 0100034012606000,"Family Mysteries: Poisonous Promises",audio;crash,menus,2021-11-26 12:35:06
010017C012726000,"Fantasy Friends",,playable,2022-10-17 19:42:39 010017C012726000,"Fantasy Friends",,playable,2022-10-17 19:42:39
0100767008502000,"FANTASY HERO unsigned legacy",,playable,2022-07-26 12:28:52 0100767008502000,"FANTASY HERO unsigned legacy",,playable,2022-07-26 12:28:52
0100755017EE0000,"FANTASY LIFE i: The Girl Who Steals Time",gpu;crash;vulkan-backend-bug,ingame,2025-06-08 20:41:00
0100944003820000,"Fantasy Strike",online,playable,2021-02-27 01:59:18 0100944003820000,"Fantasy Strike",online,playable,2021-02-27 01:59:18
01000E2012F6E000,"Fantasy Tavern Sextet -Vol.1 New World Days-",gpu;crash;Needs Update,ingame,2022-12-05 16:48:00 01000E2012F6E000,"Fantasy Tavern Sextet -Vol.1 New World Days-",gpu;crash;Needs Update,ingame,2022-12-05 16:48:00
01005C10136CA000,"Fantasy Tavern Sextet -Vol.2 Adventurer's Days-",gpu;slow;crash,ingame,2021-11-06 02:57:29 01005C10136CA000,"Fantasy Tavern Sextet -Vol.2 Adventurer's Days-",gpu;slow;crash,ingame,2021-11-06 02:57:29

1 title_id game_name labels status last_updated
1125 0100034012606000 Family Mysteries: Poisonous Promises audio;crash menus 2021-11-26 12:35:06
1126 010017C012726000 Fantasy Friends playable 2022-10-17 19:42:39
1127 0100767008502000 FANTASY HERO ~unsigned legacy~ playable 2022-07-26 12:28:52
1128 0100755017EE0000 FANTASY LIFE i: The Girl Who Steals Time gpu;crash;vulkan-backend-bug ingame 2025-06-08 20:41:00
1129 0100944003820000 Fantasy Strike online playable 2021-02-27 01:59:18
1130 01000E2012F6E000 Fantasy Tavern Sextet -Vol.1 New World Days- gpu;crash;Needs Update ingame 2022-12-05 16:48:00
1131 01005C10136CA000 Fantasy Tavern Sextet -Vol.2 Adventurer's Days- gpu;slow;crash ingame 2021-11-06 02:57:29

View File

@ -4,20 +4,8 @@
<packageSources> <packageSources>
<clear /> <clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" /> <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="LibHacAlpha" value="https://git.ryujinx.app/api/v4/projects/17/packages/nuget/index.json" /> <!-- Only needed when using pre-release versions of Ryujinx.LibHac. -->
<add key="RyubingPkgs" value="https://git.ryujinx.app/api/v4/projects/1/packages/nuget/index.json" /> <!--<add key="LibHacAlpha" value="https://git.ryujinx.app/api/v4/projects/17/packages/nuget/index.json" />-->
<add key="Ryujinx.UpdateClient" value="https://git.ryujinx.app/api/v4/projects/71/packages/nuget/index.json" />
</packageSources> </packageSources>
<!-- Define mappings by adding package patterns beneath the target source. -->
<!-- Ryujinx.LibHac packages will be restored from LibHacAlpha,
everything else from nuget.org. -->
<packageSourceMapping>
<!-- key value for <packageSource> should match key values from <packageSources> element -->
<packageSource key="nuget.org">
<package pattern="*" />
</packageSource>
<packageSource key="LibHacAlpha">
<package pattern="Ryujinx.LibHac" />
</packageSource>
</packageSourceMapping>
</configuration> </configuration>

View File

@ -7,7 +7,6 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
<ProjectReference Include="..\Ryujinx.Memory\Ryujinx.Memory.csproj" /> <ProjectReference Include="..\Ryujinx.Memory\Ryujinx.Memory.csproj" />
</ItemGroup> </ItemGroup>

View File

@ -254,7 +254,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static bool IsMemoryLoadOrStore(Instruction inst) private static bool IsMemoryLoadOrStore(Instruction inst)
{ {
return inst == Instruction.Load || inst == Instruction.Store; return inst is Instruction.Load or Instruction.Store;
} }
private static bool ConstTooLong(Operand constOp, OperandType accessType) private static bool ConstTooLong(Operand constOp, OperandType accessType)

View File

@ -774,6 +774,7 @@ namespace ARMeilleure.CodeGen.Arm64
instI |= 1 << 22; // sh flag instI |= 1 << 22; // sh flag
imm >>= 12; imm >>= 12;
} }
WriteInstructionAuto(instI | (EncodeUImm12(imm, 0) << 10), rd, rn); WriteInstructionAuto(instI | (EncodeUImm12(imm, 0) << 10), rd, rn);
} }
else else
@ -1128,7 +1129,6 @@ namespace ARMeilleure.CodeGen.Arm64
}; };
} }
#pragma warning disable IDE0051 // Remove unused private member
private void WriteInt16(short value) private void WriteInt16(short value)
{ {
WriteUInt16((ushort)value); WriteUInt16((ushort)value);
@ -1143,7 +1143,6 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
_stream.WriteByte(value); _stream.WriteByte(value);
} }
#pragma warning restore IDE0051
private void WriteUInt16(ushort value) private void WriteUInt16(ushort value)
{ {

View File

@ -52,7 +52,7 @@ namespace ARMeilleure.CodeGen.Arm64
// Any value AND all ones will be equal itself, so it's effectively a no-op. // Any value AND all ones will be equal itself, so it's effectively a no-op.
// Any value OR all ones will be equal all ones, so one can just use MOV. // Any value OR all ones will be equal all ones, so one can just use MOV.
// Any value XOR all ones will be equal its inverse, so one can just use MVN. // Any value XOR all ones will be equal its inverse, so one can just use MVN.
if (value == 0 || value == ulong.MaxValue) if (value is 0 or ulong.MaxValue)
{ {
immN = 0; immN = 0;
immS = 0; immS = 0;

View File

@ -1,6 +1,7 @@
using ARMeilleure.CodeGen.Linking; using ARMeilleure.CodeGen.Linking;
using ARMeilleure.CodeGen.RegisterAllocators; using ARMeilleure.CodeGen.RegisterAllocators;
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using Microsoft.IO;
using Ryujinx.Common.Memory; using Ryujinx.Common.Memory;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -14,7 +15,7 @@ namespace ARMeilleure.CodeGen.Arm64
private const int CbnzInstLength = 4; private const int CbnzInstLength = 4;
private const int LdrLitInstLength = 4; private const int LdrLitInstLength = 4;
private readonly Stream _stream; private readonly RecyclableMemoryStream _stream;
public int StreamOffset => (int)_stream.Length; public int StreamOffset => (int)_stream.Length;

View File

@ -189,8 +189,8 @@ namespace ARMeilleure.CodeGen.Arm64
// The only blocks which can have 0 successors are exit blocks. // The only blocks which can have 0 successors are exit blocks.
Operation last = block.Operations.Last; Operation last = block.Operations.Last;
Debug.Assert(last.Instruction == Instruction.Tailcall || Debug.Assert(last.Instruction is Instruction.Tailcall or
last.Instruction == Instruction.Return); Instruction.Return);
} }
else else
{ {
@ -464,7 +464,7 @@ namespace ARMeilleure.CodeGen.Arm64
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64); Debug.Assert(dest.Type is OperandType.FP32 or OperandType.FP64);
Debug.Assert(dest.Type != source.Type); Debug.Assert(dest.Type != source.Type);
Debug.Assert(source.Type != OperandType.V128); Debug.Assert(source.Type != OperandType.V128);
@ -483,7 +483,7 @@ namespace ARMeilleure.CodeGen.Arm64
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64); Debug.Assert(dest.Type is OperandType.FP32 or OperandType.FP64);
Debug.Assert(dest.Type != source.Type); Debug.Assert(dest.Type != source.Type);
Debug.Assert(source.Type.IsInteger()); Debug.Assert(source.Type.IsInteger());
@ -1463,7 +1463,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static bool IsLoadOrStore(Operation operation) private static bool IsLoadOrStore(Operation operation)
{ {
return operation.Instruction == Instruction.Load || operation.Instruction == Instruction.Store; return operation.Instruction is Instruction.Load or Instruction.Store;
} }
private static OperandType GetMemOpValueType(Operation operation) private static OperandType GetMemOpValueType(Operation operation)
@ -1499,6 +1499,7 @@ namespace ARMeilleure.CodeGen.Arm64
return false; return false;
} }
} }
if (memOp.Index != default) if (memOp.Index != default)
{ {
return false; return false;
@ -1553,7 +1554,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void EnsureSameReg(Operand op1, Operand op2) private static void EnsureSameReg(Operand op1, Operand op2)
{ {
Debug.Assert(op1.Kind == OperandKind.Register || op1.Kind == OperandKind.Memory); Debug.Assert(op1.Kind is OperandKind.Register or OperandKind.Memory);
Debug.Assert(op1.Kind == op2.Kind); Debug.Assert(op1.Kind == op2.Kind);
Debug.Assert(op1.Value == op2.Value); Debug.Assert(op1.Value == op2.Value);
} }
@ -1569,13 +1570,11 @@ namespace ARMeilleure.CodeGen.Arm64
Debug.Assert(op1.Type == op3.Type); Debug.Assert(op1.Type == op3.Type);
} }
#pragma warning disable IDE0051 // Remove unused private member
private static void EnsureSameType(Operand op1, Operand op2, Operand op3, Operand op4) private static void EnsureSameType(Operand op1, Operand op2, Operand op3, Operand op4)
{ {
Debug.Assert(op1.Type == op2.Type); Debug.Assert(op1.Type == op2.Type);
Debug.Assert(op1.Type == op3.Type); Debug.Assert(op1.Type == op3.Type);
Debug.Assert(op1.Type == op4.Type); Debug.Assert(op1.Type == op4.Type);
} }
#pragma warning restore IDE0051
} }
} }

View File

@ -509,7 +509,6 @@ namespace ARMeilleure.CodeGen.Arm64
context.Assembler.WriteInstruction(instruction, rd, rn); context.Assembler.WriteInstruction(instruction, rd, rn);
} }
} }
private static void GenerateScalarTernary( private static void GenerateScalarTernary(

View File

@ -137,6 +137,7 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
return val != 0; return val != 0;
} }
return false; return false;
} }

View File

@ -736,19 +736,19 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
IntrinsicInfo info = IntrinsicTable.GetInfo(intrinsic & ~(Intrinsic.Arm64VTypeMask | Intrinsic.Arm64VSizeMask)); IntrinsicInfo info = IntrinsicTable.GetInfo(intrinsic & ~(Intrinsic.Arm64VTypeMask | Intrinsic.Arm64VSizeMask));
return info.Type == IntrinsicType.ScalarBinaryRd || return info.Type is IntrinsicType.ScalarBinaryRd or
info.Type == IntrinsicType.ScalarTernaryFPRdByElem || IntrinsicType.ScalarTernaryFPRdByElem or
info.Type == IntrinsicType.ScalarTernaryShlRd || IntrinsicType.ScalarTernaryShlRd or
info.Type == IntrinsicType.ScalarTernaryShrRd || IntrinsicType.ScalarTernaryShrRd or
info.Type == IntrinsicType.Vector128BinaryRd || IntrinsicType.Vector128BinaryRd or
info.Type == IntrinsicType.VectorBinaryRd || IntrinsicType.VectorBinaryRd or
info.Type == IntrinsicType.VectorInsertByElem || IntrinsicType.VectorInsertByElem or
info.Type == IntrinsicType.VectorTernaryRd || IntrinsicType.VectorTernaryRd or
info.Type == IntrinsicType.VectorTernaryRdBitwise || IntrinsicType.VectorTernaryRdBitwise or
info.Type == IntrinsicType.VectorTernaryFPRdByElem || IntrinsicType.VectorTernaryFPRdByElem or
info.Type == IntrinsicType.VectorTernaryRdByElem || IntrinsicType.VectorTernaryRdByElem or
info.Type == IntrinsicType.VectorTernaryShlRd || IntrinsicType.VectorTernaryShlRd or
info.Type == IntrinsicType.VectorTernaryShrRd; IntrinsicType.VectorTernaryShrRd;
} }
private static bool HasConstSrc1(Operation node, ulong value) private static bool HasConstSrc1(Operation node, ulong value)
@ -849,7 +849,7 @@ namespace ARMeilleure.CodeGen.Arm64
Comparison compType = (Comparison)comp.AsInt32(); Comparison compType = (Comparison)comp.AsInt32();
return compType == Comparison.Equal || compType == Comparison.NotEqual; return compType is Comparison.Equal or Comparison.NotEqual;
} }
} }
@ -871,9 +871,9 @@ namespace ARMeilleure.CodeGen.Arm64
IntrinsicInfo info = IntrinsicTable.GetInfo(intrinsic & ~(Intrinsic.Arm64VTypeMask | Intrinsic.Arm64VSizeMask)); IntrinsicInfo info = IntrinsicTable.GetInfo(intrinsic & ~(Intrinsic.Arm64VTypeMask | Intrinsic.Arm64VSizeMask));
// Those have integer inputs that don't support consts. // Those have integer inputs that don't support consts.
return info.Type != IntrinsicType.ScalarFPConvGpr && return info.Type is not IntrinsicType.ScalarFPConvGpr and
info.Type != IntrinsicType.ScalarFPConvFixedGpr && not IntrinsicType.ScalarFPConvFixedGpr and
info.Type != IntrinsicType.SetRegister; not IntrinsicType.SetRegister;
} }
return false; return false;

View File

@ -37,6 +37,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => x + y); EvaluateBinaryI64(operation, (x, y) => x + y);
} }
break; break;
case Instruction.BitwiseAnd: case Instruction.BitwiseAnd:
@ -48,6 +49,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => x & y); EvaluateBinaryI64(operation, (x, y) => x & y);
} }
break; break;
case Instruction.BitwiseExclusiveOr: case Instruction.BitwiseExclusiveOr:
@ -59,6 +61,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => x ^ y); EvaluateBinaryI64(operation, (x, y) => x ^ y);
} }
break; break;
case Instruction.BitwiseNot: case Instruction.BitwiseNot:
@ -70,6 +73,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateUnaryI64(operation, (x) => ~x); EvaluateUnaryI64(operation, (x) => ~x);
} }
break; break;
case Instruction.BitwiseOr: case Instruction.BitwiseOr:
@ -81,6 +85,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => x | y); EvaluateBinaryI64(operation, (x, y) => x | y);
} }
break; break;
case Instruction.ConvertI64ToI32: case Instruction.ConvertI64ToI32:
@ -88,6 +93,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateUnaryI32(operation, (x) => x); EvaluateUnaryI32(operation, (x) => x);
} }
break; break;
case Instruction.Compare: case Instruction.Compare:
@ -129,6 +135,7 @@ namespace ARMeilleure.CodeGen.Optimizations
break; break;
} }
} }
break; break;
case Instruction.Copy: case Instruction.Copy:
@ -140,6 +147,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateUnaryI64(operation, (x) => x); EvaluateUnaryI64(operation, (x) => x);
} }
break; break;
case Instruction.Divide: case Instruction.Divide:
@ -151,6 +159,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => y != 0 ? x / y : 0); EvaluateBinaryI64(operation, (x, y) => y != 0 ? x / y : 0);
} }
break; break;
case Instruction.DivideUI: case Instruction.DivideUI:
@ -162,6 +171,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => y != 0 ? (long)((ulong)x / (ulong)y) : 0); EvaluateBinaryI64(operation, (x, y) => y != 0 ? (long)((ulong)x / (ulong)y) : 0);
} }
break; break;
case Instruction.Multiply: case Instruction.Multiply:
@ -173,6 +183,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => x * y); EvaluateBinaryI64(operation, (x, y) => x * y);
} }
break; break;
case Instruction.Negate: case Instruction.Negate:
@ -184,6 +195,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateUnaryI64(operation, (x) => -x); EvaluateUnaryI64(operation, (x) => -x);
} }
break; break;
case Instruction.ShiftLeft: case Instruction.ShiftLeft:
@ -195,6 +207,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => x << (int)y); EvaluateBinaryI64(operation, (x, y) => x << (int)y);
} }
break; break;
case Instruction.ShiftRightSI: case Instruction.ShiftRightSI:
@ -206,6 +219,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => x >> (int)y); EvaluateBinaryI64(operation, (x, y) => x >> (int)y);
} }
break; break;
case Instruction.ShiftRightUI: case Instruction.ShiftRightUI:
@ -217,6 +231,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => (long)((ulong)x >> (int)y)); EvaluateBinaryI64(operation, (x, y) => (long)((ulong)x >> (int)y));
} }
break; break;
case Instruction.SignExtend16: case Instruction.SignExtend16:
@ -228,6 +243,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateUnaryI64(operation, (x) => (short)x); EvaluateUnaryI64(operation, (x) => (short)x);
} }
break; break;
case Instruction.SignExtend32: case Instruction.SignExtend32:
@ -239,6 +255,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateUnaryI64(operation, (x) => (int)x); EvaluateUnaryI64(operation, (x) => (int)x);
} }
break; break;
case Instruction.SignExtend8: case Instruction.SignExtend8:
@ -250,6 +267,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateUnaryI64(operation, (x) => (sbyte)x); EvaluateUnaryI64(operation, (x) => (sbyte)x);
} }
break; break;
case Instruction.ZeroExtend16: case Instruction.ZeroExtend16:
@ -261,6 +279,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateUnaryI64(operation, (x) => (ushort)x); EvaluateUnaryI64(operation, (x) => (ushort)x);
} }
break; break;
case Instruction.ZeroExtend32: case Instruction.ZeroExtend32:
@ -272,6 +291,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateUnaryI64(operation, (x) => (uint)x); EvaluateUnaryI64(operation, (x) => (uint)x);
} }
break; break;
case Instruction.ZeroExtend8: case Instruction.ZeroExtend8:
@ -283,6 +303,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateUnaryI64(operation, (x) => (byte)x); EvaluateUnaryI64(operation, (x) => (byte)x);
} }
break; break;
case Instruction.Subtract: case Instruction.Subtract:
@ -294,6 +315,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => x - y); EvaluateBinaryI64(operation, (x, y) => x - y);
} }
break; break;
} }
} }

View File

@ -227,11 +227,11 @@ namespace ARMeilleure.CodeGen.Optimizations
private static bool HasSideEffects(Operation node) private static bool HasSideEffects(Operation node)
{ {
return node.Instruction == Instruction.Call return node.Instruction is Instruction.Call
|| node.Instruction == Instruction.Tailcall or Instruction.Tailcall
|| node.Instruction == Instruction.CompareAndSwap or Instruction.CompareAndSwap
|| node.Instruction == Instruction.CompareAndSwap16 or Instruction.CompareAndSwap16
|| node.Instruction == Instruction.CompareAndSwap8; or Instruction.CompareAndSwap8;
} }
private static bool IsPropagableCompare(Operation operation) private static bool IsPropagableCompare(Operation operation)

View File

@ -847,7 +847,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
// If this is a copy (or copy-like operation), set the copy source interval as well. // If this is a copy (or copy-like operation), set the copy source interval as well.
// This is used for register preferencing later on, which allows the copy to be eliminated // This is used for register preferencing later on, which allows the copy to be eliminated
// in some cases. // in some cases.
if (node.Instruction == Instruction.Copy || node.Instruction == Instruction.ZeroExtend32) if (node.Instruction is Instruction.Copy or Instruction.ZeroExtend32)
{ {
Operand source = node.GetSource(0); Operand source = node.GetSource(0);
@ -1120,8 +1120,8 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private static bool IsLocalOrRegister(OperandKind kind) private static bool IsLocalOrRegister(OperandKind kind)
{ {
return kind == OperandKind.LocalVariable || return kind is OperandKind.LocalVariable or
kind == OperandKind.Register; OperandKind.Register;
} }
} }
} }

View File

@ -1478,7 +1478,7 @@ namespace ARMeilleure.CodeGen.X86
private static bool Is64Bits(OperandType type) private static bool Is64Bits(OperandType type)
{ {
return type == OperandType.I64 || type == OperandType.FP64; return type is OperandType.I64 or OperandType.FP64;
} }
private static bool IsImm8(ulong immediate, OperandType type) private static bool IsImm8(ulong immediate, OperandType type)

View File

@ -1,5 +1,4 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
namespace ARMeilleure.CodeGen.X86 namespace ARMeilleure.CodeGen.X86
{ {
@ -13,7 +12,6 @@ namespace ARMeilleure.CodeGen.X86
private const int BadOp = 0; private const int BadOp = 0;
[Flags] [Flags]
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
private enum InstructionFlags private enum InstructionFlags
{ {
None = 0, None = 0,

View File

@ -20,12 +20,12 @@ namespace ARMeilleure.CodeGen.X86
{ {
if (GetCurrentCallConv() == CallConvName.Windows) if (GetCurrentCallConv() == CallConvName.Windows)
{ {
#pragma warning disable IDE0055 // Disable formatting
return (1 << (int)X86Register.Rax) | return (1 << (int)X86Register.Rax) |
(1 << (int)X86Register.Rcx) | (1 << (int)X86Register.Rcx) |
(1 << (int)X86Register.Rdx) | (1 << (int)X86Register.Rdx) |
(1 << (int)X86Register.R8) | (1 << (int)X86Register.R8) |
(1 << (int)X86Register.R9) | (1 << (int)X86Register.R9) |
(1 << (int)X86Register.R10) | (1 << (int)X86Register.R10) |
(1 << (int)X86Register.R11); (1 << (int)X86Register.R11);
} }
@ -36,11 +36,11 @@ namespace ARMeilleure.CodeGen.X86
(1 << (int)X86Register.Rdx) | (1 << (int)X86Register.Rdx) |
(1 << (int)X86Register.Rsi) | (1 << (int)X86Register.Rsi) |
(1 << (int)X86Register.Rdi) | (1 << (int)X86Register.Rdi) |
(1 << (int)X86Register.R8) | (1 << (int)X86Register.R8) |
(1 << (int)X86Register.R9) | (1 << (int)X86Register.R9) |
(1 << (int)X86Register.R10) | (1 << (int)X86Register.R10) |
(1 << (int)X86Register.R11); (1 << (int)X86Register.R11);
#pragma warning restore IDE0055
} }
} }

View File

@ -1,14 +1,14 @@
using ARMeilleure.CodeGen.RegisterAllocators; using ARMeilleure.CodeGen.RegisterAllocators;
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using Microsoft.IO;
using Ryujinx.Common.Memory; using Ryujinx.Common.Memory;
using System.IO;
using System.Numerics; using System.Numerics;
namespace ARMeilleure.CodeGen.X86 namespace ARMeilleure.CodeGen.X86
{ {
class CodeGenContext class CodeGenContext
{ {
private readonly Stream _stream; private readonly RecyclableMemoryStream _stream;
private readonly Operand[] _blockLabels; private readonly Operand[] _blockLabels;
public int StreamOffset => (int)_stream.Length; public int StreamOffset => (int)_stream.Length;

View File

@ -175,8 +175,8 @@ namespace ARMeilleure.CodeGen.X86
// The only blocks which can have 0 successors are exit blocks. // The only blocks which can have 0 successors are exit blocks.
Operation last = block.Operations.Last; Operation last = block.Operations.Last;
Debug.Assert(last.Instruction == Instruction.Tailcall || Debug.Assert(last.Instruction is Instruction.Tailcall or
last.Instruction == Instruction.Return); Instruction.Return);
} }
else else
{ {
@ -478,7 +478,7 @@ namespace ARMeilleure.CodeGen.X86
Debug.Assert(HardwareCapabilities.SupportsVexEncoding); Debug.Assert(HardwareCapabilities.SupportsVexEncoding);
Debug.Assert(dest.Kind == OperandKind.Register && src1.Kind == OperandKind.Register && src2.Kind == OperandKind.Register); Debug.Assert(dest.Kind == OperandKind.Register && src1.Kind == OperandKind.Register && src2.Kind == OperandKind.Register);
Debug.Assert(src3.Kind == OperandKind.Register || src3.Kind == OperandKind.Memory); Debug.Assert(src3.Kind is OperandKind.Register or OperandKind.Memory);
EnsureSameType(dest, src1, src2, src3); EnsureSameType(dest, src1, src2, src3);
Debug.Assert(dest.Type == OperandType.V128); Debug.Assert(dest.Type == OperandType.V128);
@ -788,7 +788,7 @@ namespace ARMeilleure.CodeGen.X86
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64); Debug.Assert(dest.Type is OperandType.FP32 or OperandType.FP64);
if (dest.Type == OperandType.FP32) if (dest.Type == OperandType.FP32)
{ {
@ -1723,7 +1723,7 @@ namespace ARMeilleure.CodeGen.X86
return; return;
} }
Debug.Assert(op1.Kind == OperandKind.Register || op1.Kind == OperandKind.Memory); Debug.Assert(op1.Kind is OperandKind.Register or OperandKind.Memory);
Debug.Assert(op1.Kind == op2.Kind); Debug.Assert(op1.Kind == op2.Kind);
Debug.Assert(op1.Value == op2.Value); Debug.Assert(op1.Value == op2.Value);
} }

View File

@ -66,6 +66,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
PreAllocatorSystemV.InsertCallCopies(block.Operations, node); PreAllocatorSystemV.InsertCallCopies(block.Operations, node);
} }
break; break;
case Instruction.ConvertToFPUI: case Instruction.ConvertToFPUI:
@ -81,6 +82,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
nextNode = PreAllocatorSystemV.InsertLoadArgumentCopy(cctx, ref buffer, block.Operations, preservedArgs, node); nextNode = PreAllocatorSystemV.InsertLoadArgumentCopy(cctx, ref buffer, block.Operations, preservedArgs, node);
} }
break; break;
case Instruction.Negate: case Instruction.Negate:
@ -88,6 +90,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
GenerateNegate(block.Operations, node); GenerateNegate(block.Operations, node);
} }
break; break;
case Instruction.Return: case Instruction.Return:
@ -99,6 +102,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
PreAllocatorSystemV.InsertReturnCopy(block.Operations, node); PreAllocatorSystemV.InsertReturnCopy(block.Operations, node);
} }
break; break;
case Instruction.Tailcall: case Instruction.Tailcall:
@ -110,6 +114,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
PreAllocatorSystemV.InsertTailcallCopies(block.Operations, node); PreAllocatorSystemV.InsertTailcallCopies(block.Operations, node);
} }
break; break;
case Instruction.VectorInsert8: case Instruction.VectorInsert8:
@ -117,6 +122,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
GenerateVectorInsert8(block.Operations, node); GenerateVectorInsert8(block.Operations, node);
} }
break; break;
case Instruction.Extended: case Instruction.Extended:
@ -132,6 +138,7 @@ namespace ARMeilleure.CodeGen.X86
node.SetSources([Const(stackOffset)]); node.SetSources([Const(stackOffset)]);
} }
break; break;
} }
} }
@ -312,9 +319,9 @@ namespace ARMeilleure.CodeGen.X86
case Instruction.Extended: case Instruction.Extended:
{ {
bool isBlend = node.Intrinsic == Intrinsic.X86Blendvpd || bool isBlend = node.Intrinsic is Intrinsic.X86Blendvpd or
node.Intrinsic == Intrinsic.X86Blendvps || Intrinsic.X86Blendvps or
node.Intrinsic == Intrinsic.X86Pblendvb; Intrinsic.X86Pblendvb;
// BLENDVPD, BLENDVPS, PBLENDVB last operand is always implied to be XMM0 when VEX is not supported. // BLENDVPD, BLENDVPS, PBLENDVB last operand is always implied to be XMM0 when VEX is not supported.
// SHA256RNDS2 always has an implied XMM0 as a last operand. // SHA256RNDS2 always has an implied XMM0 as a last operand.
@ -513,8 +520,8 @@ namespace ARMeilleure.CodeGen.X86
Operand dest = node.Destination; Operand dest = node.Destination;
Operand source = node.GetSource(0); Operand source = node.GetSource(0);
Debug.Assert(dest.Type == OperandType.FP32 || Debug.Assert(dest.Type is OperandType.FP32 or
dest.Type == OperandType.FP64, $"Invalid destination type \"{dest.Type}\"."); OperandType.FP64, $"Invalid destination type \"{dest.Type}\".");
Operation currentNode = node; Operation currentNode = node;
@ -761,7 +768,7 @@ namespace ARMeilleure.CodeGen.X86
Comparison compType = (Comparison)comp.AsInt32(); Comparison compType = (Comparison)comp.AsInt32();
return compType == Comparison.Equal || compType == Comparison.NotEqual; return compType is Comparison.Equal or Comparison.NotEqual;
} }
} }

View File

@ -248,12 +248,12 @@ namespace ARMeilleure.CodeGen.X86
private static bool IsMemoryLoadOrStore(Instruction inst) private static bool IsMemoryLoadOrStore(Instruction inst)
{ {
return inst == Instruction.Load || return inst is Instruction.Load or
inst == Instruction.Load16 || Instruction.Load16 or
inst == Instruction.Load8 || Instruction.Load8 or
inst == Instruction.Store || Instruction.Store or
inst == Instruction.Store16 || Instruction.Store16 or
inst == Instruction.Store8; Instruction.Store8;
} }
} }
} }

View File

@ -1,8 +1,5 @@
using System.Diagnostics.CodeAnalysis;
namespace ARMeilleure.CodeGen.X86 namespace ARMeilleure.CodeGen.X86
{ {
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
enum X86Register enum X86Register
{ {
Invalid = -1, Invalid = -1,

View File

@ -254,8 +254,8 @@ namespace ARMeilleure.Decoders
} }
// Compare and branch instructions are always conditional. // Compare and branch instructions are always conditional.
if (opCode.Instruction.Name == InstName.Cbz || if (opCode.Instruction.Name is InstName.Cbz or
opCode.Instruction.Name == InstName.Cbnz) InstName.Cbnz)
{ {
return false; return false;
} }
@ -274,9 +274,10 @@ namespace ARMeilleure.Decoders
{ {
if (opCode is OpCodeT32) if (opCode is OpCodeT32)
{ {
return opCode.Instruction.Name != InstName.Tst && opCode.Instruction.Name != InstName.Teq && return opCode.Instruction.Name is not InstName.Tst and not InstName.Teq and
opCode.Instruction.Name != InstName.Cmp && opCode.Instruction.Name != InstName.Cmn; not InstName.Cmp and not InstName.Cmn;
} }
return true; return true;
} }
@ -284,7 +285,7 @@ namespace ARMeilleure.Decoders
// register (Rt == 15 or (mask & (1 << 15)) != 0), and cases where there is // register (Rt == 15 or (mask & (1 << 15)) != 0), and cases where there is
// a write back to PC (wback == true && Rn == 15), however the later may // a write back to PC (wback == true && Rn == 15), however the later may
// be "undefined" depending on the CPU, so compilers should not produce that. // be "undefined" depending on the CPU, so compilers should not produce that.
if (opCode is IOpCode32Mem || opCode is IOpCode32MemMult) if (opCode is IOpCode32Mem or IOpCode32MemMult)
{ {
int rt, rn; int rt, rn;
@ -326,15 +327,15 @@ namespace ARMeilleure.Decoders
} }
// Explicit branch instructions. // Explicit branch instructions.
return opCode is IOpCode32BImm || return opCode is IOpCode32BImm or
opCode is IOpCode32BReg; IOpCode32BReg;
} }
private static bool IsCall(OpCode opCode) private static bool IsCall(OpCode opCode)
{ {
return opCode.Instruction.Name == InstName.Bl || return opCode.Instruction.Name is InstName.Bl or
opCode.Instruction.Name == InstName.Blr || InstName.Blr or
opCode.Instruction.Name == InstName.Blx; InstName.Blx;
} }
private static bool IsException(OpCode opCode) private static bool IsException(OpCode opCode)
@ -344,9 +345,9 @@ namespace ARMeilleure.Decoders
private static bool IsTrap(OpCode opCode) private static bool IsTrap(OpCode opCode)
{ {
return opCode.Instruction.Name == InstName.Brk || return opCode.Instruction.Name is InstName.Brk or
opCode.Instruction.Name == InstName.Trap || InstName.Trap or
opCode.Instruction.Name == InstName.Und; InstName.Und;
} }
public static OpCode DecodeOpCode(IMemoryManager memory, ulong address, ExecutionMode mode) public static OpCode DecodeOpCode(IMemoryManager memory, ulong address, ExecutionMode mode)

View File

@ -162,6 +162,7 @@ namespace ARMeilleure.Decoders
} }
} }
} }
return false; return false;
} }
} }

View File

@ -20,6 +20,7 @@ namespace ARMeilleure.Decoders
Instruction = InstDescriptor.Undefined; Instruction = InstDescriptor.Undefined;
return; return;
} }
Q = ((opCode >> 21) & 0x1) != 0; Q = ((opCode >> 21) & 0x1) != 0;
RegisterSize = Q ? RegisterSize.Simd128 : RegisterSize.Simd64; RegisterSize = Q ? RegisterSize.Simd128 : RegisterSize.Simd64;

View File

@ -40,7 +40,7 @@ namespace ARMeilleure.Decoders
Rn = (opCode >> 16) & 0xf; Rn = (opCode >> 16) & 0xf;
WBack = Rm != RegisterAlias.Aarch32Pc; WBack = Rm != RegisterAlias.Aarch32Pc;
RegisterIndex = Rm != RegisterAlias.Aarch32Pc && Rm != RegisterAlias.Aarch32Sp; RegisterIndex = Rm is not RegisterAlias.Aarch32Pc and not RegisterAlias.Aarch32Sp;
Regs = _regsMap[(opCode >> 8) & 0xf]; Regs = _regsMap[(opCode >> 8) & 0xf];

View File

@ -45,7 +45,7 @@ namespace ARMeilleure.Decoders
Rn = (opCode >> 16) & 0xf; Rn = (opCode >> 16) & 0xf;
WBack = Rm != RegisterAlias.Aarch32Pc; WBack = Rm != RegisterAlias.Aarch32Pc;
RegisterIndex = Rm != RegisterAlias.Aarch32Pc && Rm != RegisterAlias.Aarch32Sp; RegisterIndex = Rm is not RegisterAlias.Aarch32Pc and not RegisterAlias.Aarch32Sp;
} }
} }
} }

View File

@ -28,8 +28,8 @@ namespace ARMeilleure.Decoders
MemOp type = WBack ? (MemOp)((opCode >> 10) & 3) : MemOp.Unsigned; MemOp type = WBack ? (MemOp)((opCode >> 10) & 3) : MemOp.Unsigned;
PostIdx = type == MemOp.PostIndexed; PostIdx = type == MemOp.PostIndexed;
Unscaled = type == MemOp.Unscaled || Unscaled = type is MemOp.Unscaled or
type == MemOp.Unprivileged; MemOp.Unprivileged;
// Unscaled and Unprivileged doesn't write back, // Unscaled and Unprivileged doesn't write back,
// but they do use the 9-bits Signed Immediate. // but they do use the 9-bits Signed Immediate.

View File

@ -1381,6 +1381,7 @@ namespace ARMeilleure.Decoders
{ {
thumbEncoding = $"1110{thumbEncoding.AsSpan(4)}"; thumbEncoding = $"1110{thumbEncoding.AsSpan(4)}";
} }
SetT32(thumbEncoding, name, emitter, makeOpT32); SetT32(thumbEncoding, name, emitter, makeOpT32);
} }
@ -1409,6 +1410,7 @@ namespace ARMeilleure.Decoders
{ {
throw new ArgumentException("Invalid ASIMD instruction encoding"); throw new ArgumentException("Invalid ASIMD instruction encoding");
} }
SetT32(thumbEncoding, name, emitter, makeOpT32); SetT32(thumbEncoding, name, emitter, makeOpT32);
} }

View File

@ -9,7 +9,7 @@ namespace ARMeilleure.Diagnostics
{ {
class IRDumper class IRDumper
{ {
private const string Indentation = " "; private const char Indentation = ' ';
private int _indentLevel; private int _indentLevel;
@ -30,14 +30,11 @@ namespace ARMeilleure.Diagnostics
private void Indent() private void Indent()
{ {
_builder.EnsureCapacity(_builder.Capacity + _indentLevel * Indentation.Length); if (_indentLevel == 0)
return;
for (int index = 0; index < _indentLevel; index++) _builder.EnsureCapacity(_builder.Capacity + _indentLevel);
{ _builder.Append(Indentation, _indentLevel);
#pragma warning disable CA1834 // Use StringBuilder.Append(char) for single character strings
_builder.Append(Indentation);
#pragma warning restore CA1834
}
} }
private void IncreaseIndentation() private void IncreaseIndentation()
@ -235,8 +232,8 @@ namespace ARMeilleure.Diagnostics
{ {
_builder.Append('.').Append(operation.Intrinsic); _builder.Append('.').Append(operation.Intrinsic);
} }
else if (operation.Instruction == Instruction.BranchIf || else if (operation.Instruction is Instruction.BranchIf or
operation.Instruction == Instruction.Compare) Instruction.Compare)
{ {
comparison = true; comparison = true;
} }
@ -262,6 +259,7 @@ namespace ARMeilleure.Diagnostics
DumpOperand(source); DumpOperand(source);
} }
} }
break; break;
} }

View File

@ -8,8 +8,8 @@ namespace ARMeilleure.Instructions
static class CryptoHelper static class CryptoHelper
{ {
#region "LookUp Tables" #region "LookUp Tables"
#pragma warning disable IDE1006 // Naming rule violation
private static ReadOnlySpan<byte> _sBox => private static ReadOnlySpan<byte> SBox =>
[ [
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
@ -29,7 +29,7 @@ namespace ARMeilleure.Instructions
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
]; ];
private static ReadOnlySpan<byte> _invSBox => private static ReadOnlySpan<byte> InvSBox =>
[ [
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
@ -49,7 +49,7 @@ namespace ARMeilleure.Instructions
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
]; ];
private static ReadOnlySpan<byte> _gfMul02 => private static ReadOnlySpan<byte> GfMul02 =>
[ [
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
@ -69,7 +69,7 @@ namespace ARMeilleure.Instructions
0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5
]; ];
private static ReadOnlySpan<byte> _gfMul03 => private static ReadOnlySpan<byte> GfMul03 =>
[ [
0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11, 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
@ -89,7 +89,7 @@ namespace ARMeilleure.Instructions
0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a
]; ];
private static ReadOnlySpan<byte> _gfMul09 => private static ReadOnlySpan<byte> GfMul09 =>
[ [
0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
@ -109,7 +109,7 @@ namespace ARMeilleure.Instructions
0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46 0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46
]; ];
private static ReadOnlySpan<byte> _gfMul0B => private static ReadOnlySpan<byte> GfMul0B =>
[ [
0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69, 0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
@ -129,7 +129,7 @@ namespace ARMeilleure.Instructions
0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3 0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3
]; ];
private static ReadOnlySpan<byte> _gfMul0D => private static ReadOnlySpan<byte> GfMul0D =>
[ [
0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b, 0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
@ -149,7 +149,7 @@ namespace ARMeilleure.Instructions
0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97 0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97
]; ];
private static ReadOnlySpan<byte> _gfMul0E => private static ReadOnlySpan<byte> GfMul0E =>
[ [
0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a, 0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
@ -169,16 +169,16 @@ namespace ARMeilleure.Instructions
0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d
]; ];
private static ReadOnlySpan<byte> _srPerm => private static ReadOnlySpan<byte> SrPerm =>
[ [
0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3 0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3
]; ];
private static ReadOnlySpan<byte> _isrPerm => private static ReadOnlySpan<byte> IsrPerm =>
[ [
0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11
]; ];
#pragma warning restore IDE1006
#endregion #endregion
public static V128 AesInvMixColumns(V128 op) public static V128 AesInvMixColumns(V128 op)
@ -195,10 +195,10 @@ namespace ARMeilleure.Instructions
byte row2 = inState[idx + 2]; // C, G, K, O: [row2, col0-col3] byte row2 = inState[idx + 2]; // C, G, K, O: [row2, col0-col3]
byte row3 = inState[idx + 3]; // D, H, L, P: [row3, col0-col3] byte row3 = inState[idx + 3]; // D, H, L, P: [row3, col0-col3]
outState[idx + 0] = (byte)((uint)_gfMul0E[row0] ^ _gfMul0B[row1] ^ _gfMul0D[row2] ^ _gfMul09[row3]); outState[idx + 0] = (byte)((uint)GfMul0E[row0] ^ GfMul0B[row1] ^ GfMul0D[row2] ^ GfMul09[row3]);
outState[idx + 1] = (byte)((uint)_gfMul09[row0] ^ _gfMul0E[row1] ^ _gfMul0B[row2] ^ _gfMul0D[row3]); outState[idx + 1] = (byte)((uint)GfMul09[row0] ^ GfMul0E[row1] ^ GfMul0B[row2] ^ GfMul0D[row3]);
outState[idx + 2] = (byte)((uint)_gfMul0D[row0] ^ _gfMul09[row1] ^ _gfMul0E[row2] ^ _gfMul0B[row3]); outState[idx + 2] = (byte)((uint)GfMul0D[row0] ^ GfMul09[row1] ^ GfMul0E[row2] ^ GfMul0B[row3]);
outState[idx + 3] = (byte)((uint)_gfMul0B[row0] ^ _gfMul0D[row1] ^ _gfMul09[row2] ^ _gfMul0E[row3]); outState[idx + 3] = (byte)((uint)GfMul0B[row0] ^ GfMul0D[row1] ^ GfMul09[row2] ^ GfMul0E[row3]);
} }
return new V128(outState); return new V128(outState);
@ -211,7 +211,7 @@ namespace ARMeilleure.Instructions
for (int idx = 0; idx <= 15; idx++) for (int idx = 0; idx <= 15; idx++)
{ {
outState[_isrPerm[idx]] = inState[idx]; outState[IsrPerm[idx]] = inState[idx];
} }
return new V128(outState); return new V128(outState);
@ -224,7 +224,7 @@ namespace ARMeilleure.Instructions
for (int idx = 0; idx <= 15; idx++) for (int idx = 0; idx <= 15; idx++)
{ {
outState[idx] = _invSBox[inState[idx]]; outState[idx] = InvSBox[inState[idx]];
} }
return new V128(outState); return new V128(outState);
@ -244,10 +244,10 @@ namespace ARMeilleure.Instructions
byte row2 = inState[idx + 2]; // C, G, K, O: [row2, col0-col3] byte row2 = inState[idx + 2]; // C, G, K, O: [row2, col0-col3]
byte row3 = inState[idx + 3]; // D, H, L, P: [row3, col0-col3] byte row3 = inState[idx + 3]; // D, H, L, P: [row3, col0-col3]
outState[idx + 0] = (byte)((uint)_gfMul02[row0] ^ _gfMul03[row1] ^ row2 ^ row3); outState[idx + 0] = (byte)((uint)GfMul02[row0] ^ GfMul03[row1] ^ row2 ^ row3);
outState[idx + 1] = (byte)((uint)row0 ^ _gfMul02[row1] ^ _gfMul03[row2] ^ row3); outState[idx + 1] = (byte)((uint)row0 ^ GfMul02[row1] ^ GfMul03[row2] ^ row3);
outState[idx + 2] = (byte)((uint)row0 ^ row1 ^ _gfMul02[row2] ^ _gfMul03[row3]); outState[idx + 2] = (byte)((uint)row0 ^ row1 ^ GfMul02[row2] ^ GfMul03[row3]);
outState[idx + 3] = (byte)((uint)_gfMul03[row0] ^ row1 ^ row2 ^ _gfMul02[row3]); outState[idx + 3] = (byte)((uint)GfMul03[row0] ^ row1 ^ row2 ^ GfMul02[row3]);
} }
return new V128(outState); return new V128(outState);
@ -260,7 +260,7 @@ namespace ARMeilleure.Instructions
for (int idx = 0; idx <= 15; idx++) for (int idx = 0; idx <= 15; idx++)
{ {
outState[_srPerm[idx]] = inState[idx]; outState[SrPerm[idx]] = inState[idx];
} }
return new V128(outState); return new V128(outState);
@ -273,7 +273,7 @@ namespace ARMeilleure.Instructions
for (int idx = 0; idx <= 15; idx++) for (int idx = 0; idx <= 15; idx++)
{ {
outState[idx] = _sBox[inState[idx]]; outState[idx] = SBox[inState[idx]];
} }
return new V128(outState); return new V128(outState);

View File

@ -899,6 +899,7 @@ namespace ARMeilleure.Instructions
{ {
n = context.ShiftLeft(n, Const(shift)); n = context.ShiftLeft(n, Const(shift));
} }
break; break;
case ShiftType.Asr: case ShiftType.Asr:
if (shift == 32) if (shift == 32)
@ -909,6 +910,7 @@ namespace ARMeilleure.Instructions
{ {
n = context.ShiftRightSI(n, Const(shift)); n = context.ShiftRightSI(n, Const(shift));
} }
break; break;
} }

View File

@ -266,7 +266,7 @@ namespace ARMeilleure.Instructions
} }
} }
private static Exception InvalidOpCodeType(OpCode opCode) private static InvalidOperationException InvalidOpCodeType(OpCode opCode)
{ {
return new InvalidOperationException($"Invalid OpCode type \"{opCode?.GetType().Name ?? "null"}\"."); return new InvalidOperationException($"Invalid OpCode type \"{opCode?.GetType().Name ?? "null"}\".");
} }
@ -318,6 +318,7 @@ namespace ARMeilleure.Instructions
{ {
m = GetRrxC(context, m, setCarry); m = GetRrxC(context, m, setCarry);
} }
break; break;
} }
} }

View File

@ -17,7 +17,7 @@ namespace ARMeilleure.Instructions
public static Operand EmitCrc32(ArmEmitterContext context, Operand crc, Operand value, int size, bool castagnoli) public static Operand EmitCrc32(ArmEmitterContext context, Operand crc, Operand value, int size, bool castagnoli)
{ {
Debug.Assert(crc.Type.IsInteger() && value.Type.IsInteger()); Debug.Assert(crc.Type.IsInteger() && value.Type.IsInteger());
Debug.Assert(size >= 0 && size < 4); Debug.Assert(size is >= 0 and < 4);
Debug.Assert((size < 3) || (value.Type == OperandType.I64)); Debug.Assert((size < 3) || (value.Type == OperandType.I64));
if (castagnoli && Optimizations.UseSse42) if (castagnoli && Optimizations.UseSse42)

View File

@ -90,6 +90,7 @@ namespace ARMeilleure.Instructions
{ {
value = context.ConvertI64ToI32(value); value = context.ConvertI64ToI32(value);
} }
Operand reg = Register(GetRegisterAlias(context.Mode, regIndex), RegisterType.Integer, OperandType.I32); Operand reg = Register(GetRegisterAlias(context.Mode, regIndex), RegisterType.Integer, OperandType.I32);
context.Copy(reg, value); context.Copy(reg, value);

View File

@ -140,7 +140,7 @@ namespace ARMeilleure.Instructions
if (pair) if (pair)
{ {
Debug.Assert(op.Size == 2 || op.Size == 3, "Invalid size for pairwise store."); Debug.Assert(op.Size is 2 or 3, "Invalid size for pairwise store.");
Operand t2 = GetIntOrZR(context, op.Rt2); Operand t2 = GetIntOrZR(context, op.Rt2);

View File

@ -42,6 +42,7 @@ namespace ARMeilleure.Instructions
{ {
context.Store(exValuePtr, Const(0UL)); context.Store(exValuePtr, Const(0UL));
} }
if (size < 4) if (size < 4)
{ {
context.Store(context.Add(exValuePtr, Const(exValuePtr.Type, 8L)), Const(0UL)); context.Store(context.Add(exValuePtr, Const(exValuePtr.Type, 8L)), Const(0UL));

View File

@ -59,7 +59,7 @@ namespace ARMeilleure.Instructions
{ {
Operand value = GetInt(context, rt); Operand value = GetInt(context, rt);
if (ext == Extension.Sx32 || ext == Extension.Sx64) if (ext is Extension.Sx32 or Extension.Sx64)
{ {
OperandType destType = ext == Extension.Sx64 ? OperandType.I64 : OperandType.I32; OperandType destType = ext == Extension.Sx64 ? OperandType.I64 : OperandType.I32;
@ -123,9 +123,9 @@ namespace ARMeilleure.Instructions
private static bool IsSimd(ArmEmitterContext context) private static bool IsSimd(ArmEmitterContext context)
{ {
return context.CurrOp is IOpCodeSimd && return context.CurrOp is IOpCodeSimd and
!(context.CurrOp is OpCodeSimdMemMs || not (OpCodeSimdMemMs or
context.CurrOp is OpCodeSimdMemSs); OpCodeSimdMemSs);
} }
public static Operand EmitReadInt(ArmEmitterContext context, Operand address, int size) public static Operand EmitReadInt(ArmEmitterContext context, Operand address, int size)
@ -717,7 +717,7 @@ namespace ARMeilleure.Instructions
}; };
} }
private static Exception InvalidOpCodeType(OpCode opCode) private static InvalidOperationException InvalidOpCodeType(OpCode opCode)
{ {
return new InvalidOperationException($"Invalid OpCode type \"{opCode?.GetType().Name ?? "null"}\"."); return new InvalidOperationException($"Invalid OpCode type \"{opCode?.GetType().Name ?? "null"}\".");
} }
@ -768,6 +768,7 @@ namespace ARMeilleure.Instructions
{ {
m = InstEmitAluHelper.GetRrxC(context, m, setCarry); m = InstEmitAluHelper.GetRrxC(context, m, setCarry);
} }
break; break;
} }
} }

View File

@ -2,7 +2,6 @@ using ARMeilleure.Decoders;
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation; using ARMeilleure.Translation;
using System; using System;
using System.Diagnostics.CodeAnalysis;
using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitHelper;
namespace ARMeilleure.Instructions namespace ARMeilleure.Instructions
@ -33,7 +32,6 @@ namespace ARMeilleure.Instructions
public static void Umsubl(ArmEmitterContext context) => EmitMull(context, MullFlags.Subtract); public static void Umsubl(ArmEmitterContext context) => EmitMull(context, MullFlags.Subtract);
[Flags] [Flags]
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
private enum MullFlags private enum MullFlags
{ {
Subtract = 0, Subtract = 0,

View File

@ -11,11 +11,10 @@ using static ARMeilleure.Instructions.InstEmitHelper;
using static ARMeilleure.Instructions.InstEmitSimdHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper;
using static ARMeilleure.Instructions.InstEmitSimdHelper32; using static ARMeilleure.Instructions.InstEmitSimdHelper32;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
using Func2I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
namespace ARMeilleure.Instructions namespace ARMeilleure.Instructions
{ {
using Func2I = Func<Operand, Operand, Operand>;
static partial class InstEmit static partial class InstEmit
{ {
public static void Abs_S(ArmEmitterContext context) public static void Abs_S(ArmEmitterContext context)
@ -5266,7 +5265,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitSse2Sll_128(ArmEmitterContext context, Operand op, int shift) private static Operand EmitSse2Sll_128(ArmEmitterContext context, Operand op, int shift)
{ {
// The upper part of op is assumed to be zero. // The upper part of op is assumed to be zero.
Debug.Assert(shift >= 0 && shift < 64); Debug.Assert(shift is >= 0 and < 64);
if (shift == 0) if (shift == 0)
{ {

View File

@ -231,10 +231,12 @@ namespace ARMeilleure.Instructions
{ {
result |= (long)((i >= end || i < start) ? 0x80 : b++) << (i * 8); result |= (long)((i >= end || i < start) ? 0x80 : b++) << (i * 8);
} }
for (int i = 8; i < 16; i++) for (int i = 8; i < 16; i++)
{ {
result2 |= (long)((i >= end || i < start) ? 0x80 : b++) << ((i - 8) * 8); result2 |= (long)((i >= end || i < start) ? 0x80 : b++) << ((i - 8) * 8);
} }
return (result2, result); return (result2, result);
} }
@ -261,6 +263,7 @@ namespace ARMeilleure.Instructions
nMaskHigh = nMaskLow + 0x0808080808080808L; nMaskHigh = nMaskLow + 0x0808080808080808L;
mMaskHigh = mMaskLow + 0x0808080808080808L; mMaskHigh = mMaskLow + 0x0808080808080808L;
} }
nMask = X86GetElements(context, nMaskHigh, nMaskLow); nMask = X86GetElements(context, nMaskHigh, nMaskLow);
mMask = X86GetElements(context, mMaskHigh, mMaskLow); mMask = X86GetElements(context, mMaskHigh, mMaskLow);
Operand nPart = context.AddIntrinsic(Intrinsic.X86Pshufb, n, nMask); Operand nPart = context.AddIntrinsic(Intrinsic.X86Pshufb, n, nMask);
@ -285,6 +288,7 @@ namespace ARMeilleure.Instructions
{ {
extract = EmitVectorExtractZx32(context, op.Qn, op.In + byteOff, op.Size); extract = EmitVectorExtractZx32(context, op.Qn, op.In + byteOff, op.Size);
} }
byteOff++; byteOff++;
res = EmitVectorInsert(context, res, extract, op.Id + index, op.Size); res = EmitVectorInsert(context, res, extract, op.Id + index, op.Size);
@ -1304,6 +1308,7 @@ namespace ARMeilleure.Instructions
case 2: case 2:
return context.AddIntrinsic(Intrinsic.X86Shufps, op1, op1, Const(1 | (0 << 2) | (3 << 4) | (2 << 6))); return context.AddIntrinsic(Intrinsic.X86Shufps, op1, op1, Const(1 | (0 << 2) | (3 << 4) | (2 << 6)));
} }
break; break;
case 2: case 2:
// Rev32 // Rev32
@ -1316,6 +1321,7 @@ namespace ARMeilleure.Instructions
mask = X86GetElements(context, 0x0d0c0f0e_09080b0aL, 0x05040706_01000302L); mask = X86GetElements(context, 0x0d0c0f0e_09080b0aL, 0x05040706_01000302L);
return context.AddIntrinsic(Intrinsic.X86Pshufb, op1, mask); return context.AddIntrinsic(Intrinsic.X86Pshufb, op1, mask);
} }
break; break;
case 1: case 1:
// Rev16 // Rev16
@ -1341,6 +1347,7 @@ namespace ARMeilleure.Instructions
case 3: case 3:
return context.ByteSwap(op1); return context.ByteSwap(op1);
} }
break; break;
case 1: case 1:
switch (op.Size) switch (op.Size)
@ -1355,6 +1362,7 @@ namespace ARMeilleure.Instructions
context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(op1, Const(0x0000ffff00000000ul)), Const(16)), context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(op1, Const(0x0000ffff00000000ul)), Const(16)),
context.ShiftLeft(context.BitwiseAnd(op1, Const(0x00000000ffff0000ul)), Const(16)))); context.ShiftLeft(context.BitwiseAnd(op1, Const(0x00000000ffff0000ul)), Const(16))));
} }
break; break;
case 2: case 2:
// Swap upper and lower halves. // Swap upper and lower halves.

View File

@ -2,15 +2,13 @@ using ARMeilleure.Decoders;
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.State; using ARMeilleure.State;
using ARMeilleure.Translation; using ARMeilleure.Translation;
using System;
using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitHelper;
using static ARMeilleure.Instructions.InstEmitSimdHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
using Func2I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
namespace ARMeilleure.Instructions namespace ARMeilleure.Instructions
{ {
using Func2I = Func<Operand, Operand, Operand>;
static partial class InstEmit static partial class InstEmit
{ {
public static void Cmeq_S(ArmEmitterContext context) public static void Cmeq_S(ArmEmitterContext context)

View File

@ -2,17 +2,15 @@ using ARMeilleure.Decoders;
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.State; using ARMeilleure.State;
using ARMeilleure.Translation; using ARMeilleure.Translation;
using System;
using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitHelper;
using static ARMeilleure.Instructions.InstEmitSimdHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper;
using static ARMeilleure.Instructions.InstEmitSimdHelper32; using static ARMeilleure.Instructions.InstEmitSimdHelper32;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
using Func2I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
namespace ARMeilleure.Instructions namespace ARMeilleure.Instructions
{ {
using Func2I = Func<Operand, Operand, Operand>;
static partial class InstEmit32 static partial class InstEmit32
{ {
public static void Vceq_V(ArmEmitterContext context) public static void Vceq_V(ArmEmitterContext context)

View File

@ -8,11 +8,10 @@ using System.Reflection;
using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitHelper;
using static ARMeilleure.Instructions.InstEmitSimdHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
using Func1I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
namespace ARMeilleure.Instructions namespace ARMeilleure.Instructions
{ {
using Func1I = Func<Operand, Operand>;
static partial class InstEmit static partial class InstEmit
{ {
public static void Fcvt_S(ArmEmitterContext context) public static void Fcvt_S(ArmEmitterContext context)
@ -1119,7 +1118,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitFPConvert(ArmEmitterContext context, Operand value, int size, bool signed) private static Operand EmitFPConvert(ArmEmitterContext context, Operand value, int size, bool signed)
{ {
Debug.Assert(value.Type == OperandType.I32 || value.Type == OperandType.I64); Debug.Assert(value.Type is OperandType.I32 or OperandType.I64);
Debug.Assert((uint)size < 2); Debug.Assert((uint)size < 2);
OperandType type = size == 0 ? OperandType.FP32 : OperandType.FP64; OperandType type = size == 0 ? OperandType.FP32 : OperandType.FP64;
@ -1136,7 +1135,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitScalarFcvts(ArmEmitterContext context, Operand value, int fBits) private static Operand EmitScalarFcvts(ArmEmitterContext context, Operand value, int fBits)
{ {
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.FP64); Debug.Assert(value.Type is OperandType.FP32 or OperandType.FP64);
value = EmitF2iFBitsMul(context, value, fBits); value = EmitF2iFBitsMul(context, value, fBits);
@ -1160,7 +1159,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitScalarFcvtu(ArmEmitterContext context, Operand value, int fBits) private static Operand EmitScalarFcvtu(ArmEmitterContext context, Operand value, int fBits)
{ {
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.FP64); Debug.Assert(value.Type is OperandType.FP32 or OperandType.FP64);
value = EmitF2iFBitsMul(context, value, fBits); value = EmitF2iFBitsMul(context, value, fBits);
@ -1184,7 +1183,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitF2iFBitsMul(ArmEmitterContext context, Operand value, int fBits) private static Operand EmitF2iFBitsMul(ArmEmitterContext context, Operand value, int fBits)
{ {
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.FP64); Debug.Assert(value.Type is OperandType.FP32 or OperandType.FP64);
if (fBits == 0) if (fBits == 0)
{ {
@ -1203,7 +1202,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitI2fFBitsMul(ArmEmitterContext context, Operand value, int fBits) private static Operand EmitI2fFBitsMul(ArmEmitterContext context, Operand value, int fBits)
{ {
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.FP64); Debug.Assert(value.Type is OperandType.FP32 or OperandType.FP64);
if (fBits == 0) if (fBits == 0)
{ {

View File

@ -385,6 +385,7 @@ namespace ARMeilleure.Instructions
{ {
res = context.AddIntrinsic(Intrinsic.X86Cvtsd2ss, context.VectorZero(), res); res = context.AddIntrinsic(Intrinsic.X86Cvtsd2ss, context.VectorZero(), res);
} }
res = context.AddIntrinsic(Intrinsic.X86Vcvtps2ph, res, Const(X86GetRoundControl(FPRoundingMode.ToNearest))); res = context.AddIntrinsic(Intrinsic.X86Vcvtps2ph, res, Const(X86GetRoundControl(FPRoundingMode.ToNearest)));
res = context.VectorExtract16(res, 0); res = context.VectorExtract16(res, 0);
InsertScalar16(context, op.Vd, op.T, res); InsertScalar16(context, op.Vd, op.T, res);
@ -397,6 +398,7 @@ namespace ARMeilleure.Instructions
{ {
res = context.AddIntrinsic(Intrinsic.X86Cvtss2sd, context.VectorZero(), res); res = context.AddIntrinsic(Intrinsic.X86Cvtss2sd, context.VectorZero(), res);
} }
res = context.VectorExtract(op.Size == 1 ? OperandType.I64 : OperandType.I32, res, 0); res = context.VectorExtract(op.Size == 1 ? OperandType.I64 : OperandType.I32, res, 0);
InsertScalar(context, op.Vd, res); InsertScalar(context, op.Vd, res);
} }
@ -635,7 +637,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitFPConvert(ArmEmitterContext context, Operand value, OperandType type, bool signed) private static Operand EmitFPConvert(ArmEmitterContext context, Operand value, OperandType type, bool signed)
{ {
Debug.Assert(value.Type == OperandType.I32 || value.Type == OperandType.I64); Debug.Assert(value.Type is OperandType.I32 or OperandType.I64);
if (signed) if (signed)
{ {

View File

@ -8,13 +8,12 @@ using System.Diagnostics;
using System.Reflection; using System.Reflection;
using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitHelper;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
using Func1I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
using Func2I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
using Func3I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
namespace ARMeilleure.Instructions namespace ARMeilleure.Instructions
{ {
using Func1I = Func<Operand, Operand>;
using Func2I = Func<Operand, Operand, Operand>;
using Func3I = Func<Operand, Operand, Operand, Operand>;
static class InstEmitSimdHelper static class InstEmitSimdHelper
{ {
#region "Masks" #region "Masks"
@ -363,7 +362,7 @@ namespace ARMeilleure.Instructions
public static Operand EmitCountSetBits8(ArmEmitterContext context, Operand op) // "size" is 8 (SIMD&FP Inst.). public static Operand EmitCountSetBits8(ArmEmitterContext context, Operand op) // "size" is 8 (SIMD&FP Inst.).
{ {
Debug.Assert(op.Type == OperandType.I32 || op.Type == OperandType.I64); Debug.Assert(op.Type is OperandType.I32 or OperandType.I64);
Operand op0 = context.Subtract(op, context.BitwiseAnd(context.ShiftRightUI(op, Const(1)), Const(op.Type, 0x55L))); Operand op0 = context.Subtract(op, context.BitwiseAnd(context.ShiftRightUI(op, Const(1)), Const(op.Type, 0x55L)));
@ -489,7 +488,7 @@ namespace ARMeilleure.Instructions
public static Operand EmitRoundByRMode(ArmEmitterContext context, Operand op) public static Operand EmitRoundByRMode(ArmEmitterContext context, Operand op)
{ {
Debug.Assert(op.Type == OperandType.FP32 || op.Type == OperandType.FP64); Debug.Assert(op.Type is OperandType.FP32 or OperandType.FP64);
Operand lbl1 = Label(); Operand lbl1 = Label();
Operand lbl2 = Label(); Operand lbl2 = Label();
@ -1676,7 +1675,7 @@ namespace ARMeilleure.Instructions
int eSize = 8 << size; int eSize = 8 << size;
Debug.Assert(op.Type == OperandType.I64); Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64); Debug.Assert(eSize is 8 or 16 or 32 or 64);
Operand lbl1 = Label(); Operand lbl1 = Label();
Operand lblEnd = Label(); Operand lblEnd = Label();
@ -1709,7 +1708,7 @@ namespace ARMeilleure.Instructions
int eSize = 8 << size; int eSize = 8 << size;
Debug.Assert(op.Type == OperandType.I64); Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64); Debug.Assert(eSize is 8 or 16 or 32 or 64);
Operand lblEnd = Label(); Operand lblEnd = Label();
@ -1735,7 +1734,7 @@ namespace ARMeilleure.Instructions
int eSizeDst = 8 << sizeDst; int eSizeDst = 8 << sizeDst;
Debug.Assert(op.Type == OperandType.I64); Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSizeDst == 8 || eSizeDst == 16 || eSizeDst == 32); Debug.Assert(eSizeDst is 8 or 16 or 32);
Operand lbl1 = Label(); Operand lbl1 = Label();
Operand lblEnd = Label(); Operand lblEnd = Label();
@ -1768,7 +1767,7 @@ namespace ARMeilleure.Instructions
int eSizeDst = 8 << sizeDst; int eSizeDst = 8 << sizeDst;
Debug.Assert(op.Type == OperandType.I64); Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSizeDst == 8 || eSizeDst == 16 || eSizeDst == 32); Debug.Assert(eSizeDst is 8 or 16 or 32);
Operand lblEnd = Label(); Operand lblEnd = Label();

View File

@ -7,13 +7,12 @@ using System.Reflection;
using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitHelper;
using static ARMeilleure.Instructions.InstEmitSimdHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
using Func1I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
using Func2I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
using Func3I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
namespace ARMeilleure.Instructions namespace ARMeilleure.Instructions
{ {
using Func1I = Func<Operand, Operand>;
using Func2I = Func<Operand, Operand, Operand>;
using Func3I = Func<Operand, Operand, Operand, Operand>;
static class InstEmitSimdHelper32 static class InstEmitSimdHelper32
{ {
public static (int, int) GetQuadwordAndSubindex(int index, RegisterSize size) public static (int, int) GetQuadwordAndSubindex(int index, RegisterSize size)
@ -31,7 +30,7 @@ namespace ARMeilleure.Instructions
{ {
Debug.Assert(type != OperandType.V128); Debug.Assert(type != OperandType.V128);
if (type == OperandType.FP64 || type == OperandType.I64) if (type is OperandType.FP64 or OperandType.I64)
{ {
// From dreg. // From dreg.
return context.VectorExtract(type, GetVecA32(reg >> 1), reg & 1); return context.VectorExtract(type, GetVecA32(reg >> 1), reg & 1);
@ -48,7 +47,7 @@ namespace ARMeilleure.Instructions
Debug.Assert(value.Type != OperandType.V128); Debug.Assert(value.Type != OperandType.V128);
Operand vec, insert; Operand vec, insert;
if (value.Type == OperandType.FP64 || value.Type == OperandType.I64) if (value.Type is OperandType.FP64 or OperandType.I64)
{ {
// From dreg. // From dreg.
vec = GetVecA32(reg >> 1); vec = GetVecA32(reg >> 1);
@ -71,7 +70,7 @@ namespace ARMeilleure.Instructions
public static void InsertScalar16(ArmEmitterContext context, int reg, bool top, Operand value) public static void InsertScalar16(ArmEmitterContext context, int reg, bool top, Operand value)
{ {
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.I32); Debug.Assert(value.Type is OperandType.FP32 or OperandType.I32);
Operand vec, insert; Operand vec, insert;
vec = GetVecA32(reg >> 2); vec = GetVecA32(reg >> 2);
@ -880,6 +879,7 @@ namespace ARMeilleure.Instructions
{ {
res = EmitMoveDoubleWordToSide(context, res, side, op.Vd); res = EmitMoveDoubleWordToSide(context, res, side, op.Vd);
} }
res = EmitDoubleWordInsert(context, d, res, op.Vd); res = EmitDoubleWordInsert(context, d, res, op.Vd);
} }

View File

@ -7,13 +7,12 @@ using System.Diagnostics;
using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitHelper;
using static ARMeilleure.Instructions.InstEmitSimdHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
using Func1I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
using Func2I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
using Func3I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
namespace ARMeilleure.Instructions namespace ARMeilleure.Instructions
{ {
using Func1I = Func<Operand, Operand>;
using Func2I = Func<Operand, Operand, Operand>;
using Func3I = Func<Operand, Operand, Operand, Operand>;
static class InstEmitSimdHelper32Arm64 static class InstEmitSimdHelper32Arm64
{ {
// Intrinsic Helpers // Intrinsic Helpers
@ -146,6 +145,7 @@ namespace ARMeilleure.Instructions
{ {
res = EmitMoveDoubleWordToSide(context, res, side, op.Vd); res = EmitMoveDoubleWordToSide(context, res, side, op.Vd);
} }
res = EmitDoubleWordInsert(context, d, res, op.Vd); res = EmitDoubleWordInsert(context, d, res, op.Vd);
} }

View File

@ -268,6 +268,7 @@ namespace ARMeilleure.Instructions
{ {
m = context.BitwiseNot(m); m = context.BitwiseNot(m);
} }
return context.BitwiseExclusiveOr( return context.BitwiseExclusiveOr(
context.BitwiseAnd(m, context.BitwiseAnd(m,
context.BitwiseExclusiveOr(d, n)), d); context.BitwiseExclusiveOr(d, n)), d);

View File

@ -40,34 +40,36 @@ namespace ARMeilleure.Instructions
long offset = 0; long offset = 0;
#pragma warning disable IDE0055 // Disable formatting for (int rep = 0; rep < op.Reps; rep++)
for (int rep = 0; rep < op.Reps; rep++)
for (int elem = 0; elem < op.Elems; elem++)
for (int sElem = 0; sElem < op.SElems; sElem++)
{ {
int rtt = (op.Rt + rep + sElem) & 0x1f; for (int elem = 0; elem < op.Elems; elem++)
Operand tt = GetVec(rtt);
Operand address = context.Add(n, Const(offset));
if (isLoad)
{ {
EmitLoadSimd(context, address, tt, rtt, elem, op.Size); for (int sElem = 0; sElem < op.SElems; sElem++)
if (op.RegisterSize == RegisterSize.Simd64 && elem == op.Elems - 1)
{ {
context.Copy(tt, context.VectorZeroUpper64(tt)); int rtt = (op.Rt + rep + sElem) & 0x1f;
Operand tt = GetVec(rtt);
Operand address = context.Add(n, Const(offset));
if (isLoad)
{
EmitLoadSimd(context, address, tt, rtt, elem, op.Size);
if (op.RegisterSize == RegisterSize.Simd64 && elem == op.Elems - 1)
{
context.Copy(tt, context.VectorZeroUpper64(tt));
}
}
else
{
EmitStoreSimd(context, address, rtt, elem, op.Size);
}
offset += 1 << op.Size;
} }
} }
else
{
EmitStoreSimd(context, address, rtt, elem, op.Size);
}
offset += 1 << op.Size;
} }
#pragma warning restore IDE0055
if (op.WBack) if (op.WBack)
{ {

View File

@ -110,6 +110,7 @@ namespace ARMeilleure.Instructions
EmitStoreSimd(context, address, d >> 1, index, op.Size); EmitStoreSimd(context, address, d >> 1, index, op.Size);
} }
} }
offset += eBytes; offset += eBytes;
d += op.Increment; d += op.Increment;
} }

View File

@ -9,11 +9,10 @@ using System.Reflection;
using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitHelper;
using static ARMeilleure.Instructions.InstEmitSimdHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
using Func2I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
namespace ARMeilleure.Instructions namespace ARMeilleure.Instructions
{ {
using Func2I = Func<Operand, Operand, Operand>;
static partial class InstEmit static partial class InstEmit
{ {
#region "Masks" #region "Masks"
@ -1634,7 +1633,7 @@ namespace ARMeilleure.Instructions
int eSize = 8 << size; int eSize = 8 << size;
Debug.Assert(op.Type == OperandType.I64); Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64); Debug.Assert(eSize is 8 or 16 or 32 or 64);
Operand res = context.AllocateLocal(OperandType.I64); Operand res = context.AllocateLocal(OperandType.I64);
@ -1657,7 +1656,7 @@ namespace ARMeilleure.Instructions
int eSize = 8 << size; int eSize = 8 << size;
Debug.Assert(op.Type == OperandType.I64); Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64); Debug.Assert(eSize is 8 or 16 or 32 or 64);
Operand lblEnd = Label(); Operand lblEnd = Label();
@ -1732,7 +1731,7 @@ namespace ARMeilleure.Instructions
Debug.Assert(op.Type == OperandType.I64); Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(shiftLsB.Type == OperandType.I32); Debug.Assert(shiftLsB.Type == OperandType.I32);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64); Debug.Assert(eSize is 8 or 16 or 32 or 64);
Operand lbl1 = Label(); Operand lbl1 = Label();
Operand lblEnd = Label(); Operand lblEnd = Label();
@ -1769,7 +1768,7 @@ namespace ARMeilleure.Instructions
Debug.Assert(op.Type == OperandType.I64); Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(shiftLsB.Type == OperandType.I32); Debug.Assert(shiftLsB.Type == OperandType.I32);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64); Debug.Assert(eSize is 8 or 16 or 32 or 64);
Operand lbl1 = Label(); Operand lbl1 = Label();
Operand lbl2 = Label(); Operand lbl2 = Label();
@ -1813,6 +1812,7 @@ namespace ARMeilleure.Instructions
? EmitSignedSrcSatQ(context, shl, size, signedDst: true) ? EmitSignedSrcSatQ(context, shl, size, signedDst: true)
: EmitUnsignedSrcSatQ(context, shl, size, signedDst: false)); : EmitUnsignedSrcSatQ(context, shl, size, signedDst: false));
} }
context.Branch(lblEnd); context.Branch(lblEnd);
context.MarkLabel(lblEnd); context.MarkLabel(lblEnd);
@ -1850,6 +1850,7 @@ namespace ARMeilleure.Instructions
{ {
context.Copy(res, sar); context.Copy(res, sar);
} }
context.Branch(lblEnd); context.Branch(lblEnd);
context.MarkLabel(lblEnd); context.MarkLabel(lblEnd);
@ -1906,6 +1907,7 @@ namespace ARMeilleure.Instructions
Operand right = context.BitwiseOr(shr, context.ShiftRightUI(oneShl63UL, context.Subtract(shift, one))); Operand right = context.BitwiseOr(shr, context.ShiftRightUI(oneShl63UL, context.Subtract(shift, one)));
context.Copy(res, context.ConditionalSelect(isEqual, oneUL, right)); context.Copy(res, context.ConditionalSelect(isEqual, oneUL, right));
} }
context.Branch(lblEnd); context.Branch(lblEnd);
context.MarkLabel(lblEnd); context.MarkLabel(lblEnd);

View File

@ -69,13 +69,13 @@ namespace ARMeilleure.Instructions
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
public static ulong GetCtrEl0() public static ulong GetCtrEl0()
{ {
return GetContext().CtrEl0; return ExecutionContext.CtrEl0;
} }
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
public static ulong GetDczidEl0() public static ulong GetDczidEl0()
{ {
return GetContext().DczidEl0; return ExecutionContext.DczidEl0;
} }
[UnmanagedCallersOnly] [UnmanagedCallersOnly]

View File

@ -24,7 +24,7 @@ namespace ARMeilleure.Instructions
{ {
uint src = (uint)idx + 256u; uint src = (uint)idx + 256u;
Debug.Assert(256u <= src && src < 512u); Debug.Assert(src is >= 256u and < 512u);
src = (src << 1) + 1u; src = (src << 1) + 1u;
@ -32,7 +32,7 @@ namespace ARMeilleure.Instructions
uint dst = (aux + 1u) >> 1; uint dst = (aux + 1u) >> 1;
Debug.Assert(256u <= dst && dst < 512u); Debug.Assert(dst is >= 256u and < 512u);
tbl[idx] = (byte)(dst - 256u); tbl[idx] = (byte)(dst - 256u);
} }
@ -48,7 +48,7 @@ namespace ARMeilleure.Instructions
{ {
uint src = (uint)idx + 128u; uint src = (uint)idx + 128u;
Debug.Assert(128u <= src && src < 512u); Debug.Assert(src is >= 128u and < 512u);
if (src < 256u) if (src < 256u)
{ {
@ -69,7 +69,7 @@ namespace ARMeilleure.Instructions
uint dst = (aux + 1u) >> 1; uint dst = (aux + 1u) >> 1;
Debug.Assert(256u <= dst && dst < 512u); Debug.Assert(dst is >= 256u and < 512u);
tbl[idx] = (byte)(dst - 256u); tbl[idx] = (byte)(dst - 256u);
} }
@ -322,7 +322,7 @@ namespace ARMeilleure.Instructions
float result; float result;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
if ((context.Fpcr & FPCR.Dn) != 0) if ((context.Fpcr & FPCR.Dn) != 0)
{ {
@ -498,7 +498,7 @@ namespace ARMeilleure.Instructions
double result; double result;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
if ((context.Fpcr & FPCR.Dn) != 0) if ((context.Fpcr & FPCR.Dn) != 0)
{ {
@ -676,7 +676,7 @@ namespace ARMeilleure.Instructions
ushort resultBits; ushort resultBits;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
if (altHp) if (altHp)
{ {
@ -1086,7 +1086,7 @@ namespace ARMeilleure.Instructions
{ {
return FPMaxFpscrImpl(value1, value2, standardFpscr == 1); return FPMaxFpscrImpl(value1, value2, standardFpscr == 1);
} }
private static float FPMaxFpscrImpl(float value1, float value2, bool standardFpscr) private static float FPMaxFpscrImpl(float value1, float value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@ -1522,7 +1522,7 @@ namespace ARMeilleure.Instructions
float result; float result;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
result = FPProcessNaN(type, op, context, fpcr); result = FPProcessNaN(type, op, context, fpcr);
} }
@ -1689,7 +1689,7 @@ namespace ARMeilleure.Instructions
float result; float result;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
result = FPProcessNaN(type, op, context, fpcr); result = FPProcessNaN(type, op, context, fpcr);
} }
@ -1726,7 +1726,7 @@ namespace ARMeilleure.Instructions
float result; float result;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
result = FPProcessNaN(type, op, context, fpcr); result = FPProcessNaN(type, op, context, fpcr);
} }
@ -1920,7 +1920,7 @@ namespace ARMeilleure.Instructions
float result; float result;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
result = FPProcessNaN(type, op, context, fpcr); result = FPProcessNaN(type, op, context, fpcr);
} }
@ -2211,7 +2211,7 @@ namespace ARMeilleure.Instructions
ushort resultBits; ushort resultBits;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
if (altHp) if (altHp)
{ {
@ -3057,7 +3057,7 @@ namespace ARMeilleure.Instructions
double result; double result;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
result = FPProcessNaN(type, op, context, fpcr); result = FPProcessNaN(type, op, context, fpcr);
} }
@ -3224,7 +3224,7 @@ namespace ARMeilleure.Instructions
double result; double result;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
result = FPProcessNaN(type, op, context, fpcr); result = FPProcessNaN(type, op, context, fpcr);
} }
@ -3261,7 +3261,7 @@ namespace ARMeilleure.Instructions
double result; double result;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
result = FPProcessNaN(type, op, context, fpcr); result = FPProcessNaN(type, op, context, fpcr);
} }
@ -3455,7 +3455,7 @@ namespace ARMeilleure.Instructions
double result; double result;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
result = FPProcessNaN(type, op, context, fpcr); result = FPProcessNaN(type, op, context, fpcr);
} }

View File

@ -1,10 +1,8 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
namespace ARMeilleure.IntermediateRepresentation namespace ARMeilleure.IntermediateRepresentation
{ {
[Flags] [Flags]
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
enum Intrinsic : ushort enum Intrinsic : ushort
{ {
// X86 (SSE and AVX) // X86 (SSE and AVX)

View File

@ -7,10 +7,9 @@ namespace ARMeilleure.IntermediateRepresentation
{ {
private struct Data private struct Data
{ {
#pragma warning disable CS0649 // Field is never assigned to
public byte Kind; public byte Kind;
public byte Type; public byte Type;
#pragma warning restore CS0649
public byte Scale; public byte Scale;
public Operand BaseAddress; public Operand BaseAddress;
public Operand Index; public Operand Index;

View File

@ -446,7 +446,7 @@ namespace ARMeilleure.IntermediateRepresentation
Data* data = null; Data* data = null;
// If constant or register, then try to look up in the intern table before allocating. // If constant or register, then try to look up in the intern table before allocating.
if (kind == OperandKind.Constant || kind == OperandKind.Register) if (kind is OperandKind.Constant or OperandKind.Register)
{ {
uint hash = (uint)HashCode.Combine(kind, type, value); uint hash = (uint)HashCode.Combine(kind, type, value);

View File

@ -16,8 +16,8 @@ namespace ARMeilleure.IntermediateRepresentation
{ {
public static bool IsInteger(this OperandType type) public static bool IsInteger(this OperandType type)
{ {
return type == OperandType.I32 || return type is OperandType.I32 or
type == OperandType.I64; OperandType.I64;
} }
public static RegisterType ToRegisterType(this OperandType type) public static RegisterType ToRegisterType(this OperandType type)

View File

@ -47,12 +47,12 @@ namespace ARMeilleure.Memory
{ {
public static bool IsHostMapped(this MemoryManagerType type) public static bool IsHostMapped(this MemoryManagerType type)
{ {
return type == MemoryManagerType.HostMapped || type == MemoryManagerType.HostMappedUnsafe; return type is MemoryManagerType.HostMapped or MemoryManagerType.HostMappedUnsafe;
} }
public static bool IsHostTracked(this MemoryManagerType type) public static bool IsHostTracked(this MemoryManagerType type)
{ {
return type == MemoryManagerType.HostTracked || type == MemoryManagerType.HostTrackedUnsafe; return type is MemoryManagerType.HostTracked or MemoryManagerType.HostTrackedUnsafe;
} }
public static bool IsHostMappedOrTracked(this MemoryManagerType type) public static bool IsHostMappedOrTracked(this MemoryManagerType type)

View File

@ -1,8 +1,8 @@
using Arm64HardwareCapabilities = ARMeilleure.CodeGen.Arm64.HardwareCapabilities;
using X86HardwareCapabilities = ARMeilleure.CodeGen.X86.HardwareCapabilities;
namespace ARMeilleure namespace ARMeilleure
{ {
using Arm64HardwareCapabilities = ARMeilleure.CodeGen.Arm64.HardwareCapabilities;
using X86HardwareCapabilities = ARMeilleure.CodeGen.X86.HardwareCapabilities;
public static class Optimizations public static class Optimizations
{ {
// low-core count PPTC // low-core count PPTC

View File

@ -16,10 +16,8 @@ namespace ARMeilleure.State
public ulong Pc => _nativeContext.GetPc(); public ulong Pc => _nativeContext.GetPc();
#pragma warning disable CA1822 // Mark member as static public static uint CtrEl0 => 0x8444c004;
public uint CtrEl0 => 0x8444c004; public static uint DczidEl0 => 0x00000004;
public uint DczidEl0 => 0x00000004;
#pragma warning restore CA1822
public ulong CntfrqEl0 => _counter.Frequency; public ulong CntfrqEl0 => _counter.Frequency;
public ulong CntpctEl0 => _counter.Counter; public ulong CntpctEl0 => _counter.Counter;

View File

@ -111,6 +111,7 @@ namespace ARMeilleure.State
{ {
value |= GetStorage().Flags[flag] != 0 ? 1u << flag : 0u; value |= GetStorage().Flags[flag] != 0 ? 1u << flag : 0u;
} }
return value; return value;
} }
@ -155,6 +156,7 @@ namespace ARMeilleure.State
value |= GetStorage().FpFlags[flag] != 0 ? bit : 0u; value |= GetStorage().FpFlags[flag] != 0 ? bit : 0u;
} }
} }
return value; return value;
} }

View File

@ -218,18 +218,28 @@ namespace ARMeilleure.Translation
{ {
switch (condition) switch (condition)
{ {
#pragma warning disable IDE0055 // Disable formatting
case Condition.Eq: return ICompareEqual (n, m); case Condition.Eq:
case Condition.Ne: return ICompareNotEqual (n, m); return ICompareEqual(n, m);
case Condition.GeUn: return ICompareGreaterOrEqualUI(n, m); case Condition.Ne:
case Condition.LtUn: return ICompareLessUI (n, m); return ICompareNotEqual(n, m);
case Condition.GtUn: return ICompareGreaterUI (n, m); case Condition.GeUn:
case Condition.LeUn: return ICompareLessOrEqualUI (n, m); return ICompareGreaterOrEqualUI(n, m);
case Condition.Ge: return ICompareGreaterOrEqual (n, m); case Condition.LtUn:
case Condition.Lt: return ICompareLess (n, m); return ICompareLessUI(n, m);
case Condition.Gt: return ICompareGreater (n, m); case Condition.GtUn:
case Condition.Le: return ICompareLessOrEqual (n, m); return ICompareGreaterUI(n, m);
#pragma warning restore IDE0055 case Condition.LeUn:
return ICompareLessOrEqualUI(n, m);
case Condition.Ge:
return ICompareGreaterOrEqual(n, m);
case Condition.Lt:
return ICompareLess(n, m);
case Condition.Gt:
return ICompareGreater(n, m);
case Condition.Le:
return ICompareLessOrEqual(n, m);
} }
} }
else if (cmpName == InstName.Adds && _optOpLastCompare is IOpCodeAluImm op) else if (cmpName == InstName.Adds && _optOpLastCompare is IOpCodeAluImm op)
@ -254,14 +264,20 @@ namespace ARMeilleure.Translation
switch (condition) switch (condition)
{ {
#pragma warning disable IDE0055 // Disable formatting
case Condition.Eq: return ICompareEqual (n, m); case Condition.Eq:
case Condition.Ne: return ICompareNotEqual (n, m); return ICompareEqual(n, m);
case Condition.Ge: return ICompareGreaterOrEqual(n, m); case Condition.Ne:
case Condition.Lt: return ICompareLess (n, m); return ICompareNotEqual(n, m);
case Condition.Gt: return ICompareGreater (n, m); case Condition.Ge:
case Condition.Le: return ICompareLessOrEqual (n, m); return ICompareGreaterOrEqual(n, m);
#pragma warning restore IDE0055 case Condition.Lt:
return ICompareLess(n, m);
case Condition.Gt:
return ICompareGreater(n, m);
case Condition.Le:
return ICompareLessOrEqual(n, m);
} }
} }

View File

@ -24,7 +24,7 @@ namespace ARMeilleure.Translation.Cache
private static JitCacheInvalidation _jitCacheInvalidator; private static JitCacheInvalidation _jitCacheInvalidator;
private static List<CacheMemoryAllocator> _cacheAllocators = []; private static readonly List<CacheMemoryAllocator> _cacheAllocators = [];
private static readonly List<CacheEntry> _cacheEntries = []; private static readonly List<CacheEntry> _cacheEntries = [];
@ -205,7 +205,6 @@ namespace ARMeilleure.Translation.Cache
return allocOffsetNew; return allocOffsetNew;
} }
private static int AlignCodeSize(int codeSize) private static int AlignCodeSize(int codeSize)
{ {
return checked(codeSize + (CodeAlignment - 1)) & ~(CodeAlignment - 1); return checked(codeSize + (CodeAlignment - 1)) & ~(CodeAlignment - 1);

View File

@ -32,7 +32,7 @@ namespace ARMeilleure.Translation
return _delegates.Values[index].FuncPtr; // O(1). return _delegates.Values[index].FuncPtr; // O(1).
} }
public static int GetDelegateIndex(MethodInfo info) public static int GetDelegateIndex(MethodInfo info)
{ {
ArgumentNullException.ThrowIfNull(info); ArgumentNullException.ThrowIfNull(info);
@ -48,7 +48,7 @@ namespace ARMeilleure.Translation
return index; return index;
} }
private static void SetDelegateInfo(MethodInfo method) private static void SetDelegateInfo(MethodInfo method)
{ {
string key = GetKey(method); string key = GetKey(method);

View File

@ -77,7 +77,7 @@ namespace ARMeilleure.Translation
{ {
continue; continue;
} }
for (int pBlkIndex = 0; pBlkIndex < block.Predecessors.Count; pBlkIndex++) for (int pBlkIndex = 0; pBlkIndex < block.Predecessors.Count; pBlkIndex++)
{ {
BasicBlock current = block.Predecessors[pBlkIndex]; BasicBlock current = block.Predecessors[pBlkIndex];

View File

@ -124,7 +124,7 @@ namespace ARMeilleure.Translation
/// </summary> /// </summary>
/// <param name="node">The node to search for values within</param> /// <param name="node">The node to search for values within</param>
/// <param name="list">The list to add values to</param> /// <param name="list">The list to add values to</param>
private void AddToList(IntervalTreeNode<TK, TV> node, List<TV> list) private static void AddToList(IntervalTreeNode<TK, TV> node, List<TV> list)
{ {
if (node == null) if (node == null)
{ {
@ -165,6 +165,7 @@ namespace ARMeilleure.Translation
return node; return node;
} }
} }
return null; return null;
} }
@ -175,7 +176,7 @@ namespace ARMeilleure.Translation
/// <param name="end">End of the range</param> /// <param name="end">End of the range</param>
/// <param name="overlaps">Overlaps array to place results in</param> /// <param name="overlaps">Overlaps array to place results in</param>
/// <param name="overlapCount">Overlaps count to update</param> /// <param name="overlapCount">Overlaps count to update</param>
private void GetKeys(IntervalTreeNode<TK, TV> node, TK start, TK end, ref TK[] overlaps, ref int overlapCount) private static void GetKeys(IntervalTreeNode<TK, TV> node, TK start, TK end, ref TK[] overlaps, ref int overlapCount)
{ {
if (node == null || start.CompareTo(node.Max) >= 0) if (node == null || start.CompareTo(node.Max) >= 0)
{ {
@ -311,6 +312,7 @@ namespace ARMeilleure.Translation
return false; return false;
} }
} }
IntervalTreeNode<TK, TV> newNode = new(start, end, value, parent); IntervalTreeNode<TK, TV> newNode = new(start, end, value, parent);
if (newNode.Parent == null) if (newNode.Parent == null)
{ {
@ -422,12 +424,14 @@ namespace ARMeilleure.Translation
{ {
return Maximum(node.Left); return Maximum(node.Left);
} }
IntervalTreeNode<TK, TV> parent = node.Parent; IntervalTreeNode<TK, TV> parent = node.Parent;
while (parent != null && node == parent.Left) while (parent != null && node == parent.Left)
{ {
node = parent; node = parent;
parent = parent.Parent; parent = parent.Parent;
} }
return parent; return parent;
} }
@ -452,6 +456,7 @@ namespace ARMeilleure.Translation
RotateLeft(ParentOf(ptr)); RotateLeft(ParentOf(ptr));
sibling = RightOf(ParentOf(ptr)); sibling = RightOf(ParentOf(ptr));
} }
if (ColorOf(LeftOf(sibling)) == Black && ColorOf(RightOf(sibling)) == Black) if (ColorOf(LeftOf(sibling)) == Black && ColorOf(RightOf(sibling)) == Black)
{ {
SetColor(sibling, Red); SetColor(sibling, Red);
@ -466,6 +471,7 @@ namespace ARMeilleure.Translation
RotateRight(sibling); RotateRight(sibling);
sibling = RightOf(ParentOf(ptr)); sibling = RightOf(ParentOf(ptr));
} }
SetColor(sibling, ColorOf(ParentOf(ptr))); SetColor(sibling, ColorOf(ParentOf(ptr)));
SetColor(ParentOf(ptr), Black); SetColor(ParentOf(ptr), Black);
SetColor(RightOf(sibling), Black); SetColor(RightOf(sibling), Black);
@ -484,6 +490,7 @@ namespace ARMeilleure.Translation
RotateRight(ParentOf(ptr)); RotateRight(ParentOf(ptr));
sibling = LeftOf(ParentOf(ptr)); sibling = LeftOf(ParentOf(ptr));
} }
if (ColorOf(RightOf(sibling)) == Black && ColorOf(LeftOf(sibling)) == Black) if (ColorOf(RightOf(sibling)) == Black && ColorOf(LeftOf(sibling)) == Black)
{ {
SetColor(sibling, Red); SetColor(sibling, Red);
@ -498,6 +505,7 @@ namespace ARMeilleure.Translation
RotateLeft(sibling); RotateLeft(sibling);
sibling = LeftOf(ParentOf(ptr)); sibling = LeftOf(ParentOf(ptr));
} }
SetColor(sibling, ColorOf(ParentOf(ptr))); SetColor(sibling, ColorOf(ParentOf(ptr)));
SetColor(ParentOf(ptr), Black); SetColor(ParentOf(ptr), Black);
SetColor(LeftOf(sibling), Black); SetColor(LeftOf(sibling), Black);
@ -506,6 +514,7 @@ namespace ARMeilleure.Translation
} }
} }
} }
SetColor(ptr, Black); SetColor(ptr, Black);
} }
@ -532,6 +541,7 @@ namespace ARMeilleure.Translation
balanceNode = ParentOf(balanceNode); balanceNode = ParentOf(balanceNode);
RotateLeft(balanceNode); RotateLeft(balanceNode);
} }
SetColor(ParentOf(balanceNode), Black); SetColor(ParentOf(balanceNode), Black);
SetColor(ParentOf(ParentOf(balanceNode)), Red); SetColor(ParentOf(ParentOf(balanceNode)), Red);
RotateRight(ParentOf(ParentOf(balanceNode))); RotateRight(ParentOf(ParentOf(balanceNode)));
@ -555,12 +565,14 @@ namespace ARMeilleure.Translation
balanceNode = ParentOf(balanceNode); balanceNode = ParentOf(balanceNode);
RotateRight(balanceNode); RotateRight(balanceNode);
} }
SetColor(ParentOf(balanceNode), Black); SetColor(ParentOf(balanceNode), Black);
SetColor(ParentOf(ParentOf(balanceNode)), Red); SetColor(ParentOf(ParentOf(balanceNode)), Red);
RotateLeft(ParentOf(ParentOf(balanceNode))); RotateLeft(ParentOf(ParentOf(balanceNode)));
} }
} }
} }
SetColor(_root, Black); SetColor(_root, Black);
} }
@ -574,6 +586,7 @@ namespace ARMeilleure.Translation
{ {
node.Right.Parent = node; node.Right.Parent = node;
} }
IntervalTreeNode<TK, TV> nodeParent = ParentOf(node); IntervalTreeNode<TK, TV> nodeParent = ParentOf(node);
right.Parent = nodeParent; right.Parent = nodeParent;
if (nodeParent == null) if (nodeParent == null)
@ -588,6 +601,7 @@ namespace ARMeilleure.Translation
{ {
nodeParent.Right = right; nodeParent.Right = right;
} }
right.Left = node; right.Left = node;
node.Parent = right; node.Parent = right;
@ -605,6 +619,7 @@ namespace ARMeilleure.Translation
{ {
node.Left.Parent = node; node.Left.Parent = node;
} }
IntervalTreeNode<TK, TV> nodeParent = ParentOf(node); IntervalTreeNode<TK, TV> nodeParent = ParentOf(node);
left.Parent = nodeParent; left.Parent = nodeParent;
if (nodeParent == null) if (nodeParent == null)
@ -619,6 +634,7 @@ namespace ARMeilleure.Translation
{ {
nodeParent.Left = left; nodeParent.Left = left;
} }
left.Right = node; left.Right = node;
node.Parent = left; node.Parent = left;

View File

@ -22,12 +22,11 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using static ARMeilleure.Translation.PTC.PtcFormatter; using static ARMeilleure.Translation.PTC.PtcFormatter;
using Arm64HardwareCapabilities = ARMeilleure.CodeGen.Arm64.HardwareCapabilities;
using X86HardwareCapabilities = ARMeilleure.CodeGen.X86.HardwareCapabilities;
namespace ARMeilleure.Translation.PTC namespace ARMeilleure.Translation.PTC
{ {
using Arm64HardwareCapabilities = CodeGen.Arm64.HardwareCapabilities;
using X86HardwareCapabilities = CodeGen.X86.HardwareCapabilities;
class Ptc : IPtcLoadState class Ptc : IPtcLoadState
{ {
private const string OuterHeaderMagicString = "PTCohd\0\0"; private const string OuterHeaderMagicString = "PTCohd\0\0";
@ -193,7 +192,7 @@ namespace ARMeilleure.Translation.PTC
_infosStream.Seek(0L, SeekOrigin.Begin); _infosStream.Seek(0L, SeekOrigin.Begin);
bool foundBadFunction = false; bool foundBadFunction = false;
for (int index = 0; index < GetEntriesCount(); index++) for (int index = 0; index < _infosStream.Length / Unsafe.SizeOf<InfoEntry>(); index++)
{ {
InfoEntry infoEntry = DeserializeStructure<InfoEntry>(_infosStream); InfoEntry infoEntry = DeserializeStructure<InfoEntry>(_infosStream);
foreach (ulong address in blacklist) foreach (ulong address in blacklist)
@ -835,8 +834,6 @@ namespace ARMeilleure.Translation.PTC
return; return;
} }
int degreeOfParallelism = Environment.ProcessorCount; int degreeOfParallelism = Environment.ProcessorCount;
if (Optimizations.LowPower) if (Optimizations.LowPower)
@ -896,13 +893,12 @@ namespace ARMeilleure.Translation.PTC
} }
} }
List<Thread> threads = Enumerable.Range(0, degreeOfParallelism) List<Thread> threads = Enumerable.Range(0, degreeOfParallelism)
.Select(idx => .Select(idx =>
new Thread(TranslateFuncs) new Thread(TranslateFuncs)
{ {
IsBackground = true, IsBackground = true,
Name = "Ptc.TranslateThread." + idx Name = "Ptc.TranslateThread." + idx
} }
).ToList(); ).ToList();
@ -912,6 +908,7 @@ namespace ARMeilleure.Translation.PTC
{ {
thread.Start(); thread.Start();
} }
foreach (Thread thread in threads) foreach (Thread thread in threads)
{ {
thread.Join(); thread.Join();
@ -925,8 +922,8 @@ namespace ARMeilleure.Translation.PTC
sw.Stop(); sw.Stop();
PtcStateChanged?.Invoke(PtcLoadingState.Loaded, _translateCount, _translateTotalCount); PtcStateChanged?.Invoke(PtcLoadingState.Loaded, _translateCount, _translateTotalCount);
Logger.Info?.Print(LogClass.Ptc, Logger.Info?.Print(LogClass.Ptc,
$"{_translateCount} of {_translateTotalCount} functions translated in {sw.Elapsed.TotalSeconds} seconds " + $"{_translateCount} of {_translateTotalCount} functions translated in {sw.Elapsed.TotalSeconds} seconds " +
$"| {"function".ToQuantity(_translateTotalCount - _translateCount)} blacklisted " + $"| {"function".ToQuantity(_translateTotalCount - _translateCount)} blacklisted " +
$"| Thread count: {degreeOfParallelism}"); $"| Thread count: {degreeOfParallelism}");
@ -1164,8 +1161,8 @@ namespace ARMeilleure.Translation.PTC
public void Close() public void Close()
{ {
if (State == PtcState.Enabled || if (State is PtcState.Enabled or
State == PtcState.Continuing) PtcState.Continuing)
{ {
State = PtcState.Closing; State = PtcState.Closing;
} }

View File

@ -1,5 +1,6 @@
using ARMeilleure.State; using ARMeilleure.State;
using Humanizer; using Humanizer;
using Microsoft.IO;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.Memory; using Ryujinx.Common.Memory;
@ -26,7 +27,7 @@ namespace ARMeilleure.Translation.PTC
private const uint InternalVersion = 7007; //! Not to be incremented manually for each change to the ARMeilleure project. private const uint InternalVersion = 7007; //! Not to be incremented manually for each change to the ARMeilleure project.
private static readonly uint[] _migrateInternalVersions = private static readonly uint[] _migrateInternalVersions =
[ [
1866, 1866,
5518, 5518,
@ -75,7 +76,7 @@ namespace ARMeilleure.Translation.PTC
Enabled = false; Enabled = false;
} }
private void TimerElapsed(object _, ElapsedEventArgs __) private void TimerElapsed(object _, ElapsedEventArgs __)
=> new Thread(PreSave) { Name = "Ptc.DiskWriter" }.Start(); => new Thread(PreSave) { Name = "Ptc.DiskWriter" }.Start();
public void AddEntry(ulong address, ExecutionMode mode, bool highCq, bool blacklist = false) public void AddEntry(ulong address, ExecutionMode mode, bool highCq, bool blacklist = false)
@ -151,7 +152,7 @@ namespace ARMeilleure.Translation.PTC
if (!funcProfile.Blacklist) if (!funcProfile.Blacklist)
continue; continue;
if (!funcs.Contains(ptr)) if (!funcs.Contains(ptr))
funcs.Add(ptr); funcs.Add(ptr);
} }
@ -219,7 +220,7 @@ namespace ARMeilleure.Translation.PTC
return false; return false;
} }
using MemoryStream stream = MemoryStreamManager.Shared.GetStream(); using RecyclableMemoryStream stream = MemoryStreamManager.Shared.GetStream();
Debug.Assert(stream.Seek(0L, SeekOrigin.Begin) == 0L && stream.Length == 0L); Debug.Assert(stream.Seek(0L, SeekOrigin.Begin) == 0L && stream.Length == 0L);
try try
@ -293,10 +294,10 @@ namespace ARMeilleure.Translation.PTC
{ {
if (migrateEntryFunc != null) if (migrateEntryFunc != null)
{ {
return DeserializeAndUpdateDictionary(stream, (Stream stream) => { return new FuncProfile(DeserializeStructure<FuncProfilePreBlacklist>(stream)); }, migrateEntryFunc); return DeserializeAndUpdateDictionary(stream, stream => { return new FuncProfile(DeserializeStructure<FuncProfilePreBlacklist>(stream)); }, migrateEntryFunc);
} }
return DeserializeDictionary<ulong, FuncProfile>(stream, (Stream stream) => { return new FuncProfile(DeserializeStructure<FuncProfilePreBlacklist>(stream)); }); return DeserializeDictionary<ulong, FuncProfile>(stream, stream => { return new FuncProfile(DeserializeStructure<FuncProfilePreBlacklist>(stream)); });
} }
private static ReadOnlySpan<byte> GetReadOnlySpan(MemoryStream memoryStream) private static ReadOnlySpan<byte> GetReadOnlySpan(MemoryStream memoryStream)
@ -467,8 +468,8 @@ namespace ARMeilleure.Translation.PTC
public void Start() public void Start()
{ {
if (_ptc.State == PtcState.Enabled || if (_ptc.State is PtcState.Enabled or
_ptc.State == PtcState.Continuing) PtcState.Continuing)
{ {
Enabled = true; Enabled = true;

View File

@ -297,12 +297,20 @@ namespace ARMeilleure.Translation
switch (register.Type) switch (register.Type)
{ {
#pragma warning disable IDE0055 // Disable formatting
case RegisterType.Flag: intMask = (1L << RegsCount) << register.Index; break; case RegisterType.Flag:
case RegisterType.Integer: intMask = 1L << register.Index; break; intMask = (1L << RegsCount) << register.Index;
case RegisterType.FpFlag: vecMask = (1L << RegsCount) << register.Index; break; break;
case RegisterType.Vector: vecMask = 1L << register.Index; break; case RegisterType.Integer:
#pragma warning restore IDE0055 intMask = 1L << register.Index;
break;
case RegisterType.FpFlag:
vecMask = (1L << RegsCount) << register.Index;
break;
case RegisterType.Vector:
vecMask = 1L << register.Index;
break;
} }
return new RegisterMask(intMask, vecMask); return new RegisterMask(intMask, vecMask);

View File

@ -178,7 +178,7 @@ namespace Ryujinx.Audio.Backends.OpenAL
public bool SupportsChannelCount(uint channelCount) public bool SupportsChannelCount(uint channelCount)
{ {
return channelCount == 1 || channelCount == 2 || channelCount == 6; return channelCount is 1 or 2 or 6;
} }
public bool SupportsDirection(Direction direction) public bool SupportsDirection(Direction direction)

View File

@ -12,7 +12,7 @@ using static SDL2.SDL;
namespace Ryujinx.Audio.Backends.SDL2 namespace Ryujinx.Audio.Backends.SDL2
{ {
public class SDL2HardwareDeviceDriver : IHardwareDeviceDriver public partial class SDL2HardwareDeviceDriver : IHardwareDeviceDriver
{ {
private readonly ManualResetEvent _updateRequiredEvent; private readonly ManualResetEvent _updateRequiredEvent;
private readonly ManualResetEvent _pauseEvent; private readonly ManualResetEvent _pauseEvent;
@ -22,12 +22,36 @@ namespace Ryujinx.Audio.Backends.SDL2
public float Volume { get; set; } public float Volume { get; set; }
// TODO: Add this to SDL2-CS // A safe method to get default audio information.
// NOTE: We use a DllImport here because of marshaling issue for spec. private static int GetDefaultAudioInfo(nint name, out SDL_AudioSpec spec, int isCapture)
#pragma warning disable SYSLIB1054 {
[DllImport("SDL2")] int result;
private static extern int SDL_GetDefaultAudioInfo(nint name, out SDL_AudioSpec spec, int isCapture); spec = new SDL_AudioSpec();
#pragma warning restore SYSLIB1054 IntPtr specPtr = IntPtr.Zero;
try
{
// Reserve memory
specPtr = Marshal.AllocHGlobal(Marshal.SizeOf<SDL_AudioSpec>());
// Call method
result = SDL_GetDefaultAudioInfo(name, specPtr, isCapture);
// Copy result to managed structure
spec = Marshal.PtrToStructure<SDL_AudioSpec>(specPtr);
}
finally
{
// Free the unmanaged memory to prevent memory leaks
if (specPtr != IntPtr.Zero)
{
Marshal.FreeHGlobal(specPtr);
}
}
return result;
}
[LibraryImport("SDL2")]
private static partial int SDL_GetDefaultAudioInfo(nint name, nint spec, int isCapture);
public SDL2HardwareDeviceDriver() public SDL2HardwareDeviceDriver()
{ {
@ -37,7 +61,7 @@ namespace Ryujinx.Audio.Backends.SDL2
SDL2Driver.Instance.Initialize(); SDL2Driver.Instance.Initialize();
int res = SDL_GetDefaultAudioInfo(nint.Zero, out SDL_AudioSpec spec, 0); int res = GetDefaultAudioInfo(nint.Zero, out SDL_AudioSpec spec, 0);
if (res != 0) if (res != 0)
{ {

View File

@ -23,7 +23,7 @@ namespace Ryujinx.Audio.Backends.SoundIo.Native
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void JackCallbackDelegate(nint msg); public delegate void JackCallbackDelegate(nint msg);
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct SoundIoStruct public struct SoundIoStruct
{ {
public nint UserData; public nint UserData;

View File

@ -162,7 +162,7 @@ namespace Ryujinx.Audio.Backends.CompatLayer
public bool SupportsChannelCount(uint channelCount) public bool SupportsChannelCount(uint channelCount)
{ {
return channelCount == 1 || channelCount == 2 || channelCount == 6; return channelCount is 1 or 2 or 6;
} }
public bool SupportsSampleFormat(SampleFormat sampleFormat) public bool SupportsSampleFormat(SampleFormat sampleFormat)
@ -184,7 +184,7 @@ namespace Ryujinx.Audio.Backends.CompatLayer
public bool SupportsDirection(Direction direction) public bool SupportsDirection(Direction direction)
{ {
return direction == Direction.Input || direction == Direction.Output; return direction is Direction.Input or Direction.Output;
} }
} }
} }

View File

@ -73,12 +73,12 @@ namespace Ryujinx.Audio.Backends.Dummy
public bool SupportsDirection(Direction direction) public bool SupportsDirection(Direction direction)
{ {
return direction == Direction.Output || direction == Direction.Input; return direction is Direction.Output or Direction.Input;
} }
public bool SupportsChannelCount(uint channelCount) public bool SupportsChannelCount(uint channelCount)
{ {
return channelCount == 1 || channelCount == 2 || channelCount == 6; return channelCount is 1 or 2 or 6;
} }
} }
} }

View File

@ -109,7 +109,7 @@ namespace Ryujinx.Audio.Common
/// <returns>The state of the session</returns> /// <returns>The state of the session</returns>
public AudioDeviceState GetState() public AudioDeviceState GetState()
{ {
Debug.Assert(_state == AudioDeviceState.Started || _state == AudioDeviceState.Stopped); Debug.Assert(_state is AudioDeviceState.Started or AudioDeviceState.Stopped);
return _state; return _state;
} }

View File

@ -166,7 +166,7 @@ namespace Ryujinx.Audio.Input
/// </summary> /// </summary>
/// <param name="filtered">If true, filter disconnected devices</param> /// <param name="filtered">If true, filter disconnected devices</param>
/// <returns>The list of all audio inputs name</returns> /// <returns>The list of all audio inputs name</returns>
public string[] ListAudioIns(bool filtered) public static string[] ListAudioIns(bool filtered)
{ {
if (filtered) if (filtered)
{ {

View File

@ -91,12 +91,12 @@ namespace Ryujinx.Audio.Input
return ResultCode.DeviceNotFound; return ResultCode.DeviceNotFound;
} }
if (configuration.SampleRate != 0 && configuration.SampleRate != Constants.TargetSampleRate) if (configuration.SampleRate is not 0 and not Constants.TargetSampleRate)
{ {
return ResultCode.UnsupportedSampleRate; return ResultCode.UnsupportedSampleRate;
} }
if (configuration.ChannelCount != 0 && configuration.ChannelCount != 1 && configuration.ChannelCount != 2 && configuration.ChannelCount != 6) if (configuration.ChannelCount is not 0 and not 1 and not 2 and not 6)
{ {
return ResultCode.UnsupportedChannelConfiguration; return ResultCode.UnsupportedChannelConfiguration;
} }

View File

@ -47,7 +47,7 @@ namespace Ryujinx.Audio.Integration
{ {
uint channelCount = GetChannelCount(); uint channelCount = GetChannelCount();
Debug.Assert(channelCount > 0 && channelCount <= Constants.ChannelCountMax); Debug.Assert(channelCount is > 0 and <= Constants.ChannelCountMax);
return channelCount != Constants.ChannelCountMax; return channelCount != Constants.ChannelCountMax;
} }

View File

@ -165,7 +165,7 @@ namespace Ryujinx.Audio.Output
/// Get the list of all audio outputs name. /// Get the list of all audio outputs name.
/// </summary> /// </summary>
/// <returns>The list of all audio outputs name</returns> /// <returns>The list of all audio outputs name</returns>
public string[] ListAudioOuts() public static string[] ListAudioOuts()
{ {
return [Constants.DefaultDeviceOutputName]; return [Constants.DefaultDeviceOutputName];
} }

View File

@ -91,12 +91,12 @@ namespace Ryujinx.Audio.Output
return ResultCode.DeviceNotFound; return ResultCode.DeviceNotFound;
} }
if (configuration.SampleRate != 0 && configuration.SampleRate != Constants.TargetSampleRate) if (configuration.SampleRate is not 0 and not Constants.TargetSampleRate)
{ {
return ResultCode.UnsupportedSampleRate; return ResultCode.UnsupportedSampleRate;
} }
if (configuration.ChannelCount != 0 && configuration.ChannelCount != 1 && configuration.ChannelCount != 2 && configuration.ChannelCount != 6) if (configuration.ChannelCount is not 0 and not 1 and not 2 and not 6)
{ {
return ResultCode.UnsupportedChannelConfiguration; return ResultCode.UnsupportedChannelConfiguration;
} }

View File

@ -20,9 +20,7 @@ namespace Ryujinx.Audio.Renderer.Common
public uint Unknown24; public uint Unknown24;
public uint RenderInfoSize; public uint RenderInfoSize;
#pragma warning disable IDE0051, CS0169 // Remove unused field
private Array4<int> _reserved; private Array4<int> _reserved;
#pragma warning restore IDE0051, CS0169
public uint TotalSize; public uint TotalSize;

View File

@ -58,7 +58,7 @@ namespace Ryujinx.Audio.Renderer.Device
/// <param name="volume">The new master volume.</param> /// <param name="volume">The new master volume.</param>
public void UpdateMasterVolume(float volume) public void UpdateMasterVolume(float volume)
{ {
Debug.Assert(volume >= 0.0f && volume <= 1.0f); Debug.Assert(volume is >= 0.0f and <= 1.0f);
MasterVolume = volume; MasterVolume = volume;
} }

View File

@ -17,9 +17,7 @@ namespace Ryujinx.Audio.Renderer.Device
/// The default <see cref="VirtualDevice"/>. /// The default <see cref="VirtualDevice"/>.
/// </summary> /// </summary>
/// <remarks>This is used when the USB device is the default one on older revision.</remarks> /// <remarks>This is used when the USB device is the default one on older revision.</remarks>
#pragma warning disable CA1822 // Mark member as static public static VirtualDevice DefaultDevice => VirtualDevice.Devices[0];
public VirtualDevice DefaultDevice => VirtualDevice.Devices[0];
#pragma warning restore CA1822
/// <summary> /// <summary>
/// The current active <see cref="VirtualDevice"/>. /// The current active <see cref="VirtualDevice"/>.

View File

@ -12,9 +12,8 @@ namespace Ryujinx.Audio.Renderer.Dsp
private const int SamplesPerFrame = 14; private const int SamplesPerFrame = 14;
private const int NibblesPerFrame = SamplesPerFrame + 2; private const int NibblesPerFrame = SamplesPerFrame + 2;
private const int BytesPerFrame = 8; private const int BytesPerFrame = 8;
#pragma warning disable IDE0051 // Remove unused private member
private const int BitsPerFrame = BytesPerFrame * 8; private const int BitsPerFrame = BytesPerFrame * 8;
#pragma warning restore IDE0051
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint GetAdpcmDataSize(int sampleCount) public static uint GetAdpcmDataSize(int sampleCount)

View File

@ -129,7 +129,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
delayFeedbackCrossGain, 0.0f, delayFeedbackBaseGain, delayFeedbackCrossGain, delayFeedbackCrossGain, 0.0f, delayFeedbackBaseGain, delayFeedbackCrossGain,
0.0f, delayFeedbackCrossGain, delayFeedbackCrossGain, delayFeedbackBaseGain); 0.0f, delayFeedbackCrossGain, delayFeedbackCrossGain, delayFeedbackBaseGain);
for (int i = 0; i < sampleCount; i++) for (int i = 0; i < sampleCount; i++)
{ {
Vector4 channelInput = new() Vector4 channelInput = new()

View File

@ -40,7 +40,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
DelayFeedbackBaseGain = (1.0f - channelSpread) * FeedbackGain; DelayFeedbackBaseGain = (1.0f - channelSpread) * FeedbackGain;
if (parameter.ChannelCount == 4 || parameter.ChannelCount == 6) if (parameter.ChannelCount is 4 or 6)
{ {
DelayFeedbackCrossGain = channelSpread * 0.5f * FeedbackGain; DelayFeedbackCrossGain = channelSpread * 0.5f * FeedbackGain;
} }

View File

@ -27,6 +27,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
{ {
return 1.0f; return 1.0f;
} }
return (MathF.Sin(MathF.PI * x) / (MathF.PI * x)); return (MathF.Sin(MathF.PI * x) / (MathF.PI * x));
} }
@ -141,6 +142,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
state.Phase = (state.Phase + 1) % 6; state.Phase = (state.Phase + 1) % 6;
} }
break; break;
case 3.0f: case 3.0f:
for (int i = 0; i < outputSampleCount; i++) for (int i = 0; i < outputSampleCount; i++)
@ -161,6 +163,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
state.Phase = (state.Phase + 1) % 3; state.Phase = (state.Phase + 1) % 3;
} }
break; break;
case 1.5f: case 1.5f:
// Upsample by 3 then decimate by 2. // Upsample by 3 then decimate by 2.
@ -183,6 +186,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
state.Phase = (state.Phase + 1) % 3; state.Phase = (state.Phase + 1) % 3;
} }
break; break;
default: default:
throw new ArgumentOutOfRangeException(nameof(state), state.Scale, null); throw new ArgumentOutOfRangeException(nameof(state), state.Scale, null);

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