mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-06-15 11:41:11 +00:00
Compare commits
55 Commits
Canary-1.3
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
a1d44ec496 | ||
|
bab3beb0ac | ||
|
aa9e74339b | ||
|
908273d848 | ||
|
b51ad11574 | ||
|
ea027d65a7 | ||
|
d03ae9c164 | ||
|
90e9492f6c | ||
|
512120db04 | ||
|
90582e9e93 | ||
|
b97fae08b5 | ||
|
eed6ef632d | ||
|
0409c15903 | ||
|
c58272ac20 | ||
|
9d83dfd19c | ||
|
ce31a47934 | ||
|
d31d1f91cf | ||
|
ef02194a77 | ||
|
a16764d191 | ||
|
5108ab790f | ||
|
71dc71fee8 | ||
|
c95bf748b2 | ||
|
b5e9acc50b | ||
|
e3fba4e32f | ||
|
efa25d471e | ||
|
b37aa61e47 | ||
|
8feeb977b7 | ||
|
b761a2c86d | ||
|
693837dca7 | ||
|
70abff072b | ||
|
1e861b99a9 | ||
|
13e404bde0 | ||
|
04561a0cd3 | ||
|
0652d7e740 | ||
|
f2aea4fb22 | ||
|
3950e8adff | ||
|
0e84f2b1f0 | ||
|
051c794cc4 | ||
|
053a9cb549 | ||
|
d688fed7d2 | ||
|
8f5102aa2a | ||
|
379e9ab622 | ||
|
af2575b40e | ||
|
361d0c5632 | ||
|
417df486b1 | ||
|
813d05bdf7 | ||
|
3429361a5d | ||
|
92b2947f04 | ||
|
4c281062ba | ||
|
84686d50cd | ||
|
81412c7dd5 | ||
|
960421a7c1 | ||
|
9233fe86b0 | ||
|
1156307ef9 | ||
|
a32a87e0c9 |
@ -16,6 +16,17 @@ tab_width = 4
|
||||
# New line preferences
|
||||
end_of_line = lf
|
||||
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
|
||||
[*.{md,json,yml,props,csproj}]
|
||||
@ -34,10 +45,10 @@ dotnet_separate_import_directive_groups = false
|
||||
dotnet_sort_system_directives_first = false
|
||||
|
||||
# this. and Me. preferences
|
||||
dotnet_style_qualification_for_event = false:silent
|
||||
dotnet_style_qualification_for_field = false:silent
|
||||
dotnet_style_qualification_for_method = false:silent
|
||||
dotnet_style_qualification_for_property = false:silent
|
||||
dotnet_style_qualification_for_event = false:suggestion
|
||||
dotnet_style_qualification_for_field = false:suggestion
|
||||
dotnet_style_qualification_for_method = false:suggestion
|
||||
dotnet_style_qualification_for_property = false:suggestion
|
||||
|
||||
# Language keywords vs BCL types preferences
|
||||
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_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_method_group_conversion = true
|
||||
csharp_style_prefer_method_group_conversion = true:silent
|
||||
|
||||
# Code-block preferences
|
||||
csharp_prefer_braces = true:silent
|
||||
@ -177,9 +188,9 @@ csharp_preserve_single_line_statements = false
|
||||
|
||||
# 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.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.symbols = types
|
||||
@ -236,28 +247,24 @@ dotnet_naming_style.IPascalCase.required_suffix =
|
||||
dotnet_naming_style.IPascalCase.word_separator =
|
||||
dotnet_naming_style.IPascalCase.capitalization = pascal_case
|
||||
|
||||
# TODO:
|
||||
# .NET 8 migration (new warnings are caused by the NET 8 C# compiler and analyzer)
|
||||
# The following info messages might need to be fixed in the source code instead of hiding the actual message
|
||||
# Without the following lines, dotnet format would fail
|
||||
# Disable "Collection initialization can be simplified"
|
||||
# Other settings
|
||||
csharp_style_prefer_top_level_statements = true:suggestion
|
||||
csharp_style_prefer_primary_constructors = false:suggestion
|
||||
csharp_prefer_system_threading_lock = true:suggestion
|
||||
|
||||
|
||||
# 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.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.IDE0301.severity = none
|
||||
dotnet_diagnostic.IDE0302.severity = none
|
||||
dotnet_diagnostic.IDE0305.severity = none
|
||||
# Disable "'new' expression can be simplified"
|
||||
dotnet_diagnostic.IDE0090.severity = none
|
||||
# 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
|
||||
dotnet_diagnostic.CS9113.severity = none # CS9113: Parameter 'value' is unread
|
||||
dotnet_diagnostic.CS0649.severity = none # CS0649: Field is never assigned to, and will always have its default value
|
||||
|
||||
[src/Ryujinx/UI/ViewModels/**.cs]
|
||||
# Disable "mark members as static" rule for ViewModels
|
||||
|
180
.github/workflows/canary.yml
vendored
180
.github/workflows/canary.yml
vendored
@ -21,60 +21,9 @@ env:
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||
RYUJINX_BASE_VERSION: "1.3"
|
||||
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
|
||||
|
||||
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:
|
||||
name: Release for ${{ matrix.platform.name }}
|
||||
runs-on: ${{ matrix.platform.os }}
|
||||
@ -82,7 +31,7 @@ jobs:
|
||||
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: 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:
|
||||
@ -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_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_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 '/^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
|
||||
|
||||
- name: Create output dir
|
||||
@ -129,7 +75,24 @@ jobs:
|
||||
rm libarmeilleure-jitsupport.dylib
|
||||
7z a ../release_output/ryujinx-canary-${{ 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/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
|
||||
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'
|
||||
@ -139,6 +102,8 @@ jobs:
|
||||
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
|
||||
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
|
||||
|
||||
- name: Build AppImage (Linux)
|
||||
@ -169,41 +134,17 @@ jobs:
|
||||
exit 1
|
||||
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
|
||||
|
||||
pushd publish_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
|
||||
popd
|
||||
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: |
|
||||
# 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 }}
|
||||
popd
|
||||
|
||||
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"
|
||||
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"
|
||||
shell: bash
|
||||
|
||||
macos_release:
|
||||
name: Release MacOS universal
|
||||
@ -220,6 +161,16 @@ jobs:
|
||||
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: |
|
||||
@ -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_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
|
||||
shell: bash
|
||||
|
||||
- name: Publish macOS Ryujinx
|
||||
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
|
||||
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
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
name: "Canary ${{ steps.version_info.outputs.build_version }}"
|
||||
artifacts: "publish_ava/*.tar.gz"
|
||||
tag: ${{ steps.version_info.outputs.build_version }}
|
||||
body: ""
|
||||
omitBodyDuringUpdate: true
|
||||
allowUpdates: true
|
||||
replacesArtifacts: true
|
||||
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
|
||||
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
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: 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
224
.github/workflows/debug_release.yml
vendored
Normal 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"
|
166
.github/workflows/release.yml
vendored
166
.github/workflows/release.yml
vendored
@ -11,57 +11,9 @@ env:
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||
RYUJINX_BASE_VERSION: "1.3"
|
||||
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
|
||||
|
||||
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:
|
||||
name: Release for ${{ matrix.platform.name }}
|
||||
runs-on: ${{ matrix.platform.os }}
|
||||
@ -69,7 +21,7 @@ jobs:
|
||||
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: 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:
|
||||
@ -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_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_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
|
||||
shell: bash
|
||||
|
||||
@ -115,7 +64,24 @@ jobs:
|
||||
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'
|
||||
@ -125,7 +91,11 @@ jobs:
|
||||
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
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build AppImage (Linux)
|
||||
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.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
|
||||
|
||||
- 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:
|
||||
name: Release MacOS universal
|
||||
runs-on: ubuntu-24.04
|
||||
@ -203,6 +152,16 @@ jobs:
|
||||
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: |
|
||||
@ -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_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_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
|
||||
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 }}" >> $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
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
name: ${{ steps.version_info.outputs.build_version }}
|
||||
artifacts: "publish/*.tar.gz"
|
||||
tag: ${{ steps.version_info.outputs.build_version }}
|
||||
body: ""
|
||||
omitBodyDuringUpdate: true
|
||||
allowUpdates: true
|
||||
replacesArtifacts: true
|
||||
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
|
||||
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
- 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 }}|${{ 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 }}'
|
||||
|
@ -13,7 +13,6 @@ rm -rf pkgs
|
||||
mkdir pkgs
|
||||
|
||||
package ARMeilleure
|
||||
package Ryujinx.Common
|
||||
package Ryujinx.Memory
|
||||
|
||||
dotnet nuget push pkgs/*.nupkg --source RyubingPkgs
|
@ -2,20 +2,17 @@
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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)).
|
||||
- Changed executable icon to rainbow logo.
|
||||
- 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.
|
||||
|
@ -40,7 +40,7 @@
|
||||
<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.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="Gommon" Version="2.7.1.1" />
|
||||
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
||||
|
14
README.md
14
README.md
@ -7,8 +7,8 @@
|
||||
|
||||
# Ryujinx
|
||||
|
||||
[](https://github.com/Ryubing/Stable-Releases/releases/latest)
|
||||
[](https://github.com/Ryubing/Canary-Releases/releases/latest)
|
||||
[](https://git.ryujinx.app/ryubing/ryujinx/-/releases)
|
||||
[](https://git.ryujinx.app/ryubing/canary/-/releases)
|
||||
<br>
|
||||
<a href="https://discord.gg/PEuzjrFXUA">
|
||||
<img src="https://img.shields.io/discord/1294443224030511104?color=5865F2&label=Ryubing&logo=discord&logoColor=white" alt="Discord">
|
||||
@ -31,7 +31,7 @@
|
||||
<br>
|
||||
This is not a Ryujinx revival project. This is not a Phoenix project.
|
||||
<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 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**.
|
||||
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.
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
@ -111,7 +111,7 @@ See [LICENSE.txt](LICENSE.txt) and [THIRDPARTY.md](distribution/legal/THIRDPARTY
|
||||
|
||||
## 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.
|
||||
- [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.
|
@ -1847,6 +1847,131 @@
|
||||
"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",
|
||||
"Translations": {
|
||||
@ -1969,7 +2094,7 @@
|
||||
"tr_TR": "Toplam Oyun Süresi: {0}",
|
||||
"uk_UA": "",
|
||||
"zh_CN": "总游戏时间: {0}",
|
||||
"zh_TW": ""
|
||||
"zh_TW": "總遊戲時間: {0}"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -3159,7 +3284,7 @@
|
||||
"he_IL": "{1}/{0} משחקים נטענו",
|
||||
"it_IT": "{0}/{1} giochi caricati",
|
||||
"ja_JP": "{0}/{1} ゲーム",
|
||||
"ko_KR": "{0}/{1}개의 게임 확인",
|
||||
"ko_KR": "{0}/{1}개의 게임 타이틀",
|
||||
"no_NO": "{0}/{1} Spill Lastet",
|
||||
"pl_PL": "{0}/{1} Załadowane gry",
|
||||
"pt_BR": "{0}/{1} Jogos Carregados",
|
||||
@ -5450,26 +5575,26 @@
|
||||
{
|
||||
"ID": "SettingsTabGraphicsAPI",
|
||||
"Translations": {
|
||||
"ar_SA": "API الرسومات ",
|
||||
"de_DE": "Grafik-API",
|
||||
"el_GR": "API Γραφικά",
|
||||
"en_US": "Graphics API",
|
||||
"es_ES": "API de gráficos",
|
||||
"fr_FR": "API Graphique",
|
||||
"he_IL": "ממשק גראפי",
|
||||
"it_IT": "API grafica",
|
||||
"ja_JP": "グラフィックスAPI",
|
||||
"ko_KR": "그래픽 API",
|
||||
"no_NO": "Grafikk API",
|
||||
"pl_PL": "Graficzne API",
|
||||
"pt_BR": "API gráfica",
|
||||
"ru_RU": "Графические API",
|
||||
"sv_SE": "Grafik-API",
|
||||
"th_TH": "API กราฟฟิก",
|
||||
"tr_TR": "Grafikler API",
|
||||
"uk_UA": "Графічний API",
|
||||
"zh_CN": "图形 API",
|
||||
"zh_TW": "圖形 API"
|
||||
"ar_SA": "API الرسومات و تحسين",
|
||||
"de_DE": "Grafik-API & Optimierung",
|
||||
"el_GR": "API Γραφικά & Βελτιστοποίηση",
|
||||
"en_US": "Graphics API & Optimization",
|
||||
"es_ES": "API de gráficos & Optimización",
|
||||
"fr_FR": "API Graphique & Optimisation",
|
||||
"he_IL": "ממשק גראפי & אופטימיזציה",
|
||||
"it_IT": "API grafica & Ottimizzazione",
|
||||
"ja_JP": "グラフィックスAPI&最適化",
|
||||
"ko_KR": "그래픽 API & 최적화",
|
||||
"no_NO": "Grafikk-API & Optimalisering",
|
||||
"pl_PL": "Graficzne API & Optymalizacja",
|
||||
"pt_BR": "API gráfica & Otimização",
|
||||
"ru_RU": "Графический API & Оптимизация",
|
||||
"sv_SE": "Grafik-API & Optimering",
|
||||
"th_TH": "API กราฟฟิก & การเพิ่มประสิทธิภาพ",
|
||||
"tr_TR": "Grafikler API & Optimizasyon",
|
||||
"uk_UA": "Графічний API & Оптимізація",
|
||||
"zh_CN": "图形 API & 优化",
|
||||
"zh_TW": "圖形 API & 優化"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -6547,6 +6672,31 @@
|
||||
"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",
|
||||
"Translations": {
|
||||
@ -7069,7 +7219,7 @@
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
"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": "מושבת",
|
||||
"it_IT": "Disabilitato",
|
||||
"ja_JP": "無効",
|
||||
"ko_KR": "비활성화됨",
|
||||
"ko_KR": "비활성화",
|
||||
"no_NO": "Deaktivert",
|
||||
"pl_PL": "Wyłączone",
|
||||
"pt_BR": "Desabilitado",
|
||||
@ -12973,53 +13123,28 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "DialogUpdaterFailedToGetVersionMessage",
|
||||
"ID": "DialogUpdaterConvertFailedServerMessage",
|
||||
"Translations": {
|
||||
"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.",
|
||||
"el_GR": "Προέκυψε ένα σφάλμα στη λήψη πληροφοριών έκδοσης από τα GitHub Releases. Αυτό δύναται να συμβεί αν μία έκδοση χτίζεται αυτή τη στιγμή στα GitHub Actions. Παρακαλούμε προσπαθήστε αργότερα.",
|
||||
"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.",
|
||||
"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.",
|
||||
"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.",
|
||||
"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.",
|
||||
"ja_JP": "Github からのリリース情報取得時にエラーが発生しました. Github Actions でリリースファイルを作成中かもしれません. 後ほどもう一度試してみてください.",
|
||||
"ko_KR": "GitHub에서 릴리스 정보를 검색하는 동안 오류가 발생했습니다. 현재 GitHub Actions에서 새 릴리스를 컴파일하는 중일 때 발생할 수 있습니다. 몇 분 후에 다시 시도해 주세요.",
|
||||
"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.",
|
||||
"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.",
|
||||
"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.",
|
||||
"ru_RU": "Произошла ошибка при попытке получить информацию о выпуске от GitHub Release. Это может быть вызвано тем, что в данный момент в GitHub Actions компилируется новый релиз. Повторите попытку позже.",
|
||||
"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.",
|
||||
"th_TH": "เกิดข้อผิดพลาดขณะพยายามรับข้อมูลเวอร์ชั่นจาก GitHub Release ปัญหานี้อาจเกิดขึ้นได้หากมีการรวบรวมเวอร์ชั่นใหม่โดย GitHub โปรดลองอีกครั้งในอีกไม่กี่นาทีข้างหน้า",
|
||||
"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.",
|
||||
"uk_UA": "Під час спроби отримати інформацію про випуск із GitHub Release сталася помилка. Це може бути спричинено, якщо новий випуск компілюється GitHub Actions. Повторіть спробу через кілька хвилин.",
|
||||
"zh_CN": "尝试从 Github 获取版本信息时无效,可能由于 GitHub Actions 正在编译新版本。\n请过一会再试。",
|
||||
"zh_TW": "嘗試從 GitHub Release 取得發布資訊時發生錯誤。如果 GitHub Actions 正在編譯新版本,則可能會出現這種情況。請幾分鐘後再試一次。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"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 版本。"
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "Failed to convert the Ryujinx version received from the update server.",
|
||||
"es_ES": "",
|
||||
"fr_FR": "La conversion de la version de Ryujinx reçue du serveur a échoué.",
|
||||
"he_IL": "",
|
||||
"it_IT": "",
|
||||
"ja_JP": "",
|
||||
"ko_KR": "업데이트 서버에서 받은 Ryujinx 버전을 변환하는 데 실패했습니다.",
|
||||
"no_NO": "Kunne ikke konvertere Ryujinx-versjonen som ble mottatt fra oppdateringsserveren.",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Falha em atualizar a versão do Ryujinx recebida do servidor de atualização.",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
"zh_CN": "无法转换从更新服务器接收的 Ryujinx 版本。",
|
||||
"zh_TW": "無法轉換從更新何服器接收的 Ryujinx 版本。"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -16422,6 +16547,31 @@
|
||||
"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",
|
||||
"Translations": {
|
||||
@ -18394,7 +18544,7 @@
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
"zh_CN": "{0} FPS ({1}毫秒)",
|
||||
"zh_TW": ""
|
||||
"zh_TW": "{0} FPS ({1}毫秒)"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -19684,7 +19834,7 @@
|
||||
"he_IL": "מוריד עדכון...",
|
||||
"it_IT": "Download dell'aggiornamento...",
|
||||
"ja_JP": "アップデートをダウンロード中...",
|
||||
"ko_KR": "업데이트 내려받기 중...",
|
||||
"ko_KR": "업데이트 내려받는 중...",
|
||||
"no_NO": "Laster ned oppdatering...",
|
||||
"pl_PL": "Pobieranie Aktualizacji...",
|
||||
"pt_BR": "Baixando Atualização...",
|
||||
@ -23294,7 +23444,7 @@
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
"zh_CN": "查看更新日志",
|
||||
"zh_TW": ""
|
||||
"zh_TW": "檢視更新日誌"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -23409,7 +23559,7 @@
|
||||
"he_IL": "",
|
||||
"it_IT": "Disabilitato",
|
||||
"ja_JP": "無効",
|
||||
"ko_KR": "비활성화됨",
|
||||
"ko_KR": "비활성화",
|
||||
"no_NO": "Deaktivert",
|
||||
"pl_PL": "Wyłączone",
|
||||
"pt_BR": "Desativado",
|
||||
@ -24372,6 +24522,106 @@
|
||||
"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",
|
||||
"Translations": {
|
||||
@ -24534,7 +24784,7 @@
|
||||
"he_IL": "",
|
||||
"it_IT": "",
|
||||
"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.",
|
||||
"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.",
|
||||
@ -24559,7 +24809,7 @@
|
||||
"he_IL": "",
|
||||
"it_IT": "",
|
||||
"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.",
|
||||
"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.",
|
||||
@ -24634,7 +24884,7 @@
|
||||
"he_IL": "",
|
||||
"it_IT": "",
|
||||
"ja_JP": "",
|
||||
"ko_KR": "부팅되지 않거나 활동 흔적이 보이지 않습니다.",
|
||||
"ko_KR": "부팅되지 않거나 동작하지 않습니다.",
|
||||
"no_NO": "Starter ikke opp eller viser ingen tegn til aktivitet.",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Não inicializa ou não mostra sinais de atividade.",
|
||||
|
@ -33,23 +33,29 @@ echo -n "APPL????" > "$APP_BUNDLE_DIRECTORY/Contents/PkgInfo"
|
||||
echo "Running bundle fix up python script"
|
||||
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
|
||||
echo "Starting signing process"
|
||||
if ! [ -x "$(command -v codesign)" ];
|
||||
then
|
||||
if ! [ -x "$(command -v rcodesign)" ];
|
||||
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
|
||||
fi
|
||||
|
||||
# cargo install apple-codesign
|
||||
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"
|
||||
else
|
||||
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"
|
||||
fi
|
||||
|
@ -20,6 +20,18 @@ SOURCE_REVISION_ID=$6
|
||||
CONFIGURATION=$7
|
||||
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
|
||||
RELEASE_TAR_FILE_NAME=ryujinx-canary-$VERSION-macos_universal.app.tar
|
||||
elif [ "$VERSION" == "1.1.0" ]; then
|
||||
|
@ -20,6 +20,18 @@ SOURCE_REVISION_ID=$6
|
||||
CONFIGURATION=$7
|
||||
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
|
||||
RELEASE_TAR_FILE_NAME=nogui-ryujinx-canary-$VERSION-macos_universal.tar
|
||||
elif [ "$VERSION" == "1.1.0" ]; then
|
||||
|
@ -1125,6 +1125,7 @@
|
||||
0100034012606000,"Family Mysteries: Poisonous Promises",audio;crash,menus,2021-11-26 12:35:06
|
||||
010017C012726000,"Fantasy Friends",,playable,2022-10-17 19:42:39
|
||||
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
|
||||
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
|
||||
|
|
18
nuget.config
18
nuget.config
@ -4,20 +4,8 @@
|
||||
<packageSources>
|
||||
<clear />
|
||||
<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" />
|
||||
<add key="RyubingPkgs" value="https://git.ryujinx.app/api/v4/projects/1/packages/nuget/index.json" />
|
||||
<!-- Only needed when using pre-release versions of Ryujinx.LibHac. -->
|
||||
<!--<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>
|
||||
|
||||
<!-- 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>
|
||||
|
@ -7,7 +7,6 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
|
||||
<ProjectReference Include="..\Ryujinx.Memory\Ryujinx.Memory.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -254,7 +254,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
|
||||
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)
|
||||
|
@ -774,6 +774,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
instI |= 1 << 22; // sh flag
|
||||
imm >>= 12;
|
||||
}
|
||||
|
||||
WriteInstructionAuto(instI | (EncodeUImm12(imm, 0) << 10), rd, rn);
|
||||
}
|
||||
else
|
||||
@ -1128,7 +1129,6 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
};
|
||||
}
|
||||
|
||||
#pragma warning disable IDE0051 // Remove unused private member
|
||||
private void WriteInt16(short value)
|
||||
{
|
||||
WriteUInt16((ushort)value);
|
||||
@ -1143,7 +1143,6 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
{
|
||||
_stream.WriteByte(value);
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
private void WriteUInt16(ushort value)
|
||||
{
|
||||
|
@ -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 OR all ones will be equal all ones, so one can just use MOV.
|
||||
// Any value XOR all ones will be equal its inverse, so one can just use MVN.
|
||||
if (value == 0 || value == ulong.MaxValue)
|
||||
if (value is 0 or ulong.MaxValue)
|
||||
{
|
||||
immN = 0;
|
||||
immS = 0;
|
||||
|
@ -1,6 +1,7 @@
|
||||
using ARMeilleure.CodeGen.Linking;
|
||||
using ARMeilleure.CodeGen.RegisterAllocators;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using Microsoft.IO;
|
||||
using Ryujinx.Common.Memory;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -14,7 +15,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
private const int CbnzInstLength = 4;
|
||||
private const int LdrLitInstLength = 4;
|
||||
|
||||
private readonly Stream _stream;
|
||||
private readonly RecyclableMemoryStream _stream;
|
||||
|
||||
public int StreamOffset => (int)_stream.Length;
|
||||
|
||||
|
@ -189,8 +189,8 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
// The only blocks which can have 0 successors are exit blocks.
|
||||
Operation last = block.Operations.Last;
|
||||
|
||||
Debug.Assert(last.Instruction == Instruction.Tailcall ||
|
||||
last.Instruction == Instruction.Return);
|
||||
Debug.Assert(last.Instruction is Instruction.Tailcall or
|
||||
Instruction.Return);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -464,7 +464,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
Operand dest = operation.Destination;
|
||||
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(source.Type != OperandType.V128);
|
||||
|
||||
@ -483,7 +483,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
Operand dest = operation.Destination;
|
||||
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(source.Type.IsInteger());
|
||||
|
||||
@ -1463,7 +1463,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
|
||||
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)
|
||||
@ -1499,6 +1499,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (memOp.Index != default)
|
||||
{
|
||||
return false;
|
||||
@ -1553,7 +1554,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
|
||||
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.Value == op2.Value);
|
||||
}
|
||||
@ -1569,13 +1570,11 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
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)
|
||||
{
|
||||
Debug.Assert(op1.Type == op2.Type);
|
||||
Debug.Assert(op1.Type == op3.Type);
|
||||
Debug.Assert(op1.Type == op4.Type);
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
}
|
||||
}
|
||||
|
@ -509,7 +509,6 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
|
||||
context.Assembler.WriteInstruction(instruction, rd, rn);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void GenerateScalarTernary(
|
||||
|
@ -137,6 +137,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
{
|
||||
return val != 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -736,19 +736,19 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
{
|
||||
IntrinsicInfo info = IntrinsicTable.GetInfo(intrinsic & ~(Intrinsic.Arm64VTypeMask | Intrinsic.Arm64VSizeMask));
|
||||
|
||||
return info.Type == IntrinsicType.ScalarBinaryRd ||
|
||||
info.Type == IntrinsicType.ScalarTernaryFPRdByElem ||
|
||||
info.Type == IntrinsicType.ScalarTernaryShlRd ||
|
||||
info.Type == IntrinsicType.ScalarTernaryShrRd ||
|
||||
info.Type == IntrinsicType.Vector128BinaryRd ||
|
||||
info.Type == IntrinsicType.VectorBinaryRd ||
|
||||
info.Type == IntrinsicType.VectorInsertByElem ||
|
||||
info.Type == IntrinsicType.VectorTernaryRd ||
|
||||
info.Type == IntrinsicType.VectorTernaryRdBitwise ||
|
||||
info.Type == IntrinsicType.VectorTernaryFPRdByElem ||
|
||||
info.Type == IntrinsicType.VectorTernaryRdByElem ||
|
||||
info.Type == IntrinsicType.VectorTernaryShlRd ||
|
||||
info.Type == IntrinsicType.VectorTernaryShrRd;
|
||||
return info.Type is IntrinsicType.ScalarBinaryRd or
|
||||
IntrinsicType.ScalarTernaryFPRdByElem or
|
||||
IntrinsicType.ScalarTernaryShlRd or
|
||||
IntrinsicType.ScalarTernaryShrRd or
|
||||
IntrinsicType.Vector128BinaryRd or
|
||||
IntrinsicType.VectorBinaryRd or
|
||||
IntrinsicType.VectorInsertByElem or
|
||||
IntrinsicType.VectorTernaryRd or
|
||||
IntrinsicType.VectorTernaryRdBitwise or
|
||||
IntrinsicType.VectorTernaryFPRdByElem or
|
||||
IntrinsicType.VectorTernaryRdByElem or
|
||||
IntrinsicType.VectorTernaryShlRd or
|
||||
IntrinsicType.VectorTernaryShrRd;
|
||||
}
|
||||
|
||||
private static bool HasConstSrc1(Operation node, ulong value)
|
||||
@ -849,7 +849,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
|
||||
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));
|
||||
|
||||
// Those have integer inputs that don't support consts.
|
||||
return info.Type != IntrinsicType.ScalarFPConvGpr &&
|
||||
info.Type != IntrinsicType.ScalarFPConvFixedGpr &&
|
||||
info.Type != IntrinsicType.SetRegister;
|
||||
return info.Type is not IntrinsicType.ScalarFPConvGpr and
|
||||
not IntrinsicType.ScalarFPConvFixedGpr and
|
||||
not IntrinsicType.SetRegister;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -37,6 +37,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
{
|
||||
EvaluateBinaryI64(operation, (x, y) => x + y);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.BitwiseAnd:
|
||||
@ -48,6 +49,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
{
|
||||
EvaluateBinaryI64(operation, (x, y) => x & y);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.BitwiseExclusiveOr:
|
||||
@ -59,6 +61,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
{
|
||||
EvaluateBinaryI64(operation, (x, y) => x ^ y);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.BitwiseNot:
|
||||
@ -70,6 +73,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
{
|
||||
EvaluateUnaryI64(operation, (x) => ~x);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.BitwiseOr:
|
||||
@ -81,6 +85,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
{
|
||||
EvaluateBinaryI64(operation, (x, y) => x | y);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.ConvertI64ToI32:
|
||||
@ -88,6 +93,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
{
|
||||
EvaluateUnaryI32(operation, (x) => x);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.Compare:
|
||||
@ -129,6 +135,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.Copy:
|
||||
@ -140,6 +147,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
{
|
||||
EvaluateUnaryI64(operation, (x) => x);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.Divide:
|
||||
@ -151,6 +159,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
{
|
||||
EvaluateBinaryI64(operation, (x, y) => y != 0 ? x / y : 0);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.DivideUI:
|
||||
@ -162,6 +171,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
{
|
||||
EvaluateBinaryI64(operation, (x, y) => y != 0 ? (long)((ulong)x / (ulong)y) : 0);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.Multiply:
|
||||
@ -173,6 +183,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
{
|
||||
EvaluateBinaryI64(operation, (x, y) => x * y);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.Negate:
|
||||
@ -184,6 +195,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
{
|
||||
EvaluateUnaryI64(operation, (x) => -x);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.ShiftLeft:
|
||||
@ -195,6 +207,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
{
|
||||
EvaluateBinaryI64(operation, (x, y) => x << (int)y);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.ShiftRightSI:
|
||||
@ -206,6 +219,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
{
|
||||
EvaluateBinaryI64(operation, (x, y) => x >> (int)y);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.ShiftRightUI:
|
||||
@ -217,6 +231,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
{
|
||||
EvaluateBinaryI64(operation, (x, y) => (long)((ulong)x >> (int)y));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.SignExtend16:
|
||||
@ -228,6 +243,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
{
|
||||
EvaluateUnaryI64(operation, (x) => (short)x);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.SignExtend32:
|
||||
@ -239,6 +255,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
{
|
||||
EvaluateUnaryI64(operation, (x) => (int)x);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.SignExtend8:
|
||||
@ -250,6 +267,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
{
|
||||
EvaluateUnaryI64(operation, (x) => (sbyte)x);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.ZeroExtend16:
|
||||
@ -261,6 +279,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
{
|
||||
EvaluateUnaryI64(operation, (x) => (ushort)x);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.ZeroExtend32:
|
||||
@ -272,6 +291,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
{
|
||||
EvaluateUnaryI64(operation, (x) => (uint)x);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.ZeroExtend8:
|
||||
@ -283,6 +303,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
{
|
||||
EvaluateUnaryI64(operation, (x) => (byte)x);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.Subtract:
|
||||
@ -294,6 +315,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
{
|
||||
EvaluateBinaryI64(operation, (x, y) => x - y);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -227,11 +227,11 @@ namespace ARMeilleure.CodeGen.Optimizations
|
||||
|
||||
private static bool HasSideEffects(Operation node)
|
||||
{
|
||||
return node.Instruction == Instruction.Call
|
||||
|| node.Instruction == Instruction.Tailcall
|
||||
|| node.Instruction == Instruction.CompareAndSwap
|
||||
|| node.Instruction == Instruction.CompareAndSwap16
|
||||
|| node.Instruction == Instruction.CompareAndSwap8;
|
||||
return node.Instruction is Instruction.Call
|
||||
or Instruction.Tailcall
|
||||
or Instruction.CompareAndSwap
|
||||
or Instruction.CompareAndSwap16
|
||||
or Instruction.CompareAndSwap8;
|
||||
}
|
||||
|
||||
private static bool IsPropagableCompare(Operation operation)
|
||||
|
@ -847,7 +847,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
||||
// 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
|
||||
// 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);
|
||||
|
||||
@ -1120,8 +1120,8 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
||||
|
||||
private static bool IsLocalOrRegister(OperandKind kind)
|
||||
{
|
||||
return kind == OperandKind.LocalVariable ||
|
||||
kind == OperandKind.Register;
|
||||
return kind is OperandKind.LocalVariable or
|
||||
OperandKind.Register;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1478,7 +1478,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||
|
||||
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)
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
@ -13,7 +12,6 @@ namespace ARMeilleure.CodeGen.X86
|
||||
private const int BadOp = 0;
|
||||
|
||||
[Flags]
|
||||
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
|
||||
private enum InstructionFlags
|
||||
{
|
||||
None = 0,
|
||||
|
@ -20,12 +20,12 @@ namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
if (GetCurrentCallConv() == CallConvName.Windows)
|
||||
{
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
|
||||
return (1 << (int)X86Register.Rax) |
|
||||
(1 << (int)X86Register.Rcx) |
|
||||
(1 << (int)X86Register.Rdx) |
|
||||
(1 << (int)X86Register.R8) |
|
||||
(1 << (int)X86Register.R9) |
|
||||
(1 << (int)X86Register.R8) |
|
||||
(1 << (int)X86Register.R9) |
|
||||
(1 << (int)X86Register.R10) |
|
||||
(1 << (int)X86Register.R11);
|
||||
}
|
||||
@ -36,11 +36,11 @@ namespace ARMeilleure.CodeGen.X86
|
||||
(1 << (int)X86Register.Rdx) |
|
||||
(1 << (int)X86Register.Rsi) |
|
||||
(1 << (int)X86Register.Rdi) |
|
||||
(1 << (int)X86Register.R8) |
|
||||
(1 << (int)X86Register.R9) |
|
||||
(1 << (int)X86Register.R8) |
|
||||
(1 << (int)X86Register.R9) |
|
||||
(1 << (int)X86Register.R10) |
|
||||
(1 << (int)X86Register.R11);
|
||||
#pragma warning restore IDE0055
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
using ARMeilleure.CodeGen.RegisterAllocators;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using Microsoft.IO;
|
||||
using Ryujinx.Common.Memory;
|
||||
using System.IO;
|
||||
using System.Numerics;
|
||||
|
||||
namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
class CodeGenContext
|
||||
{
|
||||
private readonly Stream _stream;
|
||||
private readonly RecyclableMemoryStream _stream;
|
||||
private readonly Operand[] _blockLabels;
|
||||
|
||||
public int StreamOffset => (int)_stream.Length;
|
||||
|
@ -175,8 +175,8 @@ namespace ARMeilleure.CodeGen.X86
|
||||
// The only blocks which can have 0 successors are exit blocks.
|
||||
Operation last = block.Operations.Last;
|
||||
|
||||
Debug.Assert(last.Instruction == Instruction.Tailcall ||
|
||||
last.Instruction == Instruction.Return);
|
||||
Debug.Assert(last.Instruction is Instruction.Tailcall or
|
||||
Instruction.Return);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -478,7 +478,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||
Debug.Assert(HardwareCapabilities.SupportsVexEncoding);
|
||||
|
||||
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);
|
||||
Debug.Assert(dest.Type == OperandType.V128);
|
||||
@ -788,7 +788,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||
Operand dest = operation.Destination;
|
||||
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)
|
||||
{
|
||||
@ -1723,7 +1723,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||
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.Value == op2.Value);
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
PreAllocatorSystemV.InsertCallCopies(block.Operations, node);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.ConvertToFPUI:
|
||||
@ -81,6 +82,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
nextNode = PreAllocatorSystemV.InsertLoadArgumentCopy(cctx, ref buffer, block.Operations, preservedArgs, node);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.Negate:
|
||||
@ -88,6 +90,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
GenerateNegate(block.Operations, node);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.Return:
|
||||
@ -99,6 +102,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
PreAllocatorSystemV.InsertReturnCopy(block.Operations, node);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.Tailcall:
|
||||
@ -110,6 +114,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
PreAllocatorSystemV.InsertTailcallCopies(block.Operations, node);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.VectorInsert8:
|
||||
@ -117,6 +122,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
GenerateVectorInsert8(block.Operations, node);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Instruction.Extended:
|
||||
@ -132,6 +138,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||
|
||||
node.SetSources([Const(stackOffset)]);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -312,9 +319,9 @@ namespace ARMeilleure.CodeGen.X86
|
||||
|
||||
case Instruction.Extended:
|
||||
{
|
||||
bool isBlend = node.Intrinsic == Intrinsic.X86Blendvpd ||
|
||||
node.Intrinsic == Intrinsic.X86Blendvps ||
|
||||
node.Intrinsic == Intrinsic.X86Pblendvb;
|
||||
bool isBlend = node.Intrinsic is Intrinsic.X86Blendvpd or
|
||||
Intrinsic.X86Blendvps or
|
||||
Intrinsic.X86Pblendvb;
|
||||
|
||||
// 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.
|
||||
@ -513,8 +520,8 @@ namespace ARMeilleure.CodeGen.X86
|
||||
Operand dest = node.Destination;
|
||||
Operand source = node.GetSource(0);
|
||||
|
||||
Debug.Assert(dest.Type == OperandType.FP32 ||
|
||||
dest.Type == OperandType.FP64, $"Invalid destination type \"{dest.Type}\".");
|
||||
Debug.Assert(dest.Type is OperandType.FP32 or
|
||||
OperandType.FP64, $"Invalid destination type \"{dest.Type}\".");
|
||||
|
||||
Operation currentNode = node;
|
||||
|
||||
@ -761,7 +768,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||
|
||||
Comparison compType = (Comparison)comp.AsInt32();
|
||||
|
||||
return compType == Comparison.Equal || compType == Comparison.NotEqual;
|
||||
return compType is Comparison.Equal or Comparison.NotEqual;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -248,12 +248,12 @@ namespace ARMeilleure.CodeGen.X86
|
||||
|
||||
private static bool IsMemoryLoadOrStore(Instruction inst)
|
||||
{
|
||||
return inst == Instruction.Load ||
|
||||
inst == Instruction.Load16 ||
|
||||
inst == Instruction.Load8 ||
|
||||
inst == Instruction.Store ||
|
||||
inst == Instruction.Store16 ||
|
||||
inst == Instruction.Store8;
|
||||
return inst is Instruction.Load or
|
||||
Instruction.Load16 or
|
||||
Instruction.Load8 or
|
||||
Instruction.Store or
|
||||
Instruction.Store16 or
|
||||
Instruction.Store8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,5 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
|
||||
enum X86Register
|
||||
{
|
||||
Invalid = -1,
|
||||
|
@ -254,8 +254,8 @@ namespace ARMeilleure.Decoders
|
||||
}
|
||||
|
||||
// Compare and branch instructions are always conditional.
|
||||
if (opCode.Instruction.Name == InstName.Cbz ||
|
||||
opCode.Instruction.Name == InstName.Cbnz)
|
||||
if (opCode.Instruction.Name is InstName.Cbz or
|
||||
InstName.Cbnz)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -274,9 +274,10 @@ namespace ARMeilleure.Decoders
|
||||
{
|
||||
if (opCode is OpCodeT32)
|
||||
{
|
||||
return opCode.Instruction.Name != InstName.Tst && opCode.Instruction.Name != InstName.Teq &&
|
||||
opCode.Instruction.Name != InstName.Cmp && opCode.Instruction.Name != InstName.Cmn;
|
||||
return opCode.Instruction.Name is not InstName.Tst and not InstName.Teq and
|
||||
not InstName.Cmp and not InstName.Cmn;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -284,7 +285,7 @@ namespace ARMeilleure.Decoders
|
||||
// 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
|
||||
// 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;
|
||||
|
||||
@ -326,15 +327,15 @@ namespace ARMeilleure.Decoders
|
||||
}
|
||||
|
||||
// Explicit branch instructions.
|
||||
return opCode is IOpCode32BImm ||
|
||||
opCode is IOpCode32BReg;
|
||||
return opCode is IOpCode32BImm or
|
||||
IOpCode32BReg;
|
||||
}
|
||||
|
||||
private static bool IsCall(OpCode opCode)
|
||||
{
|
||||
return opCode.Instruction.Name == InstName.Bl ||
|
||||
opCode.Instruction.Name == InstName.Blr ||
|
||||
opCode.Instruction.Name == InstName.Blx;
|
||||
return opCode.Instruction.Name is InstName.Bl or
|
||||
InstName.Blr or
|
||||
InstName.Blx;
|
||||
}
|
||||
|
||||
private static bool IsException(OpCode opCode)
|
||||
@ -344,9 +345,9 @@ namespace ARMeilleure.Decoders
|
||||
|
||||
private static bool IsTrap(OpCode opCode)
|
||||
{
|
||||
return opCode.Instruction.Name == InstName.Brk ||
|
||||
opCode.Instruction.Name == InstName.Trap ||
|
||||
opCode.Instruction.Name == InstName.Und;
|
||||
return opCode.Instruction.Name is InstName.Brk or
|
||||
InstName.Trap or
|
||||
InstName.Und;
|
||||
}
|
||||
|
||||
public static OpCode DecodeOpCode(IMemoryManager memory, ulong address, ExecutionMode mode)
|
||||
|
@ -162,6 +162,7 @@ namespace ARMeilleure.Decoders
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ namespace ARMeilleure.Decoders
|
||||
Instruction = InstDescriptor.Undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
Q = ((opCode >> 21) & 0x1) != 0;
|
||||
|
||||
RegisterSize = Q ? RegisterSize.Simd128 : RegisterSize.Simd64;
|
||||
|
@ -40,7 +40,7 @@ namespace ARMeilleure.Decoders
|
||||
Rn = (opCode >> 16) & 0xf;
|
||||
|
||||
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];
|
||||
|
||||
|
@ -45,7 +45,7 @@ namespace ARMeilleure.Decoders
|
||||
Rn = (opCode >> 16) & 0xf;
|
||||
|
||||
WBack = Rm != RegisterAlias.Aarch32Pc;
|
||||
RegisterIndex = Rm != RegisterAlias.Aarch32Pc && Rm != RegisterAlias.Aarch32Sp;
|
||||
RegisterIndex = Rm is not RegisterAlias.Aarch32Pc and not RegisterAlias.Aarch32Sp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,8 +28,8 @@ namespace ARMeilleure.Decoders
|
||||
MemOp type = WBack ? (MemOp)((opCode >> 10) & 3) : MemOp.Unsigned;
|
||||
|
||||
PostIdx = type == MemOp.PostIndexed;
|
||||
Unscaled = type == MemOp.Unscaled ||
|
||||
type == MemOp.Unprivileged;
|
||||
Unscaled = type is MemOp.Unscaled or
|
||||
MemOp.Unprivileged;
|
||||
|
||||
// Unscaled and Unprivileged doesn't write back,
|
||||
// but they do use the 9-bits Signed Immediate.
|
||||
|
@ -1381,6 +1381,7 @@ namespace ARMeilleure.Decoders
|
||||
{
|
||||
thumbEncoding = $"1110{thumbEncoding.AsSpan(4)}";
|
||||
}
|
||||
|
||||
SetT32(thumbEncoding, name, emitter, makeOpT32);
|
||||
}
|
||||
|
||||
@ -1409,6 +1410,7 @@ namespace ARMeilleure.Decoders
|
||||
{
|
||||
throw new ArgumentException("Invalid ASIMD instruction encoding");
|
||||
}
|
||||
|
||||
SetT32(thumbEncoding, name, emitter, makeOpT32);
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ namespace ARMeilleure.Diagnostics
|
||||
{
|
||||
class IRDumper
|
||||
{
|
||||
private const string Indentation = " ";
|
||||
private const char Indentation = ' ';
|
||||
|
||||
private int _indentLevel;
|
||||
|
||||
@ -30,14 +30,11 @@ namespace ARMeilleure.Diagnostics
|
||||
|
||||
private void Indent()
|
||||
{
|
||||
_builder.EnsureCapacity(_builder.Capacity + _indentLevel * Indentation.Length);
|
||||
if (_indentLevel == 0)
|
||||
return;
|
||||
|
||||
for (int index = 0; index < _indentLevel; index++)
|
||||
{
|
||||
#pragma warning disable CA1834 // Use StringBuilder.Append(char) for single character strings
|
||||
_builder.Append(Indentation);
|
||||
#pragma warning restore CA1834
|
||||
}
|
||||
_builder.EnsureCapacity(_builder.Capacity + _indentLevel);
|
||||
_builder.Append(Indentation, _indentLevel);
|
||||
}
|
||||
|
||||
private void IncreaseIndentation()
|
||||
@ -235,8 +232,8 @@ namespace ARMeilleure.Diagnostics
|
||||
{
|
||||
_builder.Append('.').Append(operation.Intrinsic);
|
||||
}
|
||||
else if (operation.Instruction == Instruction.BranchIf ||
|
||||
operation.Instruction == Instruction.Compare)
|
||||
else if (operation.Instruction is Instruction.BranchIf or
|
||||
Instruction.Compare)
|
||||
{
|
||||
comparison = true;
|
||||
}
|
||||
@ -262,6 +259,7 @@ namespace ARMeilleure.Diagnostics
|
||||
DumpOperand(source);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -8,8 +8,8 @@ namespace ARMeilleure.Instructions
|
||||
static class CryptoHelper
|
||||
{
|
||||
#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,
|
||||
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
|
||||
];
|
||||
|
||||
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,
|
||||
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
|
||||
];
|
||||
|
||||
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,
|
||||
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
|
||||
];
|
||||
|
||||
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,
|
||||
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
|
||||
];
|
||||
|
||||
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,
|
||||
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
|
||||
];
|
||||
|
||||
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,
|
||||
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
|
||||
];
|
||||
|
||||
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,
|
||||
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
|
||||
];
|
||||
|
||||
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,
|
||||
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
|
||||
];
|
||||
|
||||
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
|
||||
];
|
||||
|
||||
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
|
||||
];
|
||||
#pragma warning restore IDE1006
|
||||
|
||||
#endregion
|
||||
|
||||
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 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 + 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 + 3] = (byte)((uint)_gfMul0B[row0] ^ _gfMul0D[row1] ^ _gfMul09[row2] ^ _gfMul0E[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 + 2] = (byte)((uint)GfMul0D[row0] ^ GfMul09[row1] ^ GfMul0E[row2] ^ GfMul0B[row3]);
|
||||
outState[idx + 3] = (byte)((uint)GfMul0B[row0] ^ GfMul0D[row1] ^ GfMul09[row2] ^ GfMul0E[row3]);
|
||||
}
|
||||
|
||||
return new V128(outState);
|
||||
@ -211,7 +211,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
for (int idx = 0; idx <= 15; idx++)
|
||||
{
|
||||
outState[_isrPerm[idx]] = inState[idx];
|
||||
outState[IsrPerm[idx]] = inState[idx];
|
||||
}
|
||||
|
||||
return new V128(outState);
|
||||
@ -224,7 +224,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
for (int idx = 0; idx <= 15; idx++)
|
||||
{
|
||||
outState[idx] = _invSBox[inState[idx]];
|
||||
outState[idx] = InvSBox[inState[idx]];
|
||||
}
|
||||
|
||||
return new V128(outState);
|
||||
@ -244,10 +244,10 @@ namespace ARMeilleure.Instructions
|
||||
byte row2 = inState[idx + 2]; // C, G, K, O: [row2, 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 + 1] = (byte)((uint)row0 ^ _gfMul02[row1] ^ _gfMul03[row2] ^ 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 + 0] = (byte)((uint)GfMul02[row0] ^ GfMul03[row1] ^ 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 + 3] = (byte)((uint)GfMul03[row0] ^ row1 ^ row2 ^ GfMul02[row3]);
|
||||
}
|
||||
|
||||
return new V128(outState);
|
||||
@ -260,7 +260,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
for (int idx = 0; idx <= 15; idx++)
|
||||
{
|
||||
outState[_srPerm[idx]] = inState[idx];
|
||||
outState[SrPerm[idx]] = inState[idx];
|
||||
}
|
||||
|
||||
return new V128(outState);
|
||||
@ -273,7 +273,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
for (int idx = 0; idx <= 15; idx++)
|
||||
{
|
||||
outState[idx] = _sBox[inState[idx]];
|
||||
outState[idx] = SBox[inState[idx]];
|
||||
}
|
||||
|
||||
return new V128(outState);
|
||||
|
@ -899,6 +899,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
n = context.ShiftLeft(n, Const(shift));
|
||||
}
|
||||
|
||||
break;
|
||||
case ShiftType.Asr:
|
||||
if (shift == 32)
|
||||
@ -909,6 +910,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
n = context.ShiftRightSI(n, Const(shift));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -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"}\".");
|
||||
}
|
||||
@ -318,6 +318,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
m = GetRrxC(context, m, setCarry);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ namespace ARMeilleure.Instructions
|
||||
public static Operand EmitCrc32(ArmEmitterContext context, Operand crc, Operand value, int size, bool castagnoli)
|
||||
{
|
||||
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));
|
||||
|
||||
if (castagnoli && Optimizations.UseSse42)
|
||||
|
@ -90,6 +90,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
value = context.ConvertI64ToI32(value);
|
||||
}
|
||||
|
||||
Operand reg = Register(GetRegisterAlias(context.Mode, regIndex), RegisterType.Integer, OperandType.I32);
|
||||
|
||||
context.Copy(reg, value);
|
||||
|
@ -140,7 +140,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
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);
|
||||
|
||||
|
@ -42,6 +42,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
context.Store(exValuePtr, Const(0UL));
|
||||
}
|
||||
|
||||
if (size < 4)
|
||||
{
|
||||
context.Store(context.Add(exValuePtr, Const(exValuePtr.Type, 8L)), Const(0UL));
|
||||
|
@ -59,7 +59,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
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;
|
||||
|
||||
@ -123,9 +123,9 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
private static bool IsSimd(ArmEmitterContext context)
|
||||
{
|
||||
return context.CurrOp is IOpCodeSimd &&
|
||||
!(context.CurrOp is OpCodeSimdMemMs ||
|
||||
context.CurrOp is OpCodeSimdMemSs);
|
||||
return context.CurrOp is IOpCodeSimd and
|
||||
not (OpCodeSimdMemMs or
|
||||
OpCodeSimdMemSs);
|
||||
}
|
||||
|
||||
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"}\".");
|
||||
}
|
||||
@ -768,6 +768,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
m = InstEmitAluHelper.GetRrxC(context, m, setCarry);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ using ARMeilleure.Decoders;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.Translation;
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
@ -33,7 +32,6 @@ namespace ARMeilleure.Instructions
|
||||
public static void Umsubl(ArmEmitterContext context) => EmitMull(context, MullFlags.Subtract);
|
||||
|
||||
[Flags]
|
||||
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
|
||||
private enum MullFlags
|
||||
{
|
||||
Subtract = 0,
|
||||
|
@ -11,11 +11,10 @@ using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper32;
|
||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||
using Func2I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
using Func2I = Func<Operand, Operand, Operand>;
|
||||
|
||||
static partial class InstEmit
|
||||
{
|
||||
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)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
|
@ -231,10 +231,12 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
result |= (long)((i >= end || i < start) ? 0x80 : b++) << (i * 8);
|
||||
}
|
||||
|
||||
for (int i = 8; i < 16; i++)
|
||||
{
|
||||
result2 |= (long)((i >= end || i < start) ? 0x80 : b++) << ((i - 8) * 8);
|
||||
}
|
||||
|
||||
return (result2, result);
|
||||
}
|
||||
|
||||
@ -261,6 +263,7 @@ namespace ARMeilleure.Instructions
|
||||
nMaskHigh = nMaskLow + 0x0808080808080808L;
|
||||
mMaskHigh = mMaskLow + 0x0808080808080808L;
|
||||
}
|
||||
|
||||
nMask = X86GetElements(context, nMaskHigh, nMaskLow);
|
||||
mMask = X86GetElements(context, mMaskHigh, mMaskLow);
|
||||
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);
|
||||
}
|
||||
|
||||
byteOff++;
|
||||
|
||||
res = EmitVectorInsert(context, res, extract, op.Id + index, op.Size);
|
||||
@ -1304,6 +1308,7 @@ namespace ARMeilleure.Instructions
|
||||
case 2:
|
||||
return context.AddIntrinsic(Intrinsic.X86Shufps, op1, op1, Const(1 | (0 << 2) | (3 << 4) | (2 << 6)));
|
||||
}
|
||||
|
||||
break;
|
||||
case 2:
|
||||
// Rev32
|
||||
@ -1316,6 +1321,7 @@ namespace ARMeilleure.Instructions
|
||||
mask = X86GetElements(context, 0x0d0c0f0e_09080b0aL, 0x05040706_01000302L);
|
||||
return context.AddIntrinsic(Intrinsic.X86Pshufb, op1, mask);
|
||||
}
|
||||
|
||||
break;
|
||||
case 1:
|
||||
// Rev16
|
||||
@ -1341,6 +1347,7 @@ namespace ARMeilleure.Instructions
|
||||
case 3:
|
||||
return context.ByteSwap(op1);
|
||||
}
|
||||
|
||||
break;
|
||||
case 1:
|
||||
switch (op.Size)
|
||||
@ -1355,6 +1362,7 @@ namespace ARMeilleure.Instructions
|
||||
context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(op1, Const(0x0000ffff00000000ul)), Const(16)),
|
||||
context.ShiftLeft(context.BitwiseAnd(op1, Const(0x00000000ffff0000ul)), Const(16))));
|
||||
}
|
||||
|
||||
break;
|
||||
case 2:
|
||||
// Swap upper and lower halves.
|
||||
|
@ -2,15 +2,13 @@ using ARMeilleure.Decoders;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.State;
|
||||
using ARMeilleure.Translation;
|
||||
using System;
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||
using Func2I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
using Func2I = Func<Operand, Operand, Operand>;
|
||||
|
||||
static partial class InstEmit
|
||||
{
|
||||
public static void Cmeq_S(ArmEmitterContext context)
|
||||
|
@ -2,17 +2,15 @@ using ARMeilleure.Decoders;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.State;
|
||||
using ARMeilleure.Translation;
|
||||
using System;
|
||||
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper32;
|
||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||
using Func2I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
using Func2I = Func<Operand, Operand, Operand>;
|
||||
|
||||
static partial class InstEmit32
|
||||
{
|
||||
public static void Vceq_V(ArmEmitterContext context)
|
||||
|
@ -8,11 +8,10 @@ using System.Reflection;
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||
using Func1I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
using Func1I = Func<Operand, Operand>;
|
||||
|
||||
static partial class InstEmit
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
@ -1160,7 +1159,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
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);
|
||||
|
||||
@ -1184,7 +1183,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
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)
|
||||
{
|
||||
@ -1203,7 +1202,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -385,6 +385,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.X86Cvtsd2ss, context.VectorZero(), res);
|
||||
}
|
||||
|
||||
res = context.AddIntrinsic(Intrinsic.X86Vcvtps2ph, res, Const(X86GetRoundControl(FPRoundingMode.ToNearest)));
|
||||
res = context.VectorExtract16(res, 0);
|
||||
InsertScalar16(context, op.Vd, op.T, res);
|
||||
@ -397,6 +398,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.X86Cvtss2sd, context.VectorZero(), res);
|
||||
}
|
||||
|
||||
res = context.VectorExtract(op.Size == 1 ? OperandType.I64 : OperandType.I32, res, 0);
|
||||
InsertScalar(context, op.Vd, res);
|
||||
}
|
||||
@ -635,7 +637,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -8,13 +8,12 @@ using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
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
|
||||
{
|
||||
using Func1I = Func<Operand, Operand>;
|
||||
using Func2I = Func<Operand, Operand, Operand>;
|
||||
using Func3I = Func<Operand, Operand, Operand, Operand>;
|
||||
|
||||
static class InstEmitSimdHelper
|
||||
{
|
||||
#region "Masks"
|
||||
@ -363,7 +362,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
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)));
|
||||
|
||||
@ -489,7 +488,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
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 lbl2 = Label();
|
||||
@ -1676,7 +1675,7 @@ namespace ARMeilleure.Instructions
|
||||
int eSize = 8 << size;
|
||||
|
||||
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 lblEnd = Label();
|
||||
@ -1709,7 +1708,7 @@ namespace ARMeilleure.Instructions
|
||||
int eSize = 8 << size;
|
||||
|
||||
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();
|
||||
|
||||
@ -1735,7 +1734,7 @@ namespace ARMeilleure.Instructions
|
||||
int eSizeDst = 8 << sizeDst;
|
||||
|
||||
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 lblEnd = Label();
|
||||
@ -1768,7 +1767,7 @@ namespace ARMeilleure.Instructions
|
||||
int eSizeDst = 8 << sizeDst;
|
||||
|
||||
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();
|
||||
|
||||
|
@ -7,13 +7,12 @@ using System.Reflection;
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
||||
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
|
||||
{
|
||||
using Func1I = Func<Operand, Operand>;
|
||||
using Func2I = Func<Operand, Operand, Operand>;
|
||||
using Func3I = Func<Operand, Operand, Operand, Operand>;
|
||||
|
||||
static class InstEmitSimdHelper32
|
||||
{
|
||||
public static (int, int) GetQuadwordAndSubindex(int index, RegisterSize size)
|
||||
@ -31,7 +30,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
Debug.Assert(type != OperandType.V128);
|
||||
|
||||
if (type == OperandType.FP64 || type == OperandType.I64)
|
||||
if (type is OperandType.FP64 or OperandType.I64)
|
||||
{
|
||||
// From dreg.
|
||||
return context.VectorExtract(type, GetVecA32(reg >> 1), reg & 1);
|
||||
@ -48,7 +47,7 @@ namespace ARMeilleure.Instructions
|
||||
Debug.Assert(value.Type != OperandType.V128);
|
||||
|
||||
Operand vec, insert;
|
||||
if (value.Type == OperandType.FP64 || value.Type == OperandType.I64)
|
||||
if (value.Type is OperandType.FP64 or OperandType.I64)
|
||||
{
|
||||
// From dreg.
|
||||
vec = GetVecA32(reg >> 1);
|
||||
@ -71,7 +70,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
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;
|
||||
vec = GetVecA32(reg >> 2);
|
||||
@ -880,6 +879,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
res = EmitMoveDoubleWordToSide(context, res, side, op.Vd);
|
||||
}
|
||||
|
||||
res = EmitDoubleWordInsert(context, d, res, op.Vd);
|
||||
}
|
||||
|
||||
|
@ -7,13 +7,12 @@ using System.Diagnostics;
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
||||
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
|
||||
{
|
||||
using Func1I = Func<Operand, Operand>;
|
||||
using Func2I = Func<Operand, Operand, Operand>;
|
||||
using Func3I = Func<Operand, Operand, Operand, Operand>;
|
||||
|
||||
static class InstEmitSimdHelper32Arm64
|
||||
{
|
||||
// Intrinsic Helpers
|
||||
@ -146,6 +145,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
res = EmitMoveDoubleWordToSide(context, res, side, op.Vd);
|
||||
}
|
||||
|
||||
res = EmitDoubleWordInsert(context, d, res, op.Vd);
|
||||
}
|
||||
|
||||
|
@ -268,6 +268,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
m = context.BitwiseNot(m);
|
||||
}
|
||||
|
||||
return context.BitwiseExclusiveOr(
|
||||
context.BitwiseAnd(m,
|
||||
context.BitwiseExclusiveOr(d, n)), d);
|
||||
|
@ -40,34 +40,36 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
long offset = 0;
|
||||
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
for (int rep = 0; rep < op.Reps; rep++)
|
||||
for (int elem = 0; elem < op.Elems; elem++)
|
||||
for (int sElem = 0; sElem < op.SElems; sElem++)
|
||||
for (int rep = 0; rep < op.Reps; rep++)
|
||||
{
|
||||
int rtt = (op.Rt + rep + sElem) & 0x1f;
|
||||
|
||||
Operand tt = GetVec(rtt);
|
||||
|
||||
Operand address = context.Add(n, Const(offset));
|
||||
|
||||
if (isLoad)
|
||||
for (int elem = 0; elem < op.Elems; elem++)
|
||||
{
|
||||
EmitLoadSimd(context, address, tt, rtt, elem, op.Size);
|
||||
|
||||
if (op.RegisterSize == RegisterSize.Simd64 && elem == op.Elems - 1)
|
||||
for (int sElem = 0; sElem < op.SElems; sElem++)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -110,6 +110,7 @@ namespace ARMeilleure.Instructions
|
||||
EmitStoreSimd(context, address, d >> 1, index, op.Size);
|
||||
}
|
||||
}
|
||||
|
||||
offset += eBytes;
|
||||
d += op.Increment;
|
||||
}
|
||||
|
@ -9,11 +9,10 @@ using System.Reflection;
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||
using Func2I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
using Func2I = Func<Operand, Operand, Operand>;
|
||||
|
||||
static partial class InstEmit
|
||||
{
|
||||
#region "Masks"
|
||||
@ -1634,7 +1633,7 @@ namespace ARMeilleure.Instructions
|
||||
int eSize = 8 << size;
|
||||
|
||||
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);
|
||||
|
||||
@ -1657,7 +1656,7 @@ namespace ARMeilleure.Instructions
|
||||
int eSize = 8 << size;
|
||||
|
||||
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();
|
||||
|
||||
@ -1732,7 +1731,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Debug.Assert(op.Type == OperandType.I64);
|
||||
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 lblEnd = Label();
|
||||
@ -1769,7 +1768,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Debug.Assert(op.Type == OperandType.I64);
|
||||
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 lbl2 = Label();
|
||||
@ -1813,6 +1812,7 @@ namespace ARMeilleure.Instructions
|
||||
? EmitSignedSrcSatQ(context, shl, size, signedDst: true)
|
||||
: EmitUnsignedSrcSatQ(context, shl, size, signedDst: false));
|
||||
}
|
||||
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
@ -1850,6 +1850,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
context.Copy(res, sar);
|
||||
}
|
||||
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
@ -1906,6 +1907,7 @@ namespace ARMeilleure.Instructions
|
||||
Operand right = context.BitwiseOr(shr, context.ShiftRightUI(oneShl63UL, context.Subtract(shift, one)));
|
||||
context.Copy(res, context.ConditionalSelect(isEqual, oneUL, right));
|
||||
}
|
||||
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
|
@ -69,13 +69,13 @@ namespace ARMeilleure.Instructions
|
||||
[UnmanagedCallersOnly]
|
||||
public static ulong GetCtrEl0()
|
||||
{
|
||||
return GetContext().CtrEl0;
|
||||
return ExecutionContext.CtrEl0;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static ulong GetDczidEl0()
|
||||
{
|
||||
return GetContext().DczidEl0;
|
||||
return ExecutionContext.DczidEl0;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
|
@ -24,7 +24,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
uint src = (uint)idx + 256u;
|
||||
|
||||
Debug.Assert(256u <= src && src < 512u);
|
||||
Debug.Assert(src is >= 256u and < 512u);
|
||||
|
||||
src = (src << 1) + 1u;
|
||||
|
||||
@ -32,7 +32,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
uint dst = (aux + 1u) >> 1;
|
||||
|
||||
Debug.Assert(256u <= dst && dst < 512u);
|
||||
Debug.Assert(dst is >= 256u and < 512u);
|
||||
|
||||
tbl[idx] = (byte)(dst - 256u);
|
||||
}
|
||||
@ -48,7 +48,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
uint src = (uint)idx + 128u;
|
||||
|
||||
Debug.Assert(128u <= src && src < 512u);
|
||||
Debug.Assert(src is >= 128u and < 512u);
|
||||
|
||||
if (src < 256u)
|
||||
{
|
||||
@ -69,7 +69,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
uint dst = (aux + 1u) >> 1;
|
||||
|
||||
Debug.Assert(256u <= dst && dst < 512u);
|
||||
Debug.Assert(dst is >= 256u and < 512u);
|
||||
|
||||
tbl[idx] = (byte)(dst - 256u);
|
||||
}
|
||||
@ -322,7 +322,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
float result;
|
||||
|
||||
if (type == FPType.SNaN || type == FPType.QNaN)
|
||||
if (type is FPType.SNaN or FPType.QNaN)
|
||||
{
|
||||
if ((context.Fpcr & FPCR.Dn) != 0)
|
||||
{
|
||||
@ -498,7 +498,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
double result;
|
||||
|
||||
if (type == FPType.SNaN || type == FPType.QNaN)
|
||||
if (type is FPType.SNaN or FPType.QNaN)
|
||||
{
|
||||
if ((context.Fpcr & FPCR.Dn) != 0)
|
||||
{
|
||||
@ -676,7 +676,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
ushort resultBits;
|
||||
|
||||
if (type == FPType.SNaN || type == FPType.QNaN)
|
||||
if (type is FPType.SNaN or FPType.QNaN)
|
||||
{
|
||||
if (altHp)
|
||||
{
|
||||
@ -1086,7 +1086,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
return FPMaxFpscrImpl(value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
|
||||
private static float FPMaxFpscrImpl(float value1, float value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
@ -1522,7 +1522,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
float result;
|
||||
|
||||
if (type == FPType.SNaN || type == FPType.QNaN)
|
||||
if (type is FPType.SNaN or FPType.QNaN)
|
||||
{
|
||||
result = FPProcessNaN(type, op, context, fpcr);
|
||||
}
|
||||
@ -1689,7 +1689,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
float result;
|
||||
|
||||
if (type == FPType.SNaN || type == FPType.QNaN)
|
||||
if (type is FPType.SNaN or FPType.QNaN)
|
||||
{
|
||||
result = FPProcessNaN(type, op, context, fpcr);
|
||||
}
|
||||
@ -1726,7 +1726,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
float result;
|
||||
|
||||
if (type == FPType.SNaN || type == FPType.QNaN)
|
||||
if (type is FPType.SNaN or FPType.QNaN)
|
||||
{
|
||||
result = FPProcessNaN(type, op, context, fpcr);
|
||||
}
|
||||
@ -1920,7 +1920,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
float result;
|
||||
|
||||
if (type == FPType.SNaN || type == FPType.QNaN)
|
||||
if (type is FPType.SNaN or FPType.QNaN)
|
||||
{
|
||||
result = FPProcessNaN(type, op, context, fpcr);
|
||||
}
|
||||
@ -2211,7 +2211,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
ushort resultBits;
|
||||
|
||||
if (type == FPType.SNaN || type == FPType.QNaN)
|
||||
if (type is FPType.SNaN or FPType.QNaN)
|
||||
{
|
||||
if (altHp)
|
||||
{
|
||||
@ -3057,7 +3057,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
double result;
|
||||
|
||||
if (type == FPType.SNaN || type == FPType.QNaN)
|
||||
if (type is FPType.SNaN or FPType.QNaN)
|
||||
{
|
||||
result = FPProcessNaN(type, op, context, fpcr);
|
||||
}
|
||||
@ -3224,7 +3224,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
double result;
|
||||
|
||||
if (type == FPType.SNaN || type == FPType.QNaN)
|
||||
if (type is FPType.SNaN or FPType.QNaN)
|
||||
{
|
||||
result = FPProcessNaN(type, op, context, fpcr);
|
||||
}
|
||||
@ -3261,7 +3261,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
double result;
|
||||
|
||||
if (type == FPType.SNaN || type == FPType.QNaN)
|
||||
if (type is FPType.SNaN or FPType.QNaN)
|
||||
{
|
||||
result = FPProcessNaN(type, op, context, fpcr);
|
||||
}
|
||||
@ -3455,7 +3455,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
double result;
|
||||
|
||||
if (type == FPType.SNaN || type == FPType.QNaN)
|
||||
if (type is FPType.SNaN or FPType.QNaN)
|
||||
{
|
||||
result = FPProcessNaN(type, op, context, fpcr);
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace ARMeilleure.IntermediateRepresentation
|
||||
{
|
||||
[Flags]
|
||||
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
|
||||
enum Intrinsic : ushort
|
||||
{
|
||||
// X86 (SSE and AVX)
|
||||
|
@ -7,10 +7,9 @@ namespace ARMeilleure.IntermediateRepresentation
|
||||
{
|
||||
private struct Data
|
||||
{
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public byte Kind;
|
||||
public byte Type;
|
||||
#pragma warning restore CS0649
|
||||
|
||||
public byte Scale;
|
||||
public Operand BaseAddress;
|
||||
public Operand Index;
|
||||
|
@ -446,7 +446,7 @@ namespace ARMeilleure.IntermediateRepresentation
|
||||
Data* data = null;
|
||||
|
||||
// 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);
|
||||
|
||||
|
@ -16,8 +16,8 @@ namespace ARMeilleure.IntermediateRepresentation
|
||||
{
|
||||
public static bool IsInteger(this OperandType type)
|
||||
{
|
||||
return type == OperandType.I32 ||
|
||||
type == OperandType.I64;
|
||||
return type is OperandType.I32 or
|
||||
OperandType.I64;
|
||||
}
|
||||
|
||||
public static RegisterType ToRegisterType(this OperandType type)
|
||||
|
@ -47,12 +47,12 @@ namespace ARMeilleure.Memory
|
||||
{
|
||||
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)
|
||||
{
|
||||
return type == MemoryManagerType.HostTracked || type == MemoryManagerType.HostTrackedUnsafe;
|
||||
return type is MemoryManagerType.HostTracked or MemoryManagerType.HostTrackedUnsafe;
|
||||
}
|
||||
|
||||
public static bool IsHostMappedOrTracked(this MemoryManagerType type)
|
||||
|
@ -1,8 +1,8 @@
|
||||
using Arm64HardwareCapabilities = ARMeilleure.CodeGen.Arm64.HardwareCapabilities;
|
||||
using X86HardwareCapabilities = ARMeilleure.CodeGen.X86.HardwareCapabilities;
|
||||
|
||||
namespace ARMeilleure
|
||||
{
|
||||
using Arm64HardwareCapabilities = ARMeilleure.CodeGen.Arm64.HardwareCapabilities;
|
||||
using X86HardwareCapabilities = ARMeilleure.CodeGen.X86.HardwareCapabilities;
|
||||
|
||||
public static class Optimizations
|
||||
{
|
||||
// low-core count PPTC
|
||||
|
@ -16,10 +16,8 @@ namespace ARMeilleure.State
|
||||
|
||||
public ulong Pc => _nativeContext.GetPc();
|
||||
|
||||
#pragma warning disable CA1822 // Mark member as static
|
||||
public uint CtrEl0 => 0x8444c004;
|
||||
public uint DczidEl0 => 0x00000004;
|
||||
#pragma warning restore CA1822
|
||||
public static uint CtrEl0 => 0x8444c004;
|
||||
public static uint DczidEl0 => 0x00000004;
|
||||
|
||||
public ulong CntfrqEl0 => _counter.Frequency;
|
||||
public ulong CntpctEl0 => _counter.Counter;
|
||||
|
@ -111,6 +111,7 @@ namespace ARMeilleure.State
|
||||
{
|
||||
value |= GetStorage().Flags[flag] != 0 ? 1u << flag : 0u;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -155,6 +156,7 @@ namespace ARMeilleure.State
|
||||
value |= GetStorage().FpFlags[flag] != 0 ? bit : 0u;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -218,18 +218,28 @@ namespace ARMeilleure.Translation
|
||||
{
|
||||
switch (condition)
|
||||
{
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
case Condition.Eq: return ICompareEqual (n, m);
|
||||
case Condition.Ne: return ICompareNotEqual (n, m);
|
||||
case Condition.GeUn: return ICompareGreaterOrEqualUI(n, m);
|
||||
case Condition.LtUn: return ICompareLessUI (n, m);
|
||||
case Condition.GtUn: return ICompareGreaterUI (n, m);
|
||||
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);
|
||||
#pragma warning restore IDE0055
|
||||
|
||||
case Condition.Eq:
|
||||
return ICompareEqual(n, m);
|
||||
case Condition.Ne:
|
||||
return ICompareNotEqual(n, m);
|
||||
case Condition.GeUn:
|
||||
return ICompareGreaterOrEqualUI(n, m);
|
||||
case Condition.LtUn:
|
||||
return ICompareLessUI(n, m);
|
||||
case Condition.GtUn:
|
||||
return ICompareGreaterUI(n, m);
|
||||
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)
|
||||
@ -254,14 +264,20 @@ namespace ARMeilleure.Translation
|
||||
|
||||
switch (condition)
|
||||
{
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
case Condition.Eq: return ICompareEqual (n, m);
|
||||
case Condition.Ne: return ICompareNotEqual (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);
|
||||
#pragma warning restore IDE0055
|
||||
|
||||
case Condition.Eq:
|
||||
return ICompareEqual(n, m);
|
||||
case Condition.Ne:
|
||||
return ICompareNotEqual(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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ namespace ARMeilleure.Translation.Cache
|
||||
|
||||
private static JitCacheInvalidation _jitCacheInvalidator;
|
||||
|
||||
private static List<CacheMemoryAllocator> _cacheAllocators = [];
|
||||
private static readonly List<CacheMemoryAllocator> _cacheAllocators = [];
|
||||
|
||||
private static readonly List<CacheEntry> _cacheEntries = [];
|
||||
|
||||
@ -205,7 +205,6 @@ namespace ARMeilleure.Translation.Cache
|
||||
return allocOffsetNew;
|
||||
}
|
||||
|
||||
|
||||
private static int AlignCodeSize(int codeSize)
|
||||
{
|
||||
return checked(codeSize + (CodeAlignment - 1)) & ~(CodeAlignment - 1);
|
||||
|
@ -32,7 +32,7 @@ namespace ARMeilleure.Translation
|
||||
|
||||
return _delegates.Values[index].FuncPtr; // O(1).
|
||||
}
|
||||
|
||||
|
||||
public static int GetDelegateIndex(MethodInfo info)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(info);
|
||||
@ -48,7 +48,7 @@ namespace ARMeilleure.Translation
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
private static void SetDelegateInfo(MethodInfo method)
|
||||
{
|
||||
string key = GetKey(method);
|
||||
|
@ -77,7 +77,7 @@ namespace ARMeilleure.Translation
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
for (int pBlkIndex = 0; pBlkIndex < block.Predecessors.Count; pBlkIndex++)
|
||||
{
|
||||
BasicBlock current = block.Predecessors[pBlkIndex];
|
||||
|
@ -124,7 +124,7 @@ namespace ARMeilleure.Translation
|
||||
/// </summary>
|
||||
/// <param name="node">The node to search for values within</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)
|
||||
{
|
||||
@ -165,6 +165,7 @@ namespace ARMeilleure.Translation
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -175,7 +176,7 @@ namespace ARMeilleure.Translation
|
||||
/// <param name="end">End of the range</param>
|
||||
/// <param name="overlaps">Overlaps array to place results in</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)
|
||||
{
|
||||
@ -311,6 +312,7 @@ namespace ARMeilleure.Translation
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
IntervalTreeNode<TK, TV> newNode = new(start, end, value, parent);
|
||||
if (newNode.Parent == null)
|
||||
{
|
||||
@ -422,12 +424,14 @@ namespace ARMeilleure.Translation
|
||||
{
|
||||
return Maximum(node.Left);
|
||||
}
|
||||
|
||||
IntervalTreeNode<TK, TV> parent = node.Parent;
|
||||
while (parent != null && node == parent.Left)
|
||||
{
|
||||
node = parent;
|
||||
parent = parent.Parent;
|
||||
}
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
@ -452,6 +456,7 @@ namespace ARMeilleure.Translation
|
||||
RotateLeft(ParentOf(ptr));
|
||||
sibling = RightOf(ParentOf(ptr));
|
||||
}
|
||||
|
||||
if (ColorOf(LeftOf(sibling)) == Black && ColorOf(RightOf(sibling)) == Black)
|
||||
{
|
||||
SetColor(sibling, Red);
|
||||
@ -466,6 +471,7 @@ namespace ARMeilleure.Translation
|
||||
RotateRight(sibling);
|
||||
sibling = RightOf(ParentOf(ptr));
|
||||
}
|
||||
|
||||
SetColor(sibling, ColorOf(ParentOf(ptr)));
|
||||
SetColor(ParentOf(ptr), Black);
|
||||
SetColor(RightOf(sibling), Black);
|
||||
@ -484,6 +490,7 @@ namespace ARMeilleure.Translation
|
||||
RotateRight(ParentOf(ptr));
|
||||
sibling = LeftOf(ParentOf(ptr));
|
||||
}
|
||||
|
||||
if (ColorOf(RightOf(sibling)) == Black && ColorOf(LeftOf(sibling)) == Black)
|
||||
{
|
||||
SetColor(sibling, Red);
|
||||
@ -498,6 +505,7 @@ namespace ARMeilleure.Translation
|
||||
RotateLeft(sibling);
|
||||
sibling = LeftOf(ParentOf(ptr));
|
||||
}
|
||||
|
||||
SetColor(sibling, ColorOf(ParentOf(ptr)));
|
||||
SetColor(ParentOf(ptr), Black);
|
||||
SetColor(LeftOf(sibling), Black);
|
||||
@ -506,6 +514,7 @@ namespace ARMeilleure.Translation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetColor(ptr, Black);
|
||||
}
|
||||
|
||||
@ -532,6 +541,7 @@ namespace ARMeilleure.Translation
|
||||
balanceNode = ParentOf(balanceNode);
|
||||
RotateLeft(balanceNode);
|
||||
}
|
||||
|
||||
SetColor(ParentOf(balanceNode), Black);
|
||||
SetColor(ParentOf(ParentOf(balanceNode)), Red);
|
||||
RotateRight(ParentOf(ParentOf(balanceNode)));
|
||||
@ -555,12 +565,14 @@ namespace ARMeilleure.Translation
|
||||
balanceNode = ParentOf(balanceNode);
|
||||
RotateRight(balanceNode);
|
||||
}
|
||||
|
||||
SetColor(ParentOf(balanceNode), Black);
|
||||
SetColor(ParentOf(ParentOf(balanceNode)), Red);
|
||||
RotateLeft(ParentOf(ParentOf(balanceNode)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetColor(_root, Black);
|
||||
}
|
||||
|
||||
@ -574,6 +586,7 @@ namespace ARMeilleure.Translation
|
||||
{
|
||||
node.Right.Parent = node;
|
||||
}
|
||||
|
||||
IntervalTreeNode<TK, TV> nodeParent = ParentOf(node);
|
||||
right.Parent = nodeParent;
|
||||
if (nodeParent == null)
|
||||
@ -588,6 +601,7 @@ namespace ARMeilleure.Translation
|
||||
{
|
||||
nodeParent.Right = right;
|
||||
}
|
||||
|
||||
right.Left = node;
|
||||
node.Parent = right;
|
||||
|
||||
@ -605,6 +619,7 @@ namespace ARMeilleure.Translation
|
||||
{
|
||||
node.Left.Parent = node;
|
||||
}
|
||||
|
||||
IntervalTreeNode<TK, TV> nodeParent = ParentOf(node);
|
||||
left.Parent = nodeParent;
|
||||
if (nodeParent == null)
|
||||
@ -619,6 +634,7 @@ namespace ARMeilleure.Translation
|
||||
{
|
||||
nodeParent.Left = left;
|
||||
}
|
||||
|
||||
left.Right = node;
|
||||
node.Parent = left;
|
||||
|
||||
|
@ -22,12 +22,11 @@ using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using static ARMeilleure.Translation.PTC.PtcFormatter;
|
||||
using Arm64HardwareCapabilities = ARMeilleure.CodeGen.Arm64.HardwareCapabilities;
|
||||
using X86HardwareCapabilities = ARMeilleure.CodeGen.X86.HardwareCapabilities;
|
||||
|
||||
namespace ARMeilleure.Translation.PTC
|
||||
{
|
||||
using Arm64HardwareCapabilities = CodeGen.Arm64.HardwareCapabilities;
|
||||
using X86HardwareCapabilities = CodeGen.X86.HardwareCapabilities;
|
||||
|
||||
class Ptc : IPtcLoadState
|
||||
{
|
||||
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
||||
@ -193,7 +192,7 @@ namespace ARMeilleure.Translation.PTC
|
||||
_infosStream.Seek(0L, SeekOrigin.Begin);
|
||||
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);
|
||||
foreach (ulong address in blacklist)
|
||||
@ -835,8 +834,6 @@ namespace ARMeilleure.Translation.PTC
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int degreeOfParallelism = Environment.ProcessorCount;
|
||||
|
||||
if (Optimizations.LowPower)
|
||||
@ -896,13 +893,12 @@ namespace ARMeilleure.Translation.PTC
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
List<Thread> threads = Enumerable.Range(0, degreeOfParallelism)
|
||||
.Select(idx =>
|
||||
.Select(idx =>
|
||||
new Thread(TranslateFuncs)
|
||||
{
|
||||
IsBackground = true,
|
||||
Name = "Ptc.TranslateThread." + idx
|
||||
IsBackground = true,
|
||||
Name = "Ptc.TranslateThread." + idx
|
||||
}
|
||||
).ToList();
|
||||
|
||||
@ -912,6 +908,7 @@ namespace ARMeilleure.Translation.PTC
|
||||
{
|
||||
thread.Start();
|
||||
}
|
||||
|
||||
foreach (Thread thread in threads)
|
||||
{
|
||||
thread.Join();
|
||||
@ -925,8 +922,8 @@ namespace ARMeilleure.Translation.PTC
|
||||
sw.Stop();
|
||||
|
||||
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 " +
|
||||
$"| {"function".ToQuantity(_translateTotalCount - _translateCount)} blacklisted " +
|
||||
$"| Thread count: {degreeOfParallelism}");
|
||||
@ -1164,8 +1161,8 @@ namespace ARMeilleure.Translation.PTC
|
||||
|
||||
public void Close()
|
||||
{
|
||||
if (State == PtcState.Enabled ||
|
||||
State == PtcState.Continuing)
|
||||
if (State is PtcState.Enabled or
|
||||
PtcState.Continuing)
|
||||
{
|
||||
State = PtcState.Closing;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using ARMeilleure.State;
|
||||
using Humanizer;
|
||||
using Microsoft.IO;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Logging;
|
||||
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 static readonly uint[] _migrateInternalVersions =
|
||||
private static readonly uint[] _migrateInternalVersions =
|
||||
[
|
||||
1866,
|
||||
5518,
|
||||
@ -75,7 +76,7 @@ namespace ARMeilleure.Translation.PTC
|
||||
Enabled = false;
|
||||
}
|
||||
|
||||
private void TimerElapsed(object _, ElapsedEventArgs __)
|
||||
private void TimerElapsed(object _, ElapsedEventArgs __)
|
||||
=> new Thread(PreSave) { Name = "Ptc.DiskWriter" }.Start();
|
||||
|
||||
public void AddEntry(ulong address, ExecutionMode mode, bool highCq, bool blacklist = false)
|
||||
@ -151,7 +152,7 @@ namespace ARMeilleure.Translation.PTC
|
||||
if (!funcProfile.Blacklist)
|
||||
continue;
|
||||
|
||||
if (!funcs.Contains(ptr))
|
||||
if (!funcs.Contains(ptr))
|
||||
funcs.Add(ptr);
|
||||
}
|
||||
|
||||
@ -219,7 +220,7 @@ namespace ARMeilleure.Translation.PTC
|
||||
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);
|
||||
|
||||
try
|
||||
@ -293,10 +294,10 @@ namespace ARMeilleure.Translation.PTC
|
||||
{
|
||||
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)
|
||||
@ -467,8 +468,8 @@ namespace ARMeilleure.Translation.PTC
|
||||
|
||||
public void Start()
|
||||
{
|
||||
if (_ptc.State == PtcState.Enabled ||
|
||||
_ptc.State == PtcState.Continuing)
|
||||
if (_ptc.State is PtcState.Enabled or
|
||||
PtcState.Continuing)
|
||||
{
|
||||
Enabled = true;
|
||||
|
||||
|
@ -297,12 +297,20 @@ namespace ARMeilleure.Translation
|
||||
|
||||
switch (register.Type)
|
||||
{
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
case RegisterType.Flag: intMask = (1L << RegsCount) << register.Index; break;
|
||||
case RegisterType.Integer: intMask = 1L << register.Index; break;
|
||||
case RegisterType.FpFlag: vecMask = (1L << RegsCount) << register.Index; break;
|
||||
case RegisterType.Vector: vecMask = 1L << register.Index; break;
|
||||
#pragma warning restore IDE0055
|
||||
|
||||
case RegisterType.Flag:
|
||||
intMask = (1L << RegsCount) << register.Index;
|
||||
break;
|
||||
case RegisterType.Integer:
|
||||
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);
|
||||
|
@ -178,7 +178,7 @@ namespace Ryujinx.Audio.Backends.OpenAL
|
||||
|
||||
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)
|
||||
|
@ -12,7 +12,7 @@ using static SDL2.SDL;
|
||||
|
||||
namespace Ryujinx.Audio.Backends.SDL2
|
||||
{
|
||||
public class SDL2HardwareDeviceDriver : IHardwareDeviceDriver
|
||||
public partial class SDL2HardwareDeviceDriver : IHardwareDeviceDriver
|
||||
{
|
||||
private readonly ManualResetEvent _updateRequiredEvent;
|
||||
private readonly ManualResetEvent _pauseEvent;
|
||||
@ -22,12 +22,36 @@ namespace Ryujinx.Audio.Backends.SDL2
|
||||
|
||||
public float Volume { get; set; }
|
||||
|
||||
// TODO: Add this to SDL2-CS
|
||||
// NOTE: We use a DllImport here because of marshaling issue for spec.
|
||||
#pragma warning disable SYSLIB1054
|
||||
[DllImport("SDL2")]
|
||||
private static extern int SDL_GetDefaultAudioInfo(nint name, out SDL_AudioSpec spec, int isCapture);
|
||||
#pragma warning restore SYSLIB1054
|
||||
// A safe method to get default audio information.
|
||||
private static int GetDefaultAudioInfo(nint name, out SDL_AudioSpec spec, int isCapture)
|
||||
{
|
||||
int result;
|
||||
spec = new SDL_AudioSpec();
|
||||
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()
|
||||
{
|
||||
@ -37,7 +61,7 @@ namespace Ryujinx.Audio.Backends.SDL2
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -23,7 +23,7 @@ namespace Ryujinx.Audio.Backends.SoundIo.Native
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void JackCallbackDelegate(nint msg);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct SoundIoStruct
|
||||
{
|
||||
public nint UserData;
|
||||
|
@ -162,7 +162,7 @@ namespace Ryujinx.Audio.Backends.CompatLayer
|
||||
|
||||
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)
|
||||
@ -184,7 +184,7 @@ namespace Ryujinx.Audio.Backends.CompatLayer
|
||||
|
||||
public bool SupportsDirection(Direction direction)
|
||||
{
|
||||
return direction == Direction.Input || direction == Direction.Output;
|
||||
return direction is Direction.Input or Direction.Output;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -73,12 +73,12 @@ namespace Ryujinx.Audio.Backends.Dummy
|
||||
|
||||
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)
|
||||
{
|
||||
return channelCount == 1 || channelCount == 2 || channelCount == 6;
|
||||
return channelCount is 1 or 2 or 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ namespace Ryujinx.Audio.Common
|
||||
/// <returns>The state of the session</returns>
|
||||
public AudioDeviceState GetState()
|
||||
{
|
||||
Debug.Assert(_state == AudioDeviceState.Started || _state == AudioDeviceState.Stopped);
|
||||
Debug.Assert(_state is AudioDeviceState.Started or AudioDeviceState.Stopped);
|
||||
|
||||
return _state;
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ namespace Ryujinx.Audio.Input
|
||||
/// </summary>
|
||||
/// <param name="filtered">If true, filter disconnected devices</param>
|
||||
/// <returns>The list of all audio inputs name</returns>
|
||||
public string[] ListAudioIns(bool filtered)
|
||||
public static string[] ListAudioIns(bool filtered)
|
||||
{
|
||||
if (filtered)
|
||||
{
|
||||
|
@ -91,12 +91,12 @@ namespace Ryujinx.Audio.Input
|
||||
return ResultCode.DeviceNotFound;
|
||||
}
|
||||
|
||||
if (configuration.SampleRate != 0 && configuration.SampleRate != Constants.TargetSampleRate)
|
||||
if (configuration.SampleRate is not 0 and not Constants.TargetSampleRate)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ namespace Ryujinx.Audio.Integration
|
||||
{
|
||||
uint channelCount = GetChannelCount();
|
||||
|
||||
Debug.Assert(channelCount > 0 && channelCount <= Constants.ChannelCountMax);
|
||||
Debug.Assert(channelCount is > 0 and <= Constants.ChannelCountMax);
|
||||
|
||||
return channelCount != Constants.ChannelCountMax;
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ namespace Ryujinx.Audio.Output
|
||||
/// Get the list of all audio outputs name.
|
||||
/// </summary>
|
||||
/// <returns>The list of all audio outputs name</returns>
|
||||
public string[] ListAudioOuts()
|
||||
public static string[] ListAudioOuts()
|
||||
{
|
||||
return [Constants.DefaultDeviceOutputName];
|
||||
}
|
||||
|
@ -91,12 +91,12 @@ namespace Ryujinx.Audio.Output
|
||||
return ResultCode.DeviceNotFound;
|
||||
}
|
||||
|
||||
if (configuration.SampleRate != 0 && configuration.SampleRate != Constants.TargetSampleRate)
|
||||
if (configuration.SampleRate is not 0 and not Constants.TargetSampleRate)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -20,9 +20,7 @@ namespace Ryujinx.Audio.Renderer.Common
|
||||
public uint Unknown24;
|
||||
public uint RenderInfoSize;
|
||||
|
||||
#pragma warning disable IDE0051, CS0169 // Remove unused field
|
||||
private Array4<int> _reserved;
|
||||
#pragma warning restore IDE0051, CS0169
|
||||
|
||||
public uint TotalSize;
|
||||
|
||||
|
@ -58,7 +58,7 @@ namespace Ryujinx.Audio.Renderer.Device
|
||||
/// <param name="volume">The new master volume.</param>
|
||||
public void UpdateMasterVolume(float volume)
|
||||
{
|
||||
Debug.Assert(volume >= 0.0f && volume <= 1.0f);
|
||||
Debug.Assert(volume is >= 0.0f and <= 1.0f);
|
||||
|
||||
MasterVolume = volume;
|
||||
}
|
||||
|
@ -17,9 +17,7 @@ namespace Ryujinx.Audio.Renderer.Device
|
||||
/// The default <see cref="VirtualDevice"/>.
|
||||
/// </summary>
|
||||
/// <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 VirtualDevice DefaultDevice => VirtualDevice.Devices[0];
|
||||
#pragma warning restore CA1822
|
||||
public static VirtualDevice DefaultDevice => VirtualDevice.Devices[0];
|
||||
|
||||
/// <summary>
|
||||
/// The current active <see cref="VirtualDevice"/>.
|
||||
|
@ -12,9 +12,8 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
||||
private const int SamplesPerFrame = 14;
|
||||
private const int NibblesPerFrame = SamplesPerFrame + 2;
|
||||
private const int BytesPerFrame = 8;
|
||||
#pragma warning disable IDE0051 // Remove unused private member
|
||||
|
||||
private const int BitsPerFrame = BytesPerFrame * 8;
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static uint GetAdpcmDataSize(int sampleCount)
|
||||
|
@ -129,7 +129,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
||||
delayFeedbackCrossGain, 0.0f, delayFeedbackBaseGain, delayFeedbackCrossGain,
|
||||
0.0f, delayFeedbackCrossGain, delayFeedbackCrossGain, delayFeedbackBaseGain);
|
||||
|
||||
|
||||
for (int i = 0; i < sampleCount; i++)
|
||||
{
|
||||
Vector4 channelInput = new()
|
||||
|
@ -40,7 +40,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
|
||||
|
||||
DelayFeedbackBaseGain = (1.0f - channelSpread) * FeedbackGain;
|
||||
|
||||
if (parameter.ChannelCount == 4 || parameter.ChannelCount == 6)
|
||||
if (parameter.ChannelCount is 4 or 6)
|
||||
{
|
||||
DelayFeedbackCrossGain = channelSpread * 0.5f * FeedbackGain;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
return (MathF.Sin(MathF.PI * x) / (MathF.PI * x));
|
||||
}
|
||||
|
||||
@ -141,6 +142,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
||||
|
||||
state.Phase = (state.Phase + 1) % 6;
|
||||
}
|
||||
|
||||
break;
|
||||
case 3.0f:
|
||||
for (int i = 0; i < outputSampleCount; i++)
|
||||
@ -161,6 +163,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
||||
|
||||
state.Phase = (state.Phase + 1) % 3;
|
||||
}
|
||||
|
||||
break;
|
||||
case 1.5f:
|
||||
// Upsample by 3 then decimate by 2.
|
||||
@ -183,6 +186,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
||||
|
||||
state.Phase = (state.Phase + 1) % 3;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(state), state.Scale, null);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user