mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-02-24 01:31:07 +00:00
Compare commits
118 Commits
1.3.3
...
feature/co
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4abc3a960 | ||
|
|
8ccbf33327 | ||
|
|
fa55608587 | ||
|
|
4c64300576 | ||
|
|
0a3db19b28 | ||
|
|
453b246faa | ||
|
|
45193dcc8d | ||
|
|
9ebf444644 | ||
|
|
f585b36263 | ||
|
|
a96f20dca5 | ||
|
|
1e1bcb4a5b | ||
|
|
ca76bacd22 | ||
|
|
66f339d265 | ||
|
|
6cdbdfd329 | ||
|
|
9f817d60d5 | ||
|
|
5cffc95be6 | ||
|
|
2c0977f6b3 | ||
|
|
3a593b6084 | ||
|
|
c3155fcadb | ||
|
|
fd7554425a | ||
|
|
52700f71dc | ||
|
|
b018a44ff0 | ||
|
|
d522bfef62 | ||
|
|
39f55b2af3 | ||
|
|
6126e3dc1e | ||
|
|
e1c829f91d | ||
|
|
6c7dc7646b | ||
|
|
862a686c5e | ||
|
|
e8751e1c40 | ||
|
|
09748b140a | ||
|
|
456db46065 | ||
|
|
7b39ff36c0 | ||
|
|
10476771d3 | ||
|
|
c5082ac85a | ||
|
|
5e86ad83cc | ||
|
|
1baaa1c365 | ||
|
|
e8225ce7aa | ||
|
|
6b814fb973 | ||
|
|
49c70efdd5 | ||
|
|
4677b749b1 | ||
|
|
ed32cd6999 | ||
|
|
d7e2d4534a | ||
|
|
3c3e14c819 | ||
|
|
dd9ba05e36 | ||
|
|
a49822470c | ||
|
|
58be57bf73 | ||
|
|
17d5d6e65a | ||
|
|
1dac06e394 | ||
|
|
ed89ffd3f8 | ||
|
|
844d7a9cfe | ||
|
|
cf6acba416 | ||
|
|
5a9d5ee664 | ||
|
|
bbad867319 | ||
|
|
a8ace3d23c | ||
|
|
13b69aedfe | ||
|
|
234f7ca298 | ||
|
|
2c9b193018 | ||
|
|
92b61f9d73 | ||
|
|
ab7aeee67b | ||
|
|
b991fe05d9 | ||
|
|
3140ec5f05 | ||
|
|
40f709ff55 | ||
|
|
53aae9b584 | ||
|
|
ff9a75f895 | ||
|
|
3394736b07 | ||
|
|
b06846aa5e | ||
|
|
c94ffaa00a | ||
|
|
718652599d | ||
|
|
c8959afa3d | ||
|
|
7175da8621 | ||
|
|
fd07453887 | ||
|
|
c6bc77e4bf | ||
|
|
49cbe4b328 | ||
|
|
6fd67cdcb7 | ||
|
|
5ced2bf764 | ||
|
|
67e97d1a1a | ||
|
|
09d8a411c8 | ||
|
|
93516df7e6 | ||
|
|
0c165c3f62 | ||
|
|
91da244c02 | ||
|
|
904d4a7eb0 | ||
|
|
1248a054de | ||
|
|
1bb2af84ce | ||
|
|
886981004d | ||
|
|
e551dda17e | ||
|
|
ed67535227 | ||
|
|
7d65611b96 | ||
|
|
71eb844dd8 | ||
|
|
a0e5edf8ba | ||
|
|
6541ad0726 | ||
|
|
1c084373c9 | ||
|
|
5b3b907fd2 | ||
|
|
f46577af58 | ||
|
|
0e218754f5 | ||
|
|
0c6d4a07b9 | ||
|
|
8714b010f6 | ||
|
|
d1d4a735a6 | ||
|
|
247e2e03d6 | ||
|
|
6058af5119 | ||
|
|
e11eff0f41 | ||
|
|
2a2ab523cb | ||
|
|
8e941e4a8f | ||
|
|
9aacf9b37b | ||
|
|
2b159dbca8 | ||
|
|
c33a97f01c | ||
|
|
fdbdb05cb5 | ||
|
|
7268acbfb4 | ||
|
|
d4107ac05f | ||
|
|
1d409f7127 | ||
|
|
2434c55266 | ||
|
|
99126603ba | ||
|
|
a62716002e | ||
|
|
47559cd311 | ||
|
|
51584a083b | ||
|
|
ceec9617ef | ||
|
|
1865be47cf | ||
|
|
ef9810582a | ||
|
|
13878acdb2 |
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -2,3 +2,4 @@
|
|||||||
# Set default behavior to automatically normalize line endings.
|
# Set default behavior to automatically normalize line endings.
|
||||||
###############################################################################
|
###############################################################################
|
||||||
* text=auto eol=lf
|
* text=auto eol=lf
|
||||||
|
*.json text eol=lf
|
||||||
|
|||||||
99
.github/workflows/canary.yml
vendored
99
.github/workflows/canary.yml
vendored
@@ -1,4 +1,4 @@
|
|||||||
name: Canary release job
|
name: Canary CI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@@ -19,7 +19,6 @@ concurrency: release
|
|||||||
env:
|
env:
|
||||||
POWERSHELL_TELEMETRY_OPTOUT: 1
|
POWERSHELL_TELEMETRY_OPTOUT: 1
|
||||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||||
RYUJINX_BASE_VERSION: "1.3"
|
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "canary"
|
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "canary"
|
||||||
RELEASE: 1
|
RELEASE: 1
|
||||||
|
|
||||||
@@ -30,8 +29,8 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
platform:
|
platform:
|
||||||
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
|
- { name: win-x64, os: ubuntu-latest, zip_os_name: win_x64 }
|
||||||
#- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 }
|
#- { name: win-arm64, os: ubuntu-latest, zip_os_name: win_arm64 }
|
||||||
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
|
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
|
||||||
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
|
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
|
||||||
steps:
|
steps:
|
||||||
@@ -44,11 +43,25 @@ jobs:
|
|||||||
- name: Overwrite csc problem matcher
|
- name: Overwrite csc problem matcher
|
||||||
run: echo "::add-matcher::.github/csc.json"
|
run: echo "::add-matcher::.github/csc.json"
|
||||||
|
|
||||||
|
- name: Install 7zip
|
||||||
|
run: |
|
||||||
|
sudo apt install -y 7zip
|
||||||
|
|
||||||
|
- name: Install gli
|
||||||
|
run: |
|
||||||
|
mkdir -p $HOME/.bin
|
||||||
|
gh release download -R GreemDev/GLI -O gli -p 'gli-linux-x64'
|
||||||
|
chmod +x gli
|
||||||
|
mv gli $HOME/.bin/
|
||||||
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Get version info
|
- name: Get version info
|
||||||
id: version_info
|
id: version_info
|
||||||
run: |
|
run: |
|
||||||
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
echo "build_version=$(gli get-next-version -c Canary -R)" >> $GITHUB_OUTPUT
|
||||||
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
|
echo "prev_build_version=$(gli get-current-version -c Canary -R)" >> $GITHUB_OUTPUT
|
||||||
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
@@ -69,33 +82,20 @@ jobs:
|
|||||||
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
|
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
|
- name: Packing Windows builds
|
||||||
if: matrix.platform.os == 'windows-latest'
|
if: contains(matrix.platform.name, 'win')
|
||||||
run: |
|
run: |
|
||||||
pushd publish
|
pushd publish
|
||||||
rm libarmeilleure-jitsupport.dylib
|
rm libarmeilleure-jitsupport.dylib
|
||||||
7z a ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
|
7z a ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
|
||||||
popd
|
popd
|
||||||
|
|
||||||
gh release download -R GreemDev/GLI -O gli.exe -p 'GitLabCli-win_x64.exe'
|
gli upload-generic-package -T ${{ secrets.GITLAB_TOKEN }} -P ryubing/canary -n Ryubing-Canary -v ${{ steps.version_info.outputs.build_version }} -r 5 -p release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip
|
||||||
|
|
||||||
./gli.exe --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip"
|
|
||||||
shell: bash
|
shell: bash
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Install GitLabCli
|
|
||||||
if: matrix.platform.os == 'ubuntu-latest'
|
|
||||||
run: |
|
|
||||||
mkdir -p $HOME/.bin
|
|
||||||
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
|
|
||||||
chmod +x gli
|
|
||||||
mv gli $HOME/.bin/
|
|
||||||
echo "$HOME/.bin" >> $GITHUB_PATH
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Packing Linux builds
|
- name: Packing Linux builds
|
||||||
if: matrix.platform.os == 'ubuntu-latest'
|
if: contains(matrix.platform.name, 'linux')
|
||||||
run: |
|
run: |
|
||||||
pushd publish
|
pushd publish
|
||||||
rm libarmeilleure-jitsupport.dylib
|
rm libarmeilleure-jitsupport.dylib
|
||||||
@@ -103,11 +103,11 @@ jobs:
|
|||||||
tar -czvf ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
|
tar -czvf ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
|
||||||
popd
|
popd
|
||||||
|
|
||||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz"
|
gli upload-generic-package -T ${{ secrets.GITLAB_TOKEN }} -P ryubing/canary -n Ryubing-Canary -v ${{ steps.version_info.outputs.build_version }} -r 5 -p release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Build AppImage (Linux)
|
- name: Build AppImage (Linux)
|
||||||
if: matrix.platform.os == 'ubuntu-latest'
|
if: contains(matrix.platform.name, 'linux')
|
||||||
run: |
|
run: |
|
||||||
BUILD_VERSION="${{ steps.version_info.outputs.build_version }}"
|
BUILD_VERSION="${{ steps.version_info.outputs.build_version }}"
|
||||||
PLATFORM_NAME="${{ matrix.platform.name }}"
|
PLATFORM_NAME="${{ matrix.platform.name }}"
|
||||||
@@ -139,8 +139,8 @@ jobs:
|
|||||||
pushd publish_appimage
|
pushd publish_appimage
|
||||||
mv Ryujinx.AppImage ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage
|
mv Ryujinx.AppImage ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage
|
||||||
popd
|
popd
|
||||||
|
|
||||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage"
|
gli upload-generic-package -T ${{ secrets.GITLAB_TOKEN }} -P ryubing/canary -n Ryubing-Canary -v ${{ steps.version_info.outputs.build_version }} -r 5 -p release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
macos_release:
|
macos_release:
|
||||||
@@ -159,10 +159,10 @@ jobs:
|
|||||||
chmod +x llvm.sh
|
chmod +x llvm.sh
|
||||||
sudo ./llvm.sh 17
|
sudo ./llvm.sh 17
|
||||||
|
|
||||||
- name: Install GitLabCli
|
- name: Install gli
|
||||||
run: |
|
run: |
|
||||||
mkdir -p $HOME/.bin
|
mkdir -p $HOME/.bin
|
||||||
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
|
gh release download -R GreemDev/GLI -O gli -p 'gli-linux-x64'
|
||||||
chmod +x gli
|
chmod +x gli
|
||||||
mv gli $HOME/.bin/
|
mv gli $HOME/.bin/
|
||||||
echo "$HOME/.bin" >> $GITHUB_PATH
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
@@ -183,9 +183,10 @@ jobs:
|
|||||||
- name: Get version info
|
- name: Get version info
|
||||||
id: version_info
|
id: version_info
|
||||||
run: |
|
run: |
|
||||||
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
echo "build_version=$(gli get-next-version -c Canary -R)" >> $GITHUB_OUTPUT
|
||||||
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
|
echo "prev_build_version=$(gli get-current-version -c Canary -R)" >> $GITHUB_OUTPUT
|
||||||
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
|
shell: bash
|
||||||
|
|
||||||
- name: Configure for release
|
- name: Configure for release
|
||||||
run: |
|
run: |
|
||||||
@@ -200,7 +201,7 @@ jobs:
|
|||||||
- name: Publish macOS Ryujinx
|
- name: Publish macOS Ryujinx
|
||||||
run: |
|
run: |
|
||||||
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 1
|
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 1
|
||||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|publish_ava/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz"
|
gli upload-generic-package -T ${{ secrets.GITLAB_TOKEN }} -P ryubing/canary -n Ryubing-Canary -v ${{ steps.version_info.outputs.build_version }} -r 5 -p publish_ava/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz
|
||||||
|
|
||||||
create_gitlab_release:
|
create_gitlab_release:
|
||||||
name: Create GitLab Release
|
name: Create GitLab Release
|
||||||
@@ -210,37 +211,41 @@ jobs:
|
|||||||
- release
|
- release
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Get version info
|
- name: Install gli
|
||||||
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: |
|
run: |
|
||||||
mkdir -p $HOME/.bin
|
mkdir -p $HOME/.bin
|
||||||
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
|
gh release download -R GreemDev/GLI -O gli -p 'gli-linux-x64'
|
||||||
chmod +x gli
|
chmod +x gli
|
||||||
mv gli $HOME/.bin/
|
mv gli $HOME/.bin/
|
||||||
echo "$HOME/.bin" >> $GITHUB_PATH
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Get version info
|
||||||
|
id: version_info
|
||||||
|
run: |
|
||||||
|
echo "build_version=$(gli get-next-version -c Canary -R)" >> $GITHUB_OUTPUT
|
||||||
|
echo "prev_build_version=$(gli get-current-version -c Canary -R)" >> $GITHUB_OUTPUT
|
||||||
|
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
|
shell: bash
|
||||||
|
|
||||||
- name: Create tag
|
- name: Create tag
|
||||||
run: |
|
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 }}"
|
gli create-tag -T ${{ secrets.GITLAB_TOKEN }} -P ryubing/ryujinx -n Canary-${{ steps.version_info.outputs.build_version }} -r ${{ steps.version_info.outputs.git_short_hash }}
|
||||||
|
|
||||||
- name: Create release
|
- name: Create release
|
||||||
run: |
|
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 }})"
|
gli create-release-from-generic-package-files -T ${{ secrets.GITLAB_TOKEN }} -P ryubing/canary -n Ryubing-Canary -v ${{ steps.version_info.outputs.build_version }} -r main -t "Canary ${{ steps.version_info.outputs.build_version }}" -b "**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
|
- name: Send notification webhook
|
||||||
run: |
|
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"
|
gli send-update-message -T ${{ secrets.GITLAB_TOKEN }} -P ryubing/canary -t ${{ steps.version_info.outputs.build_version }} -c FF4500 -w ${{ secrets.CANARY_DISCORD_WEBHOOK }} -i https://avatars.githubusercontent.com/u/192939710?s=200&v=4
|
||||||
|
|
||||||
- name: Notify update server of new builds
|
- name: Notify update server of new builds
|
||||||
run: |
|
run: |
|
||||||
curl 'https://update.ryujinx.app/api/v1/admin/refresh_cache?rc=canary' -X PATCH -H 'accept: */*' -H 'Authorization: ${{ secrets.UPDATE_SERVER_ADMIN_TOKEN }}'
|
gli refresh-version-cache -T ${{ secrets.UPDATE_SERVER_ADMIN_TOKEN }} -c Canary
|
||||||
|
|
||||||
|
- name: Advance to the next version
|
||||||
|
run: |
|
||||||
|
gli increment-version -T ${{ secrets.UPDATE_SERVER_ADMIN_TOKEN }} -c Canary
|
||||||
|
|||||||
224
.github/workflows/debug_release.yml
vendored
224
.github/workflows/debug_release.yml
vendored
@@ -1,224 +0,0 @@
|
|||||||
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"
|
|
||||||
123
.github/workflows/release.yml
vendored
123
.github/workflows/release.yml
vendored
@@ -1,15 +1,18 @@
|
|||||||
name: Release job
|
name: Stable CI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs: {}
|
inputs:
|
||||||
|
is_bugfix_release:
|
||||||
|
description: "Bug fix release: If checked, this will increment the third number for only Stable, and leave the Major version alone for both Stable and Canary."
|
||||||
|
required: true
|
||||||
|
type: boolean
|
||||||
|
|
||||||
concurrency: release
|
concurrency: release
|
||||||
|
|
||||||
env:
|
env:
|
||||||
POWERSHELL_TELEMETRY_OPTOUT: 1
|
POWERSHELL_TELEMETRY_OPTOUT: 1
|
||||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||||
RYUJINX_BASE_VERSION: "1.3"
|
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release"
|
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release"
|
||||||
RELEASE: 1
|
RELEASE: 1
|
||||||
|
|
||||||
@@ -20,8 +23,8 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
platform:
|
platform:
|
||||||
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
|
- { name: win-x64, os: ubuntu-latest, zip_os_name: win_x64 }
|
||||||
#- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 }
|
#- { name: win-arm64, os: ubuntu-latest, zip_os_name: win_arm64 }
|
||||||
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
|
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
|
||||||
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
|
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
|
||||||
steps:
|
steps:
|
||||||
@@ -33,12 +36,30 @@ jobs:
|
|||||||
|
|
||||||
- name: Overwrite csc problem matcher
|
- name: Overwrite csc problem matcher
|
||||||
run: echo "::add-matcher::.github/csc.json"
|
run: echo "::add-matcher::.github/csc.json"
|
||||||
|
|
||||||
|
- name: Install 7zip
|
||||||
|
run: |
|
||||||
|
sudo apt install -y 7zip
|
||||||
|
|
||||||
|
- name: Install gli
|
||||||
|
run: |
|
||||||
|
mkdir -p $HOME/.bin
|
||||||
|
gh release download -R GreemDev/GLI -O gli -p 'gli-linux-x64'
|
||||||
|
chmod +x gli
|
||||||
|
mv gli $HOME/.bin/
|
||||||
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Get version info
|
- name: Get version info
|
||||||
id: version_info
|
id: version_info
|
||||||
run: |
|
run: |
|
||||||
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
if [ '${{ inputs.is_bugfix_release }}' == 'false' ]; then
|
||||||
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
|
echo "build_version=$(gli get-next-version -m -c Stable -R)" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "build_version=$(gli get-next-version -c Stable -R)" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
echo "prev_build_version=$(gli get-current-version -c Stable -R)" >> $GITHUB_OUTPUT
|
||||||
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
@@ -58,47 +79,34 @@ jobs:
|
|||||||
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
|
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
|
- name: Packing Windows builds
|
||||||
if: matrix.platform.os == 'windows-latest'
|
if: contains(matrix.platform.name, 'win')
|
||||||
run: |
|
run: |
|
||||||
pushd publish
|
pushd publish
|
||||||
rm libarmeilleure-jitsupport.dylib
|
rm libarmeilleure-jitsupport.dylib
|
||||||
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
|
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
|
||||||
popd
|
popd
|
||||||
|
|
||||||
gh release download -R GreemDev/GLI -O gli.exe -p 'GitLabCli-win_x64.exe'
|
gli upload-generic-package -T ${{ secrets.GITLAB_TOKEN }} -P ryubing/ryujinx -n Ryubing -v ${{ steps.version_info.outputs.build_version }} -r 5 -p release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip
|
||||||
|
|
||||||
./gli.exe --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip"
|
|
||||||
shell: bash
|
shell: bash
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Install GitLabCli
|
|
||||||
if: matrix.platform.os == 'ubuntu-latest'
|
|
||||||
run: |
|
|
||||||
mkdir -p $HOME/.bin
|
|
||||||
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
|
|
||||||
chmod +x gli
|
|
||||||
mv gli $HOME/.bin/
|
|
||||||
echo "$HOME/.bin" >> $GITHUB_PATH
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Packing Linux builds
|
- name: Packing Linux builds
|
||||||
if: matrix.platform.os == 'ubuntu-latest'
|
if: contains(matrix.platform.name, 'linux')
|
||||||
run: |
|
run: |
|
||||||
pushd publish
|
pushd publish
|
||||||
rm libarmeilleure-jitsupport.dylib
|
rm libarmeilleure-jitsupport.dylib
|
||||||
chmod +x Ryujinx.sh Ryujinx
|
chmod +x Ryujinx.sh Ryujinx
|
||||||
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
|
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
|
||||||
popd
|
popd
|
||||||
|
|
||||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz"
|
gli upload-generic-package -T ${{ secrets.GITLAB_TOKEN }} -P ryubing/ryujinx -n Ryubing -v ${{ steps.version_info.outputs.build_version }} -r 5 -p release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz
|
||||||
shell: bash
|
shell: bash
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Build AppImage (Linux)
|
- name: Build AppImage (Linux)
|
||||||
if: matrix.platform.os == 'ubuntu-latest'
|
if: contains(matrix.platform.name, 'linux')
|
||||||
run: |
|
run: |
|
||||||
BUILD_VERSION="${{ steps.version_info.outputs.build_version }}"
|
BUILD_VERSION="${{ steps.version_info.outputs.build_version }}"
|
||||||
PLATFORM_NAME="${{ matrix.platform.name }}"
|
PLATFORM_NAME="${{ matrix.platform.name }}"
|
||||||
@@ -131,7 +139,7 @@ jobs:
|
|||||||
mv Ryujinx.AppImage ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage
|
mv Ryujinx.AppImage ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage
|
||||||
popd
|
popd
|
||||||
|
|
||||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage"
|
gli upload-generic-package -T ${{ secrets.GITLAB_TOKEN }} -P ryubing/ryujinx -n Ryubing -v ${{ steps.version_info.outputs.build_version }} -r 5 -p release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
macos_release:
|
macos_release:
|
||||||
@@ -150,10 +158,10 @@ jobs:
|
|||||||
chmod +x llvm.sh
|
chmod +x llvm.sh
|
||||||
sudo ./llvm.sh 17
|
sudo ./llvm.sh 17
|
||||||
|
|
||||||
- name: Install GitLabCli
|
- name: Install gli
|
||||||
run: |
|
run: |
|
||||||
mkdir -p $HOME/.bin
|
mkdir -p $HOME/.bin
|
||||||
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
|
gh release download -R GreemDev/GLI -O gli -p 'gli-linux-x64'
|
||||||
chmod +x gli
|
chmod +x gli
|
||||||
mv gli $HOME/.bin/
|
mv gli $HOME/.bin/
|
||||||
echo "$HOME/.bin" >> $GITHUB_PATH
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
@@ -174,9 +182,14 @@ jobs:
|
|||||||
- name: Get version info
|
- name: Get version info
|
||||||
id: version_info
|
id: version_info
|
||||||
run: |
|
run: |
|
||||||
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
if [ '${{ inputs.is_bugfix_release }}' == 'false' ]; then
|
||||||
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
|
echo "build_version=$(gli get-next-version -m -c Stable -R)" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "build_version=$(gli get-next-version -c Stable -R)" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
echo "prev_build_version=$(gli get-current-version -c Stable -R)" >> $GITHUB_OUTPUT
|
||||||
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
|
shell: bash
|
||||||
|
|
||||||
- name: Configure for release
|
- name: Configure for release
|
||||||
run: |
|
run: |
|
||||||
@@ -189,7 +202,8 @@ jobs:
|
|||||||
- name: Publish macOS Ryujinx
|
- name: Publish macOS Ryujinx
|
||||||
run: |
|
run: |
|
||||||
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0
|
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0
|
||||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|publish/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz"
|
|
||||||
|
gli upload-generic-package -T ${{ secrets.GITLAB_TOKEN }} -P ryubing/ryujinx -n Ryubing -v ${{ steps.version_info.outputs.build_version }} -r 5 -p publish/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz
|
||||||
|
|
||||||
create_gitlab_release:
|
create_gitlab_release:
|
||||||
name: Create GitLab Release
|
name: Create GitLab Release
|
||||||
@@ -200,32 +214,45 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Get version info
|
- name: Install gli
|
||||||
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: |
|
run: |
|
||||||
mkdir -p $HOME/.bin
|
mkdir -p $HOME/.bin
|
||||||
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
|
gh release download -R GreemDev/GLI -O gli -p 'gli-linux-x64'
|
||||||
chmod +x gli
|
chmod +x gli
|
||||||
mv gli $HOME/.bin/
|
mv gli $HOME/.bin/
|
||||||
echo "$HOME/.bin" >> $GITHUB_PATH
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Get version info
|
||||||
|
id: version_info
|
||||||
|
run: |
|
||||||
|
if [ '${{ inputs.is_bugfix_release }}' == 'false' ]; then
|
||||||
|
echo "build_version=$(gli get-next-version -m -c Stable -R)" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "build_version=$(gli get-next-version -c Stable -R)" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
echo "prev_build_version=$(gli get-current-version -c Stable -R)" >> $GITHUB_OUTPUT
|
||||||
|
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
|
echo "commit_message=$(git log -1 --pretty=%B)" >> $GITHUB_OUTPUT
|
||||||
|
shell: bash
|
||||||
|
|
||||||
- name: Create release
|
- name: Create release
|
||||||
run: |
|
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 }}"
|
gli create-release-from-generic-package-files -T ${{ secrets.GITLAB_TOKEN }} -P ryubing/ryujinx -n Ryubing -v ${{ steps.version_info.outputs.build_version }} -r ${{ steps.version_info.outputs.git_short_hash }} -t "${{ steps.version_info.outputs.build_version }}" -b "msd:${{ steps.version_info.outputs.build_version }}"
|
||||||
|
|
||||||
- name: Send notification webhook
|
- name: Send notification webhook
|
||||||
run: |
|
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"
|
gli send-update-message -T ${{ secrets.GITLAB_TOKEN }} -P ryubing/ryujinx -t ${{ steps.version_info.outputs.build_version }} -c 32cd32 -w ${{ secrets.STABLE_DISCORD_WEBHOOK }} -i https://avatars.githubusercontent.com/u/192939710?s=200&v=4
|
||||||
|
|
||||||
- name: Notify update server of new builds
|
- name: Notify update server of new builds
|
||||||
run: |
|
run: |
|
||||||
curl 'https://update.ryujinx.app/api/v1/admin/refresh_cache?rc=stable' -X PATCH -H 'accept: */*' -H 'Authorization: ${{ secrets.UPDATE_SERVER_ADMIN_TOKEN }}'
|
gli refresh-version-cache -T ${{ secrets.UPDATE_SERVER_ADMIN_TOKEN }} -c Stable
|
||||||
|
|
||||||
|
- name: Advance to the next version
|
||||||
|
run: |
|
||||||
|
if [ '${{ inputs.is_bugfix_release }}' == 'false' ]; then
|
||||||
|
gli advance-version -T ${{ secrets.UPDATE_SERVER_ADMIN_TOKEN }}
|
||||||
|
else
|
||||||
|
gli increment-version -T ${{ secrets.UPDATE_SERVER_ADMIN_TOKEN }} -c Stable
|
||||||
|
fi
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -18,6 +18,8 @@ build/
|
|||||||
[Oo]bj/
|
[Oo]bj/
|
||||||
AppDir/
|
AppDir/
|
||||||
publish_appimage/
|
publish_appimage/
|
||||||
|
publish_ava/
|
||||||
|
publish_tmp_ava/
|
||||||
|
|
||||||
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
|
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
|
||||||
!packages/*/build/
|
!packages/*/build/
|
||||||
@@ -98,6 +100,7 @@ DocProject/Help/html
|
|||||||
|
|
||||||
# Click-Once directory
|
# Click-Once directory
|
||||||
publish/
|
publish/
|
||||||
|
RyubingMaintainerTools/
|
||||||
|
|
||||||
# Publish Web Output
|
# Publish Web Output
|
||||||
*.Publish.xml
|
*.Publish.xml
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ If you wish to build the emulator yourself, follow these steps:
|
|||||||
|
|
||||||
### Step 1
|
### Step 1
|
||||||
|
|
||||||
Install the [.NET 9.0 (or higher) SDK](https://dotnet.microsoft.com/download/dotnet/9.0).
|
Install the [.NET 10.0 (or higher) SDK](https://dotnet.microsoft.com/en-us/download/dotnet/10.0).
|
||||||
Make sure your SDK version is higher or equal to the required version specified in [global.json](global.json).
|
Make sure your SDK version is higher or equal to the required version specified in [global.json](global.json).
|
||||||
|
|
||||||
### Step 2
|
### Step 2
|
||||||
|
|
||||||
Either use `git clone https://github.com/Ryubing/Ryujinx` on the command line to clone the repository or use Code --> Download zip button to get the files.
|
Either use `git clone https://git.ryujinx.app/ryubing/ryujinx.git` on the command line to clone the repository or use Code --> Download zip button to get the files.
|
||||||
|
|
||||||
### Step 3
|
### Step 3
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net9.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>preview</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -3,25 +3,26 @@
|
|||||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageVersion Include="Avalonia" Version="11.0.13" />
|
<PackageVersion Include="Avalonia" Version="11.3.6" />
|
||||||
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.0.13" />
|
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.3.6" />
|
||||||
<PackageVersion Include="Avalonia.Desktop" Version="11.0.13" />
|
<PackageVersion Include="Avalonia.Desktop" Version="11.3.6" />
|
||||||
<PackageVersion Include="Avalonia.Diagnostics" Version="11.0.13" />
|
<PackageVersion Include="Avalonia.Diagnostics" Version="11.3.6" />
|
||||||
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.0.13" />
|
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.3.6" />
|
||||||
<PackageVersion Include="Avalonia.Svg" Version="11.0.0.19" />
|
<PackageVersion Include="Svg.Controls.Avalonia" Version="11.3.6.2" />
|
||||||
<PackageVersion Include="Avalonia.Svg.Skia" Version="11.0.0.19" />
|
<PackageVersion Include="Svg.Controls.Skia.Avalonia" Version="11.3.6.2" />
|
||||||
<PackageVersion Include="Microsoft.Build.Framework" Version="17.11.4" />
|
<PackageVersion Include="Microsoft.Build.Framework" Version="17.11.4" />
|
||||||
<PackageVersion Include="Microsoft.Build.Utilities.Core" Version="17.12.6" />
|
<PackageVersion Include="Microsoft.Build.Utilities.Core" Version="17.12.6" />
|
||||||
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageVersion Include="Projektanker.Icons.Avalonia" Version="9.4.0" />
|
<PackageVersion Include="Projektanker.Icons.Avalonia" Version="9.6.2" />
|
||||||
<PackageVersion Include="Projektanker.Icons.Avalonia.FontAwesome" Version="9.4.0"/>
|
<PackageVersion Include="Projektanker.Icons.Avalonia.FontAwesome" Version="9.6.2" />
|
||||||
<PackageVersion Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="9.4.0"/>
|
<PackageVersion Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="9.6.2" />
|
||||||
|
<PackageVersion Include="ppy.SDL3-CS" Version="2025.920.0" />
|
||||||
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
||||||
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0"/>
|
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||||
<PackageVersion Include="Concentus" Version="2.2.2" />
|
<PackageVersion Include="Concentus" Version="2.2.2" />
|
||||||
<PackageVersion Include="DiscordRichPresence" Version="1.6.1.70" />
|
<PackageVersion Include="DiscordRichPresence" Version="1.6.1.70" />
|
||||||
<PackageVersion Include="DynamicData" Version="9.4.1" />
|
<PackageVersion Include="DynamicData" Version="9.4.1" />
|
||||||
<PackageVersion Include="FluentAvaloniaUI" Version="2.0.5" />
|
<PackageVersion Include="FluentAvaloniaUI.NoAnim" Version="2.4.0-build3" />
|
||||||
<PackageVersion Include="Humanizer" Version="2.14.1" />
|
<PackageVersion Include="Humanizer" Version="2.14.1" />
|
||||||
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
|
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
|
||||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
|
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
|
||||||
@@ -40,11 +41,10 @@
|
|||||||
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
|
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
|
||||||
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.AllArch" Version="6.1.2-build3" />
|
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.AllArch" Version="6.1.2-build3" />
|
||||||
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
||||||
<PackageVersion Include="Ryujinx.LibHac" Version="0.21.0-alpha.116" />
|
<PackageVersion Include="Ryujinx.LibHac" Version="0.21.0-alpha.126" />
|
||||||
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
|
||||||
<PackageVersion Include="Ryujinx.UpdateClient" Version="1.0.44" />
|
<PackageVersion Include="Ryujinx.UpdateClient" Version="1.0.44" />
|
||||||
<PackageVersion Include="Ryujinx.Systems.Update.Common" Version="1.0.44" />
|
<PackageVersion Include="Ryujinx.Systems.Update.Common" Version="1.0.44" />
|
||||||
<PackageVersion Include="Gommon" Version="2.7.2.1" />
|
<PackageVersion Include="Gommon" Version="2.8.0.4" />
|
||||||
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
||||||
<PackageVersion Include="Sep" Version="0.11.1" />
|
<PackageVersion Include="Sep" Version="0.11.1" />
|
||||||
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ If you are planning to contribute or just want to learn more about this project
|
|||||||
- **Audio**
|
- **Audio**
|
||||||
|
|
||||||
Audio output is entirely supported, audio input (microphone) isn't supported.
|
Audio output is entirely supported, audio input (microphone) isn't supported.
|
||||||
We use C# wrappers for [OpenAL](https://openal-soft.org/), and [SDL2](https://www.libsdl.org/) & [libsoundio](http://libsound.io/) as fallbacks.
|
We use C# wrappers for [OpenAL](https://openal-soft.org/), and [SDL3](https://www.libsdl.org/) & [libsoundio](http://libsound.io/) as fallbacks.
|
||||||
|
|
||||||
- **CPU**
|
- **CPU**
|
||||||
|
|
||||||
|
|||||||
361
Ryujinx.sln
361
Ryujinx.sln
@@ -21,6 +21,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.GAL", "src
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.OpenGL", "src\Ryujinx.Graphics.OpenGL\Ryujinx.Graphics.OpenGL.csproj", "{9558FB96-075D-4219-8FFF-401979DC0B69}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.OpenGL", "src\Ryujinx.Graphics.OpenGL\Ryujinx.Graphics.OpenGL.csproj", "{9558FB96-075D-4219-8FFF-401979DC0B69}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.Graphics.RenderDoc", "src\Ryujinx.Graphics.RenderDocApi\Ryujinx.Graphics.RenderDocApi.csproj", "{D58FA894-27D5-4EAA-9042-AD422AD82931}"
|
||||||
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Texture", "src\Ryujinx.Graphics.Texture\Ryujinx.Graphics.Texture.csproj", "{E1B1AD28-289D-47B7-A106-326972240207}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Texture", "src\Ryujinx.Graphics.Texture\Ryujinx.Graphics.Texture.csproj", "{E1B1AD28-289D-47B7-A106-326972240207}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Shader", "src\Ryujinx.Graphics.Shader\Ryujinx.Graphics.Shader.csproj", "{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Shader", "src\Ryujinx.Graphics.Shader\Ryujinx.Graphics.Shader.csproj", "{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}"
|
||||||
@@ -45,17 +47,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Vic", "src
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Video", "src\Ryujinx.Graphics.Video\Ryujinx.Graphics.Video.csproj", "{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Video", "src\Ryujinx.Graphics.Video\Ryujinx.Graphics.Video.csproj", "{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.SDL3", "src\Ryujinx.Audio.Backends.SDL3\Ryujinx.Audio.Backends.SDL3.csproj", "{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}"
|
||||||
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.OpenAL", "src\Ryujinx.Audio.Backends.OpenAL\Ryujinx.Audio.Backends.OpenAL.csproj", "{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.OpenAL", "src\Ryujinx.Audio.Backends.OpenAL\Ryujinx.Audio.Backends.OpenAL.csproj", "{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.SoundIo", "src\Ryujinx.Audio.Backends.SoundIo\Ryujinx.Audio.Backends.SoundIo.csproj", "{716364DE-B988-41A6-BAB4-327964266ECC}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.SoundIo", "src\Ryujinx.Audio.Backends.SoundIo\Ryujinx.Audio.Backends.SoundIo.csproj", "{716364DE-B988-41A6-BAB4-327964266ECC}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Input", "src\Ryujinx.Input\Ryujinx.Input.csproj", "{C16F112F-38C3-40BC-9F5F-4791112063D6}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Input", "src\Ryujinx.Input\Ryujinx.Input.csproj", "{C16F112F-38C3-40BC-9F5F-4791112063D6}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Input.SDL2", "src\Ryujinx.Input.SDL2\Ryujinx.Input.SDL2.csproj", "{DFAB6F2D-B9BF-4AFF-B22B-7684A328EBA3}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Input.SDL3", "src\Ryujinx.Input.SDL3\Ryujinx.Input.SDL3.csproj", "{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}"
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.SDL2.Common", "src\Ryujinx.SDL2.Common\Ryujinx.SDL2.Common.csproj", "{2D5D3A1D-5730-4648-B0AB-06C53CB910C0}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.SDL2", "src\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj", "{D99A395A-8569-4DB0-B336-900647890052}"
|
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.FFmpeg", "src\Ryujinx.Graphics.Nvdec.FFmpeg\Ryujinx.Graphics.Nvdec.FFmpeg.csproj", "{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.FFmpeg", "src\Ryujinx.Graphics.Nvdec.FFmpeg\Ryujinx.Graphics.Nvdec.FFmpeg.csproj", "{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}"
|
||||||
EndProject
|
EndProject
|
||||||
@@ -79,12 +79,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.HLE.Generators", "s
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.BuildValidationTasks", "src\Ryujinx.BuildValidationTasks\Ryujinx.BuildValidationTasks.csproj", "{4A89A234-4F19-497D-A576-DDE8CDFC5B22}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.BuildValidationTasks", "src\Ryujinx.BuildValidationTasks\Ryujinx.BuildValidationTasks.csproj", "{4A89A234-4F19-497D-A576-DDE8CDFC5B22}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.SDL3.Common", "src\Ryujinx.SDL3.Common\Ryujinx.SDL3.Common.csproj", "{F6F9826A-BC58-4D78-A700-F358A66B2B06}"
|
||||||
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36F870C1-3E5F-485F-B426-F0645AF78751}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36F870C1-3E5F-485F-B426-F0645AF78751}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
.editorconfig = .editorconfig
|
.editorconfig = .editorconfig
|
||||||
.github\workflows\build.yml = .github\workflows\build.yml
|
.github\workflows\build.yml = .github\workflows\build.yml
|
||||||
.github\workflows\canary.yml = .github\workflows\canary.yml
|
.github\workflows\canary.yml = .github\workflows\canary.yml
|
||||||
Directory.Packages.props = Directory.Packages.props
|
Directory.Packages.props = Directory.Packages.props
|
||||||
|
Directory.Build.props = Directory.Build.props
|
||||||
.github\workflows\release.yml = .github\workflows\release.yml
|
.github\workflows\release.yml = .github\workflows\release.yml
|
||||||
nuget.config = nuget.config
|
nuget.config = nuget.config
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
@@ -92,164 +95,480 @@ EndProject
|
|||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Release|Any CPU.Build.0 = Release|Any CPU
|
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Release|Any CPU.Build.0 = Release|Any CPU
|
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Release|Any CPU.Build.0 = Release|Any CPU
|
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Release|Any CPU.Build.0 = Release|Any CPU
|
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Release|Any CPU.Build.0 = Release|Any CPU
|
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{5FD4E4F6-8928-4B3C-BE07-28A675C17226}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Release|Any CPU.Build.0 = Release|Any CPU
|
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{ABF09A5E-2D8B-4B6F-A51D-5CE414DDB15A}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Release|Any CPU.Build.0 = Release|Any CPU
|
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{ADA7EA87-0D63-4D97-9433-922A2124401F}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Release|Any CPU.Build.0 = Release|Any CPU
|
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{9558FB96-075D-4219-8FFF-401979DC0B69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{9558FB96-075D-4219-8FFF-401979DC0B69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{9558FB96-075D-4219-8FFF-401979DC0B69}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{9558FB96-075D-4219-8FFF-401979DC0B69}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{9558FB96-075D-4219-8FFF-401979DC0B69}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{9558FB96-075D-4219-8FFF-401979DC0B69}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{9558FB96-075D-4219-8FFF-401979DC0B69}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{9558FB96-075D-4219-8FFF-401979DC0B69}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{9558FB96-075D-4219-8FFF-401979DC0B69}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{9558FB96-075D-4219-8FFF-401979DC0B69}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{9558FB96-075D-4219-8FFF-401979DC0B69}.Release|Any CPU.Build.0 = Release|Any CPU
|
{9558FB96-075D-4219-8FFF-401979DC0B69}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{9558FB96-075D-4219-8FFF-401979DC0B69}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{9558FB96-075D-4219-8FFF-401979DC0B69}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{9558FB96-075D-4219-8FFF-401979DC0B69}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{9558FB96-075D-4219-8FFF-401979DC0B69}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{E1B1AD28-289D-47B7-A106-326972240207}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{E1B1AD28-289D-47B7-A106-326972240207}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{E1B1AD28-289D-47B7-A106-326972240207}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{E1B1AD28-289D-47B7-A106-326972240207}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{E1B1AD28-289D-47B7-A106-326972240207}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{E1B1AD28-289D-47B7-A106-326972240207}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{E1B1AD28-289D-47B7-A106-326972240207}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{E1B1AD28-289D-47B7-A106-326972240207}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{E1B1AD28-289D-47B7-A106-326972240207}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{E1B1AD28-289D-47B7-A106-326972240207}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{E1B1AD28-289D-47B7-A106-326972240207}.Release|Any CPU.Build.0 = Release|Any CPU
|
{E1B1AD28-289D-47B7-A106-326972240207}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{E1B1AD28-289D-47B7-A106-326972240207}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{E1B1AD28-289D-47B7-A106-326972240207}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{E1B1AD28-289D-47B7-A106-326972240207}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{E1B1AD28-289D-47B7-A106-326972240207}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Release|Any CPU.Build.0 = Release|Any CPU
|
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{03B955CD-AD84-4B93-AAA7-BF17923BBAA5}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Release|Any CPU.Build.0 = Release|Any CPU
|
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{85A0FA56-DC01-4A42-8808-70DAC76BD66D}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Release|Any CPU.Build.0 = Release|Any CPU
|
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Release|Any CPU.Build.0 = Release|Any CPU
|
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{A5E6C691-9E22-4263-8F40-42F002CE66BE}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Release|Any CPU.Build.0 = Release|Any CPU
|
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{D1CC5322-7325-4F6B-9625-194B30BE1296}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Release|Any CPU.Build.0 = Release|Any CPU
|
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{3DF35E3D-D844-4399-A9A1-A9E923264C17}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Release|Any CPU.Build.0 = Release|Any CPU
|
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{C3002C3C-7B09-4FE7-894A-372EDA22FC6E}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Release|Any CPU.Build.0 = Release|Any CPU
|
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{C35F1536-7DE5-4F9D-9604-B5B4E1561947}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Release|Any CPU.Build.0 = Release|Any CPU
|
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{B9AECA11-E248-4886-A10B-81B631CAAF29}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{81BB2C11-9408-4EA3-822E-42987AF54429}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{81BB2C11-9408-4EA3-822E-42987AF54429}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{81BB2C11-9408-4EA3-822E-42987AF54429}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{81BB2C11-9408-4EA3-822E-42987AF54429}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{81BB2C11-9408-4EA3-822E-42987AF54429}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{81BB2C11-9408-4EA3-822E-42987AF54429}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{81BB2C11-9408-4EA3-822E-42987AF54429}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{81BB2C11-9408-4EA3-822E-42987AF54429}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{81BB2C11-9408-4EA3-822E-42987AF54429}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{81BB2C11-9408-4EA3-822E-42987AF54429}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{81BB2C11-9408-4EA3-822E-42987AF54429}.Release|Any CPU.Build.0 = Release|Any CPU
|
{81BB2C11-9408-4EA3-822E-42987AF54429}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{81BB2C11-9408-4EA3-822E-42987AF54429}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{81BB2C11-9408-4EA3-822E-42987AF54429}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{81BB2C11-9408-4EA3-822E-42987AF54429}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{81BB2C11-9408-4EA3-822E-42987AF54429}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Release|Any CPU.Build.0 = Release|Any CPU
|
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Release|Any CPU.Build.0 = Release|Any CPU
|
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{716364DE-B988-41A6-BAB4-327964266ECC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{716364DE-B988-41A6-BAB4-327964266ECC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{716364DE-B988-41A6-BAB4-327964266ECC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{716364DE-B988-41A6-BAB4-327964266ECC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{716364DE-B988-41A6-BAB4-327964266ECC}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{716364DE-B988-41A6-BAB4-327964266ECC}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{716364DE-B988-41A6-BAB4-327964266ECC}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{716364DE-B988-41A6-BAB4-327964266ECC}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{716364DE-B988-41A6-BAB4-327964266ECC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{716364DE-B988-41A6-BAB4-327964266ECC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{716364DE-B988-41A6-BAB4-327964266ECC}.Release|Any CPU.Build.0 = Release|Any CPU
|
{716364DE-B988-41A6-BAB4-327964266ECC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{716364DE-B988-41A6-BAB4-327964266ECC}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{716364DE-B988-41A6-BAB4-327964266ECC}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{716364DE-B988-41A6-BAB4-327964266ECC}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{716364DE-B988-41A6-BAB4-327964266ECC}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Release|Any CPU.Build.0 = Release|Any CPU
|
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{DFAB6F2D-B9BF-4AFF-B22B-7684A328EBA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
{DFAB6F2D-B9BF-4AFF-B22B-7684A328EBA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{DFAB6F2D-B9BF-4AFF-B22B-7684A328EBA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{DFAB6F2D-B9BF-4AFF-B22B-7684A328EBA3}.Release|Any CPU.Build.0 = Release|Any CPU
|
{C16F112F-38C3-40BC-9F5F-4791112063D6}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{2D5D3A1D-5730-4648-B0AB-06C53CB910C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{2D5D3A1D-5730-4648-B0AB-06C53CB910C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{2D5D3A1D-5730-4648-B0AB-06C53CB910C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{2D5D3A1D-5730-4648-B0AB-06C53CB910C0}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{D99A395A-8569-4DB0-B336-900647890052}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{D99A395A-8569-4DB0-B336-900647890052}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|Any CPU.Build.0 = Release|Any CPU
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.Build.0 = Release|Any CPU
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Release|Any CPU.Build.0 = Release|Any CPU
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|Any CPU.Build.0 = Release|Any CPU
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Release|Any CPU.Build.0 = Release|Any CPU
|
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{D4D09B08-D580-4D69-B886-C35D2853F6C8}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Release|Any CPU.Build.0 = Release|Any CPU
|
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{2BCB3D7A-38C0-4FE7-8FDA-374C6AD56D0E}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Release|Any CPU.Build.0 = Release|Any CPU
|
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{77D01AD9-2C98-478E-AE1D-8F7100738FB4}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{77F96ECE-4952-42DB-A528-DED25572A573}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{77F96ECE-4952-42DB-A528-DED25572A573}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{77F96ECE-4952-42DB-A528-DED25572A573}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{77F96ECE-4952-42DB-A528-DED25572A573}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{77F96ECE-4952-42DB-A528-DED25572A573}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{77F96ECE-4952-42DB-A528-DED25572A573}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{77F96ECE-4952-42DB-A528-DED25572A573}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{77F96ECE-4952-42DB-A528-DED25572A573}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{77F96ECE-4952-42DB-A528-DED25572A573}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{77F96ECE-4952-42DB-A528-DED25572A573}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{77F96ECE-4952-42DB-A528-DED25572A573}.Release|Any CPU.Build.0 = Release|Any CPU
|
{77F96ECE-4952-42DB-A528-DED25572A573}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{77F96ECE-4952-42DB-A528-DED25572A573}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{77F96ECE-4952-42DB-A528-DED25572A573}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{77F96ECE-4952-42DB-A528-DED25572A573}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{77F96ECE-4952-42DB-A528-DED25572A573}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Release|Any CPU.Build.0 = Release|Any CPU
|
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{AF34127A-3A92-43E5-8496-14960A50B1F1}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Release|Any CPU.Build.0 = Release|Any CPU
|
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.Build.0 = Release|Any CPU
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{F6F9826A-BC58-4D78-A700-F358A66B2B06}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{D728444C-3D1F-4A0E-B4C9-5C9375D47EA3}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{988E6191-82E1-4E13-9DDB-CB9FA2FDAF29}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{D58FA894-27D5-4EAA-9042-AD422AD82931}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{D58FA894-27D5-4EAA-9042-AD422AD82931}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D58FA894-27D5-4EAA-9042-AD422AD82931}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{D58FA894-27D5-4EAA-9042-AD422AD82931}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{D58FA894-27D5-4EAA-9042-AD422AD82931}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{D58FA894-27D5-4EAA-9042-AD422AD82931}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{D58FA894-27D5-4EAA-9042-AD422AD82931}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{D58FA894-27D5-4EAA-9042-AD422AD82931}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{D58FA894-27D5-4EAA-9042-AD422AD82931}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{D58FA894-27D5-4EAA-9042-AD422AD82931}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{D58FA894-27D5-4EAA-9042-AD422AD82931}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{D58FA894-27D5-4EAA-9042-AD422AD82931}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
24
assets/Languages.json
Normal file
24
assets/Languages.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"Languages": {
|
||||||
|
"ar_SA": "اَلْعَرَبِيَّةُ",
|
||||||
|
"de_DE": "Deutsch",
|
||||||
|
"el_GR": "Ελληνικά",
|
||||||
|
"en_US": "English (US)",
|
||||||
|
"es_ES": "Español (ES)",
|
||||||
|
"fr_FR": "Français (FR)",
|
||||||
|
"he_IL": "עִברִית",
|
||||||
|
"it_IT": "Italiano",
|
||||||
|
"ja_JP": "日本語",
|
||||||
|
"ko_KR": "한국어",
|
||||||
|
"no_NO": "Norsk",
|
||||||
|
"pl_PL": "Polski",
|
||||||
|
"pt_BR": "Português (BR)",
|
||||||
|
"ru_RU": "Русский",
|
||||||
|
"sv_SE": "Svenska",
|
||||||
|
"th_TH": "ภาษาไทย",
|
||||||
|
"tr_TR": "Türkçe",
|
||||||
|
"uk_UA": "Українська",
|
||||||
|
"zh_CN": "简体中文",
|
||||||
|
"zh_TW": "繁體中文 (台灣)"
|
||||||
|
}
|
||||||
|
}
|
||||||
60
assets/Locales.md
Normal file
60
assets/Locales.md
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
|
||||||
|
# Ryubing Locales
|
||||||
|
|
||||||
|
Ryubing Locales uses a custom format, which uses a file for defining the supported languages and a folder of json files for the locales themselves.
|
||||||
|
Each json file holds the locales for a specific part of the emulator, e.g. the Setup Wizard locales are in `SetupWizard.json`, and each locale entry in the file includes all the supported languages in the same place.
|
||||||
|
|
||||||
|
## Languages
|
||||||
|
in the `/assets/` folder you will find the `Languages.json` file, which defines all the languages supported by the emulator.
|
||||||
|
The file includes a table of the langauge codes and their langauge names.
|
||||||
|
|
||||||
|
#Example of the format for Languages.json
|
||||||
|
{
|
||||||
|
"Languages": {
|
||||||
|
"ar_SA": "اَلْعَرَبِيَّةُ",
|
||||||
|
"en_US": "English (US)",
|
||||||
|
...
|
||||||
|
"zh_TW": "繁體中文 (台灣)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## Locales
|
||||||
|
in the `/assets/Locales/` folder you will find the json files, which define all the locales supported by the emulator.
|
||||||
|
Each json file holds locales for a specific part of the emulator in a large array of locale objects.
|
||||||
|
Each locale is made up an ID used for lookup and a list of the languages and their matching translations.
|
||||||
|
Any empty string or null value will automatically use the English translation instead in the emulator.
|
||||||
|
|
||||||
|
### Format
|
||||||
|
When adding a new locale, you just need to add the ID and the en_US language translation, then the validation system will add default values for the rest of languages automatically, when rebuilding the project.
|
||||||
|
If you want to signal that a translation is supposed to match the English translation, you just have to replace the empty string with `null`.
|
||||||
|
When you want to check what translations are missing for a language just search for `"<lang_code>": ""`, e.g: `"en_US": ""` (but with any other language, as English will never be missing translations).
|
||||||
|
|
||||||
|
### Legacy file (Root.json)
|
||||||
|
Currently all older locales are stored in `Root.json`, but they are slowly being moved into newer, more descriptive json files, to make the locale system more accessible.
|
||||||
|
Do **not** add new locales to `Root.json`.
|
||||||
|
If no json file exists for the specific part of the emulator you're working on, you should instead add a new json file for that part.
|
||||||
|
|
||||||
|
#Example of the format for Root.json
|
||||||
|
{
|
||||||
|
"Locales": [
|
||||||
|
{
|
||||||
|
"ID": "MenuBarActionsOpenMiiEditor",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"en_US": "Mii Editor",
|
||||||
|
...
|
||||||
|
"zh_TW": "Mii 編輯器"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "KeyNumber9",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "٩",
|
||||||
|
"en_US": "9",
|
||||||
|
...
|
||||||
|
"zh_TW": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
104
assets/Locales/RenderDoc.json
Normal file
104
assets/Locales/RenderDoc.json
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
{
|
||||||
|
"Locales": [
|
||||||
|
{
|
||||||
|
"ID": "MenuBarActions_StartCapture",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Start RenderDoc Frame Capture",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "MenuBarActions_EndCapture",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "End RenderDoc Frame Capture",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "MenuBarActions_DiscardCapture",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Discard RenderDoc Frame Capture",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "MenuBarActions_DiscardCapture_ToolTip",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Ends the currently active RenderDoc Frame Capture, immediately discarding its result.",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
SCRIPT_DIR=$(dirname "$(realpath "$0")")
|
SCRIPT_DIR=$(dirname "$(realpath "$0")")
|
||||||
|
|
||||||
if [ -f "$SCRIPT_DIR/Ryujinx.Headless.SDL2" ]; then
|
if [ -f "$SCRIPT_DIR/Ryujinx.Headless.SDL3" ]; then
|
||||||
RYUJINX_BIN="Ryujinx.Headless.SDL2"
|
RYUJINX_BIN="Ryujinx.Headless.SDL3"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -f "$SCRIPT_DIR/Ryujinx" ]; then
|
if [ -f "$SCRIPT_DIR/Ryujinx" ]; then
|
||||||
|
|||||||
BIN
distribution/macos/Assets.car
Normal file
BIN
distribution/macos/Assets.car
Normal file
Binary file not shown.
@@ -10,6 +10,8 @@
|
|||||||
<string>Ryujinx</string>
|
<string>Ryujinx</string>
|
||||||
<key>CFBundleIconFile</key>
|
<key>CFBundleIconFile</key>
|
||||||
<string>Ryujinx.icns</string>
|
<string>Ryujinx.icns</string>
|
||||||
|
<key>CFBundleIconName</key>
|
||||||
|
<string>Ryujinx</string>
|
||||||
<key>CFBundleDocumentTypes</key>
|
<key>CFBundleDocumentTypes</key>
|
||||||
<array>
|
<array>
|
||||||
<dict>
|
<dict>
|
||||||
@@ -34,23 +36,23 @@
|
|||||||
<key>CFBundleInfoDictionaryVersion</key>
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
<string>6.0</string>
|
<string>6.0</string>
|
||||||
<key>CFBundleLongVersionString</key>
|
<key>CFBundleLongVersionString</key>
|
||||||
<string>%%RYUJINX_BUILD_VERSION%%-%%RYUJINX_BUILD_GIT_HASH%%"</string>
|
<string>%%RYUJINX_BUILD_VERSION%%-%%RYUJINX_BUILD_GIT_HASH%%</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
<string>Ryujinx</string>
|
<string>Ryujinx</string>
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.2</string>
|
<string>1.3</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1.2.0</string>
|
<string>%%RYUJINX_BUILD_VERSION%%</string>
|
||||||
<key>NSHighResolutionCapable</key>
|
<key>NSHighResolutionCapable</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>CSResourcesFileMapped</key>
|
<key>CSResourcesFileMapped</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>Copyright © 2018 - 2023 Ryujinx Team and Contributors.</string>
|
<string>Copyright © 2018 - 2024 Ryujinx Team and Contributors. Copyright © 2024 - 2025 Ryubing and Contributors.</string>
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
<string>public.app-category.games</string>
|
<string>public.app-category.games</string>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ cp "$PUBLISH_DIRECTORY"/*.dylib "$APP_BUNDLE_DIRECTORY/Contents/Frameworks"
|
|||||||
cp Info.plist "$APP_BUNDLE_DIRECTORY/Contents"
|
cp Info.plist "$APP_BUNDLE_DIRECTORY/Contents"
|
||||||
cp Ryujinx.icns "$APP_BUNDLE_DIRECTORY/Contents/Resources/Ryujinx.icns"
|
cp Ryujinx.icns "$APP_BUNDLE_DIRECTORY/Contents/Resources/Ryujinx.icns"
|
||||||
cp updater.sh "$APP_BUNDLE_DIRECTORY/Contents/Resources/updater.sh"
|
cp updater.sh "$APP_BUNDLE_DIRECTORY/Contents/Resources/updater.sh"
|
||||||
|
cp Assets.car "$APP_BUNDLE_DIRECTORY/Contents/Resources/Assets.car"
|
||||||
cp -r "$PUBLISH_DIRECTORY/THIRDPARTY.md" "$APP_BUNDLE_DIRECTORY/Contents/Resources"
|
cp -r "$PUBLISH_DIRECTORY/THIRDPARTY.md" "$APP_BUNDLE_DIRECTORY/Contents/Resources"
|
||||||
|
|
||||||
echo -n "APPL????" > "$APP_BUNDLE_DIRECTORY/Contents/PkgInfo"
|
echo -n "APPL????" > "$APP_BUNDLE_DIRECTORY/Contents/PkgInfo"
|
||||||
|
|||||||
@@ -1,124 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
if [ "$#" -lt 8 ]; then
|
|
||||||
echo "usage <BASE_DIR> <TEMP_DIRECTORY> <OUTPUT_DIRECTORY> <ENTITLEMENTS_FILE_PATH> <VERSION> <SOURCE_REVISION_ID> <CONFIGURATION> <CANARY>"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir -p "$1"
|
|
||||||
mkdir -p "$2"
|
|
||||||
mkdir -p "$3"
|
|
||||||
|
|
||||||
BASE_DIR=$(readlink -f "$1")
|
|
||||||
TEMP_DIRECTORY=$(readlink -f "$2")
|
|
||||||
OUTPUT_DIRECTORY=$(readlink -f "$3")
|
|
||||||
ENTITLEMENTS_FILE_PATH=$(readlink -f "$4")
|
|
||||||
VERSION=$5
|
|
||||||
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
|
|
||||||
RELEASE_TAR_FILE_NAME=nogui-ryujinx-$CONFIGURATION-$VERSION+$SOURCE_REVISION_ID-macos_universal.tar
|
|
||||||
else
|
|
||||||
RELEASE_TAR_FILE_NAME=nogui-ryujinx-$VERSION-macos_universal.tar
|
|
||||||
fi
|
|
||||||
|
|
||||||
ARM64_OUTPUT="$TEMP_DIRECTORY/publish_arm64"
|
|
||||||
X64_OUTPUT="$TEMP_DIRECTORY/publish_x64"
|
|
||||||
UNIVERSAL_OUTPUT="$OUTPUT_DIRECTORY/publish"
|
|
||||||
EXECUTABLE_SUB_PATH=Ryujinx.Headless.SDL2
|
|
||||||
|
|
||||||
rm -rf "$TEMP_DIRECTORY"
|
|
||||||
mkdir -p "$TEMP_DIRECTORY"
|
|
||||||
|
|
||||||
DOTNET_COMMON_ARGS=(-p:DebugType=embedded -p:Version="$VERSION" -p:SourceRevisionId="$SOURCE_REVISION_ID" --self-contained true $EXTRA_ARGS)
|
|
||||||
|
|
||||||
dotnet restore
|
|
||||||
dotnet build -c "$CONFIGURATION" src/Ryujinx.Headless.SDL2
|
|
||||||
dotnet publish -c "$CONFIGURATION" -r osx-arm64 -o "$TEMP_DIRECTORY/publish_arm64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Headless.SDL2
|
|
||||||
dotnet publish -c "$CONFIGURATION" -r osx-x64 -o "$TEMP_DIRECTORY/publish_x64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Headless.SDL2
|
|
||||||
|
|
||||||
# Get rid of the support library for ARMeilleure for x64 (that's only for arm64)
|
|
||||||
rm -rf "$TEMP_DIRECTORY/publish_x64/libarmeilleure-jitsupport.dylib"
|
|
||||||
|
|
||||||
# Get rid of libsoundio from arm64 builds as we don't have a arm64 variant
|
|
||||||
# TODO: remove this once done
|
|
||||||
rm -rf "$TEMP_DIRECTORY/publish_arm64/libsoundio.dylib"
|
|
||||||
|
|
||||||
rm -rf "$OUTPUT_DIRECTORY"
|
|
||||||
mkdir -p "$OUTPUT_DIRECTORY"
|
|
||||||
|
|
||||||
# Let's copy one of the two different outputs and remove the executable
|
|
||||||
cp -R "$ARM64_OUTPUT/" "$UNIVERSAL_OUTPUT"
|
|
||||||
rm "$UNIVERSAL_OUTPUT/$EXECUTABLE_SUB_PATH"
|
|
||||||
|
|
||||||
# Make its libraries universal
|
|
||||||
python3 "$BASE_DIR/distribution/macos/construct_universal_dylib.py" "$ARM64_OUTPUT" "$X64_OUTPUT" "$UNIVERSAL_OUTPUT" "**/*.dylib"
|
|
||||||
|
|
||||||
if ! [ -x "$(command -v lipo)" ];
|
|
||||||
then
|
|
||||||
if ! [ -x "$(command -v llvm-lipo-17)" ];
|
|
||||||
then
|
|
||||||
LIPO=llvm-lipo
|
|
||||||
else
|
|
||||||
LIPO=llvm-lipo-17
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
LIPO=lipo
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Make the executable universal
|
|
||||||
$LIPO "$ARM64_OUTPUT/$EXECUTABLE_SUB_PATH" "$X64_OUTPUT/$EXECUTABLE_SUB_PATH" -output "$UNIVERSAL_OUTPUT/$EXECUTABLE_SUB_PATH" -create
|
|
||||||
|
|
||||||
# Now sign it
|
|
||||||
if ! [ -x "$(command -v codesign)" ];
|
|
||||||
then
|
|
||||||
if ! [ -x "$(command -v rcodesign)" ];
|
|
||||||
then
|
|
||||||
echo "Cannot find rcodesign on your system, please install rcodesign."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# NOTE: Currently require https://github.com/indygreg/apple-platform-rs/pull/44 to work on other OSes.
|
|
||||||
# cargo install --git "https://github.com/marysaka/apple-platform-rs" --branch "fix/adhoc-app-bundle" apple-codesign --bin "rcodesign"
|
|
||||||
echo "Using rcodesign for ad-hoc signing"
|
|
||||||
for FILE in "$UNIVERSAL_OUTPUT"/*; do
|
|
||||||
if [[ $(file "$FILE") == *"Mach-O"* ]]; then
|
|
||||||
rcodesign sign --entitlements-xml-path "$ENTITLEMENTS_FILE_PATH" "$FILE"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
else
|
|
||||||
echo "Using codesign for ad-hoc signing"
|
|
||||||
for FILE in "$UNIVERSAL_OUTPUT"/*; do
|
|
||||||
if [[ $(file "$FILE") == *"Mach-O"* ]]; then
|
|
||||||
codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f -s - "$FILE"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Creating archive"
|
|
||||||
pushd "$OUTPUT_DIRECTORY"
|
|
||||||
tar --exclude "publish/Ryujinx.Headless.SDL2" -cvf "$RELEASE_TAR_FILE_NAME" publish 1> /dev/null
|
|
||||||
python3 "$BASE_DIR/distribution/misc/add_tar_exec.py" "$RELEASE_TAR_FILE_NAME" "publish/Ryujinx.Headless.SDL2" "publish/Ryujinx.Headless.SDL2"
|
|
||||||
gzip -9 < "$RELEASE_TAR_FILE_NAME" > "$RELEASE_TAR_FILE_NAME.gz"
|
|
||||||
rm "$RELEASE_TAR_FILE_NAME"
|
|
||||||
popd
|
|
||||||
|
|
||||||
echo "Done"
|
|
||||||
@@ -8,7 +8,7 @@ Intro to Ryujinx
|
|||||||
Ryujinx is an open-source Nintendo Switch emulator, created by gdkchan, written in C#.
|
Ryujinx is an open-source Nintendo Switch emulator, created by gdkchan, written in C#.
|
||||||
* The CPU emulator, ARMeilleure, emulates an ARMv8 CPU and currently has support for most 64-bit ARMv8 and some of the ARMv7 (and older) instructions.
|
* The CPU emulator, ARMeilleure, emulates an ARMv8 CPU and currently has support for most 64-bit ARMv8 and some of the ARMv7 (and older) instructions.
|
||||||
* The GPU emulator emulates the Switch's Maxwell GPU using either the OpenGL (version 4.5 minimum), Vulkan, or Metal (via MoltenVK) APIs through a custom build of OpenTK or Silk.NET respectively.
|
* The GPU emulator emulates the Switch's Maxwell GPU using either the OpenGL (version 4.5 minimum), Vulkan, or Metal (via MoltenVK) APIs through a custom build of OpenTK or Silk.NET respectively.
|
||||||
* Audio output is entirely supported via C# wrappers for SDL2, with OpenAL & libsoundio as fallbacks.
|
* Audio output is entirely supported via C# wrappers for SDL3, with OpenAL & libsoundio as fallbacks.
|
||||||
|
|
||||||
Getting Started
|
Getting Started
|
||||||
===============
|
===============
|
||||||
|
|||||||
@@ -2275,6 +2275,7 @@
|
|||||||
010018E011D92000,"Pokémon™ Shining Pearl",gpu;ldn-works,ingame,2024-08-28 13:26:35
|
010018E011D92000,"Pokémon™ Shining Pearl",gpu;ldn-works,ingame,2024-08-28 13:26:35
|
||||||
010015F008C54000,"Pokémon™ HOME",Needs Update;crash;services,menus,2020-12-06 06:01:51
|
010015F008C54000,"Pokémon™ HOME",Needs Update;crash;services,menus,2020-12-06 06:01:51
|
||||||
01001F5010DFA000,"Pokémon™ Legends: Arceus",gpu;Needs Update;ldn-works,ingame,2024-09-19 10:02:02
|
01001F5010DFA000,"Pokémon™ Legends: Arceus",gpu;Needs Update;ldn-works,ingame,2024-09-19 10:02:02
|
||||||
|
0100F43008C44000,"Pokémon™ Legends: Z-A",gpu;crash;ldn-works,ingame,2025-11-16 00:30:00
|
||||||
01005D100807A000,"Pokémon™ Quest",,playable,2022-02-22 16:12:32
|
01005D100807A000,"Pokémon™ Quest",,playable,2022-02-22 16:12:32
|
||||||
0100A3D008C5C000,"Pokémon™ Scarlet",gpu;nvdec;ldn-works;amd-vendor-bug,ingame,2023-12-14 13:18:29
|
0100A3D008C5C000,"Pokémon™ Scarlet",gpu;nvdec;ldn-works;amd-vendor-bug,ingame,2023-12-14 13:18:29
|
||||||
01008F6008C5E000,"Pokémon™ Violet",gpu;nvdec;ldn-works;amd-vendor-bug;mac-bug,ingame,2024-07-30 02:51:48
|
01008F6008C5E000,"Pokémon™ Violet",gpu;nvdec;ldn-works;amd-vendor-bug;mac-bug,ingame,2024-07-30 02:51:48
|
||||||
|
|||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"sdk": {
|
"sdk": {
|
||||||
"version": "9.0.100",
|
"version": "10.0.100",
|
||||||
"rollForward": "latestFeature"
|
"rollForward": "latestFeature"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
static class ComparisonArm64Extensions
|
static class ComparisonArm64Extensions
|
||||||
{
|
{
|
||||||
public static ArmCondition ToArmCondition(this Comparison comp)
|
extension(Comparison comparison)
|
||||||
{
|
{
|
||||||
return comp switch
|
public ArmCondition Arm => comparison switch
|
||||||
{
|
{
|
||||||
#pragma warning disable IDE0055 // Disable formatting
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
Comparison.Equal => ArmCondition.Eq,
|
Comparison.Equal => ArmCondition.Eq,
|
||||||
@@ -42,7 +42,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
Comparison.LessUI => ArmCondition.LtUn,
|
Comparison.LessUI => ArmCondition.LtUn,
|
||||||
#pragma warning restore IDE0055
|
#pragma warning restore IDE0055
|
||||||
|
|
||||||
_ => throw new ArgumentException(null, nameof(comp)),
|
_ => throw new ArgumentException(null, nameof(comparison))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,10 +181,10 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
public void Fmov(Operand rd, Operand rn, bool topHalf)
|
public void Fmov(Operand rd, Operand rn, bool topHalf)
|
||||||
{
|
{
|
||||||
Debug.Assert(rd.Type.IsInteger() != rn.Type.IsInteger());
|
Debug.Assert(rd.Type.IsInteger != rn.Type.IsInteger);
|
||||||
Debug.Assert(rd.Type == OperandType.I64 || rn.Type == OperandType.I64 || !topHalf);
|
Debug.Assert(rd.Type == OperandType.I64 || rn.Type == OperandType.I64 || !topHalf);
|
||||||
|
|
||||||
uint opcode = rd.Type.IsInteger() ? 0b110u : 0b111u;
|
uint opcode = rd.Type.IsInteger ? 0b110u : 0b111u;
|
||||||
|
|
||||||
uint rmode = topHalf ? 1u << 19 : 0u;
|
uint rmode = topHalf ? 1u << 19 : 0u;
|
||||||
uint ftype = rd.Type == OperandType.FP64 || rn.Type == OperandType.FP64 ? 1u << 22 : 0u;
|
uint ftype = rd.Type == OperandType.FP64 || rn.Type == OperandType.FP64 ? 1u << 22 : 0u;
|
||||||
@@ -411,7 +411,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
public void Mov(Operand rd, Operand rn)
|
public void Mov(Operand rd, Operand rn)
|
||||||
{
|
{
|
||||||
if (rd.Type.IsInteger())
|
if (rd.Type.IsInteger)
|
||||||
{
|
{
|
||||||
Orr(rd, Factory.Register(ZrRegister, RegisterType.Integer, rd.Type), rn);
|
Orr(rd, Factory.Register(ZrRegister, RegisterType.Integer, rd.Type), rn);
|
||||||
}
|
}
|
||||||
@@ -973,7 +973,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
uint instruction;
|
uint instruction;
|
||||||
int scale;
|
int scale;
|
||||||
|
|
||||||
if (type.IsInteger())
|
if (type.IsInteger)
|
||||||
{
|
{
|
||||||
instruction = intInst;
|
instruction = intInst;
|
||||||
|
|
||||||
@@ -1009,7 +1009,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
{
|
{
|
||||||
uint instruction;
|
uint instruction;
|
||||||
|
|
||||||
if (type.IsInteger())
|
if (type.IsInteger)
|
||||||
{
|
{
|
||||||
instruction = intInst;
|
instruction = intInst;
|
||||||
|
|
||||||
|
|||||||
@@ -250,7 +250,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
// ValidateBinOp(dest, src1, src2);
|
// ValidateBinOp(dest, src1, src2);
|
||||||
|
|
||||||
if (dest.Type.IsInteger())
|
if (dest.Type.IsInteger)
|
||||||
{
|
{
|
||||||
context.Assembler.Add(dest, src1, src2);
|
context.Assembler.Add(dest, src1, src2);
|
||||||
}
|
}
|
||||||
@@ -268,7 +268,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
ValidateBinOp(dest, src1, src2);
|
ValidateBinOp(dest, src1, src2);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.And(dest, src1, src2);
|
context.Assembler.And(dest, src1, src2);
|
||||||
}
|
}
|
||||||
@@ -281,7 +281,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
ValidateBinOp(dest, src1, src2);
|
ValidateBinOp(dest, src1, src2);
|
||||||
|
|
||||||
if (dest.Type.IsInteger())
|
if (dest.Type.IsInteger)
|
||||||
{
|
{
|
||||||
context.Assembler.Eor(dest, src1, src2);
|
context.Assembler.Eor(dest, src1, src2);
|
||||||
}
|
}
|
||||||
@@ -298,7 +298,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
ValidateUnOp(dest, source);
|
ValidateUnOp(dest, source);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Mvn(dest, source);
|
context.Assembler.Mvn(dest, source);
|
||||||
}
|
}
|
||||||
@@ -311,7 +311,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
ValidateBinOp(dest, src1, src2);
|
ValidateBinOp(dest, src1, src2);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Orr(dest, src1, src2);
|
context.Assembler.Orr(dest, src1, src2);
|
||||||
}
|
}
|
||||||
@@ -322,7 +322,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
Debug.Assert(comp.Kind == OperandKind.Constant);
|
Debug.Assert(comp.Kind == OperandKind.Constant);
|
||||||
|
|
||||||
ArmCondition cond = ((Comparison)comp.AsInt32()).ToArmCondition();
|
ArmCondition cond = ((Comparison)comp.AsInt32()).Arm;
|
||||||
|
|
||||||
GenerateCompareCommon(context, operation);
|
GenerateCompareCommon(context, operation);
|
||||||
|
|
||||||
@@ -336,7 +336,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
ValidateUnOp(dest, source);
|
ValidateUnOp(dest, source);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Rev(dest, source);
|
context.Assembler.Rev(dest, source);
|
||||||
}
|
}
|
||||||
@@ -354,7 +354,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
Debug.Assert(dest.Type == OperandType.I32);
|
Debug.Assert(dest.Type == OperandType.I32);
|
||||||
Debug.Assert(comp.Kind == OperandKind.Constant);
|
Debug.Assert(comp.Kind == OperandKind.Constant);
|
||||||
|
|
||||||
ArmCondition cond = ((Comparison)comp.AsInt32()).ToArmCondition();
|
ArmCondition cond = ((Comparison)comp.AsInt32()).Arm;
|
||||||
|
|
||||||
GenerateCompareCommon(context, operation);
|
GenerateCompareCommon(context, operation);
|
||||||
|
|
||||||
@@ -428,7 +428,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
EnsureSameType(src1, src2);
|
EnsureSameType(src1, src2);
|
||||||
|
|
||||||
Debug.Assert(src1.Type.IsInteger());
|
Debug.Assert(src1.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Cmp(src1, src2);
|
context.Assembler.Cmp(src1, src2);
|
||||||
}
|
}
|
||||||
@@ -442,7 +442,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
EnsureSameType(dest, src2, src3);
|
EnsureSameType(dest, src2, src3);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger);
|
||||||
Debug.Assert(src1.Type == OperandType.I32);
|
Debug.Assert(src1.Type == OperandType.I32);
|
||||||
|
|
||||||
context.Assembler.Cmp(src1, Const(src1.Type, 0));
|
context.Assembler.Cmp(src1, Const(src1.Type, 0));
|
||||||
@@ -468,7 +468,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
Debug.Assert(dest.Type != source.Type);
|
Debug.Assert(dest.Type != source.Type);
|
||||||
Debug.Assert(source.Type != OperandType.V128);
|
Debug.Assert(source.Type != OperandType.V128);
|
||||||
|
|
||||||
if (source.Type.IsInteger())
|
if (source.Type.IsInteger)
|
||||||
{
|
{
|
||||||
context.Assembler.ScvtfScalar(dest, source);
|
context.Assembler.ScvtfScalar(dest, source);
|
||||||
}
|
}
|
||||||
@@ -485,7 +485,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
Debug.Assert(dest.Type is OperandType.FP32 or OperandType.FP64);
|
Debug.Assert(dest.Type is OperandType.FP32 or OperandType.FP64);
|
||||||
Debug.Assert(dest.Type != source.Type);
|
Debug.Assert(dest.Type != source.Type);
|
||||||
Debug.Assert(source.Type.IsInteger());
|
Debug.Assert(source.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.UcvtfScalar(dest, source);
|
context.Assembler.UcvtfScalar(dest, source);
|
||||||
}
|
}
|
||||||
@@ -497,7 +497,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
EnsureSameType(dest, source);
|
EnsureSameType(dest, source);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger() || source.Kind != OperandKind.Constant);
|
Debug.Assert(dest.Type.IsInteger || source.Kind != OperandKind.Constant);
|
||||||
|
|
||||||
// Moves to the same register are useless.
|
// Moves to the same register are useless.
|
||||||
if (dest.Kind == source.Kind && dest.Value == source.Value)
|
if (dest.Kind == source.Kind && dest.Value == source.Value)
|
||||||
@@ -529,7 +529,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
EnsureSameType(dest, source);
|
EnsureSameType(dest, source);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Clz(dest, source);
|
context.Assembler.Clz(dest, source);
|
||||||
}
|
}
|
||||||
@@ -542,7 +542,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
ValidateBinOp(dest, dividend, divisor);
|
ValidateBinOp(dest, dividend, divisor);
|
||||||
|
|
||||||
if (dest.Type.IsInteger())
|
if (dest.Type.IsInteger)
|
||||||
{
|
{
|
||||||
context.Assembler.Sdiv(dest, dividend, divisor);
|
context.Assembler.Sdiv(dest, dividend, divisor);
|
||||||
}
|
}
|
||||||
@@ -576,7 +576,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
Operand value = operation.Destination;
|
Operand value = operation.Destination;
|
||||||
Operand address = operation.GetSource(0);
|
Operand address = operation.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(value.Type.IsInteger());
|
Debug.Assert(value.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.LdrhRiUn(value, address, 0);
|
context.Assembler.LdrhRiUn(value, address, 0);
|
||||||
}
|
}
|
||||||
@@ -586,7 +586,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
Operand value = operation.Destination;
|
Operand value = operation.Destination;
|
||||||
Operand address = operation.GetSource(0);
|
Operand address = operation.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(value.Type.IsInteger());
|
Debug.Assert(value.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.LdrbRiUn(value, address, 0);
|
context.Assembler.LdrbRiUn(value, address, 0);
|
||||||
}
|
}
|
||||||
@@ -604,7 +604,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
EnsureSameType(dest, src1, src2);
|
EnsureSameType(dest, src1, src2);
|
||||||
|
|
||||||
if (dest.Type.IsInteger())
|
if (dest.Type.IsInteger)
|
||||||
{
|
{
|
||||||
context.Assembler.Mul(dest, src1, src2);
|
context.Assembler.Mul(dest, src1, src2);
|
||||||
}
|
}
|
||||||
@@ -647,7 +647,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
ValidateUnOp(dest, source);
|
ValidateUnOp(dest, source);
|
||||||
|
|
||||||
if (dest.Type.IsInteger())
|
if (dest.Type.IsInteger)
|
||||||
{
|
{
|
||||||
context.Assembler.Neg(dest, source);
|
context.Assembler.Neg(dest, source);
|
||||||
}
|
}
|
||||||
@@ -732,7 +732,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
Operand source = operation.GetSource(0);
|
Operand source = operation.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger && source.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Sxth(dest, source);
|
context.Assembler.Sxth(dest, source);
|
||||||
}
|
}
|
||||||
@@ -742,7 +742,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
Operand source = operation.GetSource(0);
|
Operand source = operation.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger && source.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Sxtw(dest, source);
|
context.Assembler.Sxtw(dest, source);
|
||||||
}
|
}
|
||||||
@@ -752,7 +752,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
Operand source = operation.GetSource(0);
|
Operand source = operation.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger && source.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Sxtb(dest, source);
|
context.Assembler.Sxtb(dest, source);
|
||||||
}
|
}
|
||||||
@@ -823,7 +823,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
Operand value = operation.GetSource(1);
|
Operand value = operation.GetSource(1);
|
||||||
Operand address = operation.GetSource(0);
|
Operand address = operation.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(value.Type.IsInteger());
|
Debug.Assert(value.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.StrhRiUn(value, address, 0);
|
context.Assembler.StrhRiUn(value, address, 0);
|
||||||
}
|
}
|
||||||
@@ -833,7 +833,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
Operand value = operation.GetSource(1);
|
Operand value = operation.GetSource(1);
|
||||||
Operand address = operation.GetSource(0);
|
Operand address = operation.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(value.Type.IsInteger());
|
Debug.Assert(value.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.StrbRiUn(value, address, 0);
|
context.Assembler.StrbRiUn(value, address, 0);
|
||||||
}
|
}
|
||||||
@@ -858,7 +858,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
// ValidateBinOp(dest, src1, src2);
|
// ValidateBinOp(dest, src1, src2);
|
||||||
|
|
||||||
if (dest.Type.IsInteger())
|
if (dest.Type.IsInteger)
|
||||||
{
|
{
|
||||||
context.Assembler.Sub(dest, src1, src2);
|
context.Assembler.Sub(dest, src1, src2);
|
||||||
}
|
}
|
||||||
@@ -882,7 +882,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
if (dest != default)
|
if (dest != default)
|
||||||
{
|
{
|
||||||
Debug.Assert(!dest.Type.IsInteger() && source.Type.IsInteger());
|
Debug.Assert(!dest.Type.IsInteger && source.Type.IsInteger);
|
||||||
|
|
||||||
OperandType destType = source.Type == OperandType.I64 ? OperandType.FP64 : OperandType.FP32;
|
OperandType destType = source.Type == OperandType.I64 ? OperandType.FP64 : OperandType.FP32;
|
||||||
|
|
||||||
@@ -901,9 +901,9 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
byte index = src2.AsByte();
|
byte index = src2.AsByte();
|
||||||
|
|
||||||
Debug.Assert(index < OperandType.V128.GetSizeInBytes() / dest.Type.GetSizeInBytes());
|
Debug.Assert(index < OperandType.V128.ByteSize / dest.Type.ByteSize);
|
||||||
|
|
||||||
if (dest.Type.IsInteger())
|
if (dest.Type.IsInteger)
|
||||||
{
|
{
|
||||||
context.Assembler.Umov(dest, src1, index, dest.Type == OperandType.I64 ? 3 : 2);
|
context.Assembler.Umov(dest, src1, index, dest.Type == OperandType.I64 ? 3 : 2);
|
||||||
}
|
}
|
||||||
@@ -959,7 +959,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
byte index = src3.AsByte();
|
byte index = src3.AsByte();
|
||||||
|
|
||||||
if (src2.Type.IsInteger())
|
if (src2.Type.IsInteger)
|
||||||
{
|
{
|
||||||
context.Assembler.Ins(dest, src2, index, src2.Type == OperandType.I64 ? 3 : 2);
|
context.Assembler.Ins(dest, src2, index, src2.Type == OperandType.I64 ? 3 : 2);
|
||||||
}
|
}
|
||||||
@@ -1007,7 +1007,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
{
|
{
|
||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
|
|
||||||
Debug.Assert(!dest.Type.IsInteger());
|
Debug.Assert(!dest.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.CmeqVector(dest, dest, dest, 2);
|
context.Assembler.CmeqVector(dest, dest, dest, 2);
|
||||||
}
|
}
|
||||||
@@ -1016,7 +1016,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
{
|
{
|
||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
|
|
||||||
Debug.Assert(!dest.Type.IsInteger());
|
Debug.Assert(!dest.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.EorVector(dest, dest, dest);
|
context.Assembler.EorVector(dest, dest, dest);
|
||||||
}
|
}
|
||||||
@@ -1046,7 +1046,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
Operand source = operation.GetSource(0);
|
Operand source = operation.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger && source.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Uxth(dest, source);
|
context.Assembler.Uxth(dest, source);
|
||||||
}
|
}
|
||||||
@@ -1056,7 +1056,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
Operand source = operation.GetSource(0);
|
Operand source = operation.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger && source.Type.IsInteger);
|
||||||
|
|
||||||
// We can eliminate the move if source is already 32-bit and the registers are the same.
|
// We can eliminate the move if source is already 32-bit and the registers are the same.
|
||||||
if (dest.Value == source.Value && source.Type == OperandType.I32)
|
if (dest.Value == source.Value && source.Type == OperandType.I32)
|
||||||
@@ -1072,7 +1072,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
Operand source = operation.GetSource(0);
|
Operand source = operation.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger && source.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Uxtb(dest, source);
|
context.Assembler.Uxtb(dest, source);
|
||||||
}
|
}
|
||||||
@@ -1169,7 +1169,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
context.Assembler.StrRiPre(Register(reg, type), Register(SpRegister), -calleeSaveRegionSize);
|
context.Assembler.StrRiPre(Register(reg, type), Register(SpRegister), -calleeSaveRegionSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
offset += type.GetSizeInBytes();
|
offset += type.ByteSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (mask != 0)
|
while (mask != 0)
|
||||||
@@ -1195,7 +1195,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
context.Assembler.StpRiPre(Register(reg, type), Register(reg2, type), Register(SpRegister), -calleeSaveRegionSize);
|
context.Assembler.StpRiPre(Register(reg, type), Register(reg2, type), Register(SpRegister), -calleeSaveRegionSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
offset += type.GetSizeInBytes() * 2;
|
offset += type.ByteSize * 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1273,7 +1273,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
mask &= ~(1 << reg2);
|
mask &= ~(1 << reg2);
|
||||||
|
|
||||||
offset -= type.GetSizeInBytes() * 2;
|
offset -= type.ByteSize * 2;
|
||||||
|
|
||||||
if (offset != 0)
|
if (offset != 0)
|
||||||
{
|
{
|
||||||
@@ -1286,7 +1286,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
offset -= type.GetSizeInBytes();
|
offset -= type.ByteSize;
|
||||||
|
|
||||||
if (offset != 0)
|
if (offset != 0)
|
||||||
{
|
{
|
||||||
@@ -1435,12 +1435,12 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
OperandType valueType = GetMemOpValueType(currentOp);
|
OperandType valueType = GetMemOpValueType(currentOp);
|
||||||
|
|
||||||
if (valueType != GetMemOpValueType(nextOp) || op1Offset + valueType.GetSizeInBytes() != op2Offset)
|
if (valueType != GetMemOpValueType(nextOp) || op1Offset + valueType.ByteSize != op2Offset)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CodeGenCommon.ConstFitsOnSImm7(op1Offset, valueType.GetSizeInBytesLog2()))
|
if (!CodeGenCommon.ConstFitsOnSImm7(op1Offset, valueType.ByteSizeLog2))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1549,7 +1549,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
// EnsureSameReg (dest, src1);
|
// EnsureSameReg (dest, src1);
|
||||||
EnsureSameType(dest, src1);
|
EnsureSameType(dest, src1);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger() && src2.Type == OperandType.I32);
|
Debug.Assert(dest.Type.IsInteger && src2.Type == OperandType.I32);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void EnsureSameReg(Operand op1, Operand op2)
|
private static void EnsureSameReg(Operand op1, Operand op2)
|
||||||
|
|||||||
@@ -462,7 +462,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
{
|
{
|
||||||
instruction |= (sz << 22);
|
instruction |= (sz << 22);
|
||||||
|
|
||||||
if (rd.Type.IsInteger())
|
if (rd.Type.IsInteger)
|
||||||
{
|
{
|
||||||
context.Assembler.WriteInstructionAuto(instruction, rd, rn);
|
context.Assembler.WriteInstructionAuto(instruction, rd, rn);
|
||||||
}
|
}
|
||||||
@@ -490,7 +490,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
instruction |= (sz << 22);
|
instruction |= (sz << 22);
|
||||||
instruction |= (64 - fBits) << 10;
|
instruction |= (64 - fBits) << 10;
|
||||||
|
|
||||||
if (rd.Type.IsInteger())
|
if (rd.Type.IsInteger)
|
||||||
{
|
{
|
||||||
Debug.Assert(rd.Type != OperandType.I32 || fBits <= 32);
|
Debug.Assert(rd.Type != OperandType.I32 || fBits <= 32);
|
||||||
|
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
if (src1.Kind == OperandKind.Constant)
|
if (src1.Kind == OperandKind.Constant)
|
||||||
{
|
{
|
||||||
if (!src1.Type.IsInteger())
|
if (!src1.Type.IsInteger)
|
||||||
{
|
{
|
||||||
// Handle non-integer types (FP32, FP64 and V128).
|
// Handle non-integer types (FP32, FP64 and V128).
|
||||||
// For instructions without an immediate operand, we do the following:
|
// For instructions without an immediate operand, we do the following:
|
||||||
@@ -161,7 +161,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
if (src2.Kind == OperandKind.Constant)
|
if (src2.Kind == OperandKind.Constant)
|
||||||
{
|
{
|
||||||
if (!src2.Type.IsInteger())
|
if (!src2.Type.IsInteger)
|
||||||
{
|
{
|
||||||
src2 = AddFloatConstantCopy(constants, nodes, node, src2);
|
src2 = AddFloatConstantCopy(constants, nodes, node, src2);
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
if (src.Kind == OperandKind.Constant)
|
if (src.Kind == OperandKind.Constant)
|
||||||
{
|
{
|
||||||
if (!src.Type.IsInteger())
|
if (!src.Type.IsInteger)
|
||||||
{
|
{
|
||||||
src = AddFloatConstantCopy(constants, nodes, node, src);
|
src = AddFloatConstantCopy(constants, nodes, node, src);
|
||||||
|
|
||||||
@@ -282,7 +282,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
bool passOnReg;
|
bool passOnReg;
|
||||||
|
|
||||||
if (source.Type.IsInteger())
|
if (source.Type.IsInteger)
|
||||||
{
|
{
|
||||||
passOnReg = intCount < intMax;
|
passOnReg = intCount < intMax;
|
||||||
}
|
}
|
||||||
@@ -309,7 +309,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
if (passOnReg)
|
if (passOnReg)
|
||||||
{
|
{
|
||||||
Operand argReg = source.Type.IsInteger()
|
Operand argReg = source.Type.IsInteger
|
||||||
? Gpr(CallingConvention.GetIntArgumentRegister(intCount++), source.Type)
|
? Gpr(CallingConvention.GetIntArgumentRegister(intCount++), source.Type)
|
||||||
: Xmm(CallingConvention.GetVecArgumentRegister(vecCount++), source.Type);
|
: Xmm(CallingConvention.GetVecArgumentRegister(vecCount++), source.Type);
|
||||||
|
|
||||||
@@ -327,7 +327,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
InsertConstantRegCopies(constants, nodes, nodes.AddBefore(node, spillOp));
|
InsertConstantRegCopies(constants, nodes, nodes.AddBefore(node, spillOp));
|
||||||
|
|
||||||
stackOffset += source.Type.GetSizeInBytes();
|
stackOffset += source.Type.ByteSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,7 +345,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Operand retReg = dest.Type.IsInteger()
|
Operand retReg = dest.Type.IsInteger
|
||||||
? Gpr(CallingConvention.GetIntReturnRegister(), dest.Type)
|
? Gpr(CallingConvention.GetIntReturnRegister(), dest.Type)
|
||||||
: Xmm(CallingConvention.GetVecReturnRegister(), dest.Type);
|
: Xmm(CallingConvention.GetVecReturnRegister(), dest.Type);
|
||||||
|
|
||||||
@@ -385,7 +385,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
bool passOnReg;
|
bool passOnReg;
|
||||||
|
|
||||||
if (source.Type.IsInteger())
|
if (source.Type.IsInteger)
|
||||||
{
|
{
|
||||||
passOnReg = intCount + 1 < intMax;
|
passOnReg = intCount + 1 < intMax;
|
||||||
}
|
}
|
||||||
@@ -408,7 +408,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
if (passOnReg)
|
if (passOnReg)
|
||||||
{
|
{
|
||||||
Operand argReg = source.Type.IsInteger()
|
Operand argReg = source.Type.IsInteger
|
||||||
? Gpr(CallingConvention.GetIntArgumentRegister(intCount++), source.Type)
|
? Gpr(CallingConvention.GetIntArgumentRegister(intCount++), source.Type)
|
||||||
: Xmm(CallingConvention.GetVecArgumentRegister(vecCount++), source.Type);
|
: Xmm(CallingConvention.GetVecArgumentRegister(vecCount++), source.Type);
|
||||||
|
|
||||||
@@ -521,7 +521,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Operand retReg = source.Type.IsInteger()
|
Operand retReg = source.Type.IsInteger
|
||||||
? Gpr(CallingConvention.GetIntReturnRegister(), source.Type)
|
? Gpr(CallingConvention.GetIntReturnRegister(), source.Type)
|
||||||
: Xmm(CallingConvention.GetVecReturnRegister(), source.Type);
|
: Xmm(CallingConvention.GetVecReturnRegister(), source.Type);
|
||||||
|
|
||||||
@@ -551,7 +551,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
{
|
{
|
||||||
OperandType argType = cctx.FuncArgTypes[cIndex];
|
OperandType argType = cctx.FuncArgTypes[cIndex];
|
||||||
|
|
||||||
if (argType.IsInteger())
|
if (argType.IsInteger)
|
||||||
{
|
{
|
||||||
intCount++;
|
intCount++;
|
||||||
}
|
}
|
||||||
@@ -567,7 +567,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
bool passOnReg;
|
bool passOnReg;
|
||||||
|
|
||||||
if (source.Type.IsInteger())
|
if (source.Type.IsInteger)
|
||||||
{
|
{
|
||||||
passOnReg = intCount < CallingConvention.GetArgumentsOnRegsCount();
|
passOnReg = intCount < CallingConvention.GetArgumentsOnRegsCount();
|
||||||
}
|
}
|
||||||
@@ -606,7 +606,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
{
|
{
|
||||||
Operand pArg = Local(dest.Type);
|
Operand pArg = Local(dest.Type);
|
||||||
|
|
||||||
Operand argReg = dest.Type.IsInteger()
|
Operand argReg = dest.Type.IsInteger
|
||||||
? Gpr(CallingConvention.GetIntArgumentRegister(intCount), dest.Type)
|
? Gpr(CallingConvention.GetIntArgumentRegister(intCount), dest.Type)
|
||||||
: Xmm(CallingConvention.GetVecArgumentRegister(vecCount), dest.Type);
|
: Xmm(CallingConvention.GetVecArgumentRegister(vecCount), dest.Type);
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
|||||||
if (trueSucc == block.ListNext)
|
if (trueSucc == block.ListNext)
|
||||||
{
|
{
|
||||||
Comparison comp = (Comparison)branchOp.GetSource(2).AsInt32();
|
Comparison comp = (Comparison)branchOp.GetSource(2).AsInt32();
|
||||||
Comparison compInv = comp.Invert();
|
Comparison compInv = comp.Inverse;
|
||||||
|
|
||||||
branchOp.SetSource(2, Const((int)compInv));
|
branchOp.SetSource(2, Const((int)compInv));
|
||||||
|
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
|||||||
}
|
}
|
||||||
else if (otherCompType == Comparison.Equal)
|
else if (otherCompType == Comparison.Equal)
|
||||||
{
|
{
|
||||||
propCompType = compType.Invert();
|
propCompType = compType.Inverse;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
|||||||
Operand x = operation.GetSource(0);
|
Operand x = operation.GetSource(0);
|
||||||
Operand y = operation.GetSource(1);
|
Operand y = operation.GetSource(1);
|
||||||
|
|
||||||
if (x == y && x.Type.IsInteger())
|
if (x == y && x.Type.IsInteger)
|
||||||
{
|
{
|
||||||
operation.TurnIntoCopy(Const(x.Type, 0));
|
operation.TurnIntoCopy(Const(x.Type, 0));
|
||||||
}
|
}
|
||||||
@@ -161,7 +161,7 @@ namespace ARMeilleure.CodeGen.Optimizations
|
|||||||
|
|
||||||
private static bool IsConstEqual(Operand operand, ulong comparand)
|
private static bool IsConstEqual(Operand operand, ulong comparand)
|
||||||
{
|
{
|
||||||
if (operand.Kind != OperandKind.Constant || !operand.Type.IsInteger())
|
if (operand.Kind != OperandKind.Constant || !operand.Type.IsInteger)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||||||
{
|
{
|
||||||
OperandType type = types[copyDest];
|
OperandType type = types[copyDest];
|
||||||
|
|
||||||
type = type.IsInteger() ? OperandType.I64 : OperandType.V128;
|
type = type.IsInteger ? OperandType.I64 : OperandType.V128;
|
||||||
|
|
||||||
EmitXorSwap(sequence, GetRegister(copyDest, type), GetRegister(copySource, type));
|
EmitXorSwap(sequence, GetRegister(copyDest, type), GetRegister(copySource, type));
|
||||||
|
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||||||
}
|
}
|
||||||
else if (dest.Kind == OperandKind.Register)
|
else if (dest.Kind == OperandKind.Register)
|
||||||
{
|
{
|
||||||
if (dest.Type.IsInteger())
|
if (dest.Type.IsInteger)
|
||||||
{
|
{
|
||||||
intFixedRegisters |= 1 << dest.GetRegister().Index;
|
intFixedRegisters |= 1 << dest.GetRegister().Index;
|
||||||
}
|
}
|
||||||
@@ -236,7 +236,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||||||
{
|
{
|
||||||
Register reg = info.Register.GetRegister();
|
Register reg = info.Register.GetRegister();
|
||||||
|
|
||||||
if (local.Type.IsInteger())
|
if (local.Type.IsInteger)
|
||||||
{
|
{
|
||||||
intLocalFreeRegisters |= 1 << reg.Index;
|
intLocalFreeRegisters |= 1 << reg.Index;
|
||||||
}
|
}
|
||||||
@@ -254,7 +254,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||||||
|
|
||||||
if (temp == default || info.Sequence != sequence)
|
if (temp == default || info.Sequence != sequence)
|
||||||
{
|
{
|
||||||
temp = local.Type.IsInteger()
|
temp = local.Type.IsInteger
|
||||||
? GetSpillTemp(local, intSpillTempRegisters, ref intLocalUse)
|
? GetSpillTemp(local, intSpillTempRegisters, ref intLocalUse)
|
||||||
: GetSpillTemp(local, vecSpillTempRegisters, ref vecLocalUse);
|
: GetSpillTemp(local, vecSpillTempRegisters, ref vecLocalUse);
|
||||||
|
|
||||||
@@ -335,7 +335,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||||||
|
|
||||||
if (info.UsesAllocated == 0)
|
if (info.UsesAllocated == 0)
|
||||||
{
|
{
|
||||||
int mask = dest.Type.IsInteger()
|
int mask = dest.Type.IsInteger
|
||||||
? intLocalFreeRegisters
|
? intLocalFreeRegisters
|
||||||
: vecLocalFreeRegisters;
|
: vecLocalFreeRegisters;
|
||||||
|
|
||||||
@@ -343,9 +343,9 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||||||
{
|
{
|
||||||
int selectedReg = BitOperations.TrailingZeroCount(mask);
|
int selectedReg = BitOperations.TrailingZeroCount(mask);
|
||||||
|
|
||||||
info.Register = Register(selectedReg, info.Type.ToRegisterType(), info.Type);
|
info.Register = Register(selectedReg, info.Type.Register, info.Type);
|
||||||
|
|
||||||
if (dest.Type.IsInteger())
|
if (dest.Type.IsInteger)
|
||||||
{
|
{
|
||||||
intLocalFreeRegisters &= ~(1 << selectedReg);
|
intLocalFreeRegisters &= ~(1 << selectedReg);
|
||||||
intUsedRegisters |= 1 << selectedReg;
|
intUsedRegisters |= 1 << selectedReg;
|
||||||
@@ -359,7 +359,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
info.Register = default;
|
info.Register = default;
|
||||||
info.SpillOffset = Const(stackAlloc.Allocate(dest.Type.GetSizeInBytes()));
|
info.SpillOffset = Const(stackAlloc.Allocate(dest.Type.ByteSize));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,7 +377,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||||||
|
|
||||||
if (temp == default || info.Sequence != sequence)
|
if (temp == default || info.Sequence != sequence)
|
||||||
{
|
{
|
||||||
temp = dest.Type.IsInteger()
|
temp = dest.Type.IsInteger
|
||||||
? GetSpillTemp(dest, intSpillTempRegisters, ref intLocalAsg)
|
? GetSpillTemp(dest, intSpillTempRegisters, ref intLocalAsg)
|
||||||
: GetSpillTemp(dest, vecSpillTempRegisters, ref vecLocalAsg);
|
: GetSpillTemp(dest, vecSpillTempRegisters, ref vecLocalAsg);
|
||||||
|
|
||||||
@@ -443,7 +443,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||||||
|
|
||||||
useMask |= 1 << selectedReg;
|
useMask |= 1 << selectedReg;
|
||||||
|
|
||||||
return Register(selectedReg, local.Type.ToRegisterType(), local.Type);
|
return Register(selectedReg, local.Type.Register, local.Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int UsesCount(Operand local)
|
private static int UsesCount(Operand local)
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||||||
|
|
||||||
private bool TryAllocateRegWithoutSpill(AllocationContext context, LiveInterval current, int cIndex, int registersCount)
|
private bool TryAllocateRegWithoutSpill(AllocationContext context, LiveInterval current, int cIndex, int registersCount)
|
||||||
{
|
{
|
||||||
RegisterType regType = current.Local.Type.ToRegisterType();
|
RegisterType regType = current.Local.Type.Register;
|
||||||
|
|
||||||
Span<int> freePositions = stackalloc int[registersCount];
|
Span<int> freePositions = stackalloc int[registersCount];
|
||||||
|
|
||||||
@@ -318,7 +318,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||||||
|
|
||||||
private void AllocateRegWithSpill(AllocationContext context, LiveInterval current, int cIndex, int registersCount)
|
private void AllocateRegWithSpill(AllocationContext context, LiveInterval current, int cIndex, int registersCount)
|
||||||
{
|
{
|
||||||
RegisterType regType = current.Local.Type.ToRegisterType();
|
RegisterType regType = current.Local.Type.Register;
|
||||||
|
|
||||||
Span<int> usePositions = stackalloc int[registersCount];
|
Span<int> usePositions = stackalloc int[registersCount];
|
||||||
Span<int> blockedPositions = stackalloc int[registersCount];
|
Span<int> blockedPositions = stackalloc int[registersCount];
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||||||
|
|
||||||
public int Allocate(OperandType type)
|
public int Allocate(OperandType type)
|
||||||
{
|
{
|
||||||
return Allocate(type.GetSizeInBytes());
|
return Allocate(type.ByteSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Allocate(int sizeInBytes)
|
public int Allocate(int sizeInBytes)
|
||||||
|
|||||||
@@ -385,7 +385,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
{
|
{
|
||||||
ref readonly InstructionInfo info = ref _instTable[(int)X86Instruction.Movd];
|
ref readonly InstructionInfo info = ref _instTable[(int)X86Instruction.Movd];
|
||||||
|
|
||||||
if (source.Type.IsInteger() || source.Kind == OperandKind.Memory)
|
if (source.Type.IsInteger || source.Kind == OperandKind.Memory)
|
||||||
{
|
{
|
||||||
WriteOpCode(dest, default, source, OperandType.None, info.Flags, info.OpRRM, rrm: true);
|
WriteOpCode(dest, default, source, OperandType.None, info.Flags, info.OpRRM, rrm: true);
|
||||||
}
|
}
|
||||||
@@ -416,11 +416,11 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
InstructionFlags flags = info.Flags | InstructionFlags.RexW;
|
InstructionFlags flags = info.Flags | InstructionFlags.RexW;
|
||||||
|
|
||||||
if (source.Type.IsInteger() || source.Kind == OperandKind.Memory)
|
if (source.Type.IsInteger || source.Kind == OperandKind.Memory)
|
||||||
{
|
{
|
||||||
WriteOpCode(dest, default, source, OperandType.None, flags, info.OpRRM, rrm: true);
|
WriteOpCode(dest, default, source, OperandType.None, flags, info.OpRRM, rrm: true);
|
||||||
}
|
}
|
||||||
else if (dest.Type.IsInteger() || dest.Kind == OperandKind.Memory)
|
else if (dest.Type.IsInteger || dest.Kind == OperandKind.Memory)
|
||||||
{
|
{
|
||||||
WriteOpCode(dest, default, source, OperandType.None, flags, info.OpRMR);
|
WriteOpCode(dest, default, source, OperandType.None, flags, info.OpRMR);
|
||||||
}
|
}
|
||||||
@@ -1107,17 +1107,17 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (flags.HasFlag(InstructionFlags.Prefix66))
|
if ((flags & InstructionFlags.Prefix66) != 0)
|
||||||
{
|
{
|
||||||
WriteByte(0x66);
|
WriteByte(0x66);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags.HasFlag(InstructionFlags.PrefixF2))
|
if ((flags & InstructionFlags.PrefixF2) != 0f)
|
||||||
{
|
{
|
||||||
WriteByte(0xf2);
|
WriteByte(0xf2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags.HasFlag(InstructionFlags.PrefixF3))
|
if ((flags & InstructionFlags.PrefixF3) != 0f)
|
||||||
{
|
{
|
||||||
WriteByte(0xf3);
|
WriteByte(0xf3);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace ARMeilleure.CodeGen.X86
|
namespace ARMeilleure.CodeGen.X86
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using ARMeilleure.CodeGen.RegisterAllocators;
|
|||||||
using ARMeilleure.IntermediateRepresentation;
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
using Microsoft.IO;
|
using Microsoft.IO;
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using System.IO;
|
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|
||||||
namespace ARMeilleure.CodeGen.X86
|
namespace ARMeilleure.CodeGen.X86
|
||||||
|
|||||||
@@ -289,7 +289,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
EnsureSameType(dest, source);
|
EnsureSameType(dest, source);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Popcnt(dest, source, dest.Type);
|
context.Assembler.Popcnt(dest, source, dest.Type);
|
||||||
|
|
||||||
@@ -303,7 +303,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
EnsureSameType(dest, source);
|
EnsureSameType(dest, source);
|
||||||
|
|
||||||
Debug.Assert(!dest.Type.IsInteger());
|
Debug.Assert(!dest.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.WriteInstruction(info.Inst, dest, source);
|
context.Assembler.WriteInstruction(info.Inst, dest, source);
|
||||||
|
|
||||||
@@ -315,7 +315,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
Operand source = operation.GetSource(0);
|
Operand source = operation.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger() && !source.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger && !source.Type.IsInteger);
|
||||||
|
|
||||||
if (operation.Intrinsic == Intrinsic.X86Cvtsi2si)
|
if (operation.Intrinsic == Intrinsic.X86Cvtsi2si)
|
||||||
{
|
{
|
||||||
@@ -349,8 +349,8 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
EnsureSameReg(dest, src1);
|
EnsureSameReg(dest, src1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.Assert(!dest.Type.IsInteger());
|
Debug.Assert(!dest.Type.IsInteger);
|
||||||
Debug.Assert(!src2.Type.IsInteger() || src2.Kind == OperandKind.Constant);
|
Debug.Assert(!src2.Type.IsInteger || src2.Kind == OperandKind.Constant);
|
||||||
|
|
||||||
context.Assembler.WriteInstruction(info.Inst, dest, src1, src2);
|
context.Assembler.WriteInstruction(info.Inst, dest, src1, src2);
|
||||||
|
|
||||||
@@ -370,7 +370,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
EnsureSameReg(dest, src1);
|
EnsureSameReg(dest, src1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.Assert(!dest.Type.IsInteger() && src2.Type.IsInteger());
|
Debug.Assert(!dest.Type.IsInteger && src2.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.WriteInstruction(info.Inst, dest, src1, src2, src2.Type);
|
context.Assembler.WriteInstruction(info.Inst, dest, src1, src2, src2.Type);
|
||||||
|
|
||||||
@@ -385,7 +385,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
EnsureSameReg(dest, src1);
|
EnsureSameReg(dest, src1);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger() && src1.Type.IsInteger() && src2.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger && src1.Type.IsInteger && src2.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.WriteInstruction(info.Inst, dest, src2, dest.Type);
|
context.Assembler.WriteInstruction(info.Inst, dest, src2, dest.Type);
|
||||||
|
|
||||||
@@ -405,7 +405,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
EnsureSameReg(dest, src1);
|
EnsureSameReg(dest, src1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.Assert(!dest.Type.IsInteger() && src2.Kind == OperandKind.Constant);
|
Debug.Assert(!dest.Type.IsInteger && src2.Kind == OperandKind.Constant);
|
||||||
|
|
||||||
context.Assembler.WriteInstruction(info.Inst, dest, src1, src2.AsByte());
|
context.Assembler.WriteInstruction(info.Inst, dest, src1, src2.AsByte());
|
||||||
|
|
||||||
@@ -421,7 +421,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
EnsureSameType(dest, src1, src2, src3);
|
EnsureSameType(dest, src1, src2, src3);
|
||||||
|
|
||||||
Debug.Assert(!dest.Type.IsInteger());
|
Debug.Assert(!dest.Type.IsInteger);
|
||||||
|
|
||||||
if (info.Inst == X86Instruction.Blendvpd && HardwareCapabilities.SupportsVexEncoding)
|
if (info.Inst == X86Instruction.Blendvpd && HardwareCapabilities.SupportsVexEncoding)
|
||||||
{
|
{
|
||||||
@@ -461,7 +461,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
EnsureSameReg(dest, src1);
|
EnsureSameReg(dest, src1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.Assert(!dest.Type.IsInteger() && src3.Kind == OperandKind.Constant);
|
Debug.Assert(!dest.Type.IsInteger && src3.Kind == OperandKind.Constant);
|
||||||
|
|
||||||
context.Assembler.WriteInstruction(info.Inst, dest, src1, src2, src3.AsByte());
|
context.Assembler.WriteInstruction(info.Inst, dest, src1, src2, src3.AsByte());
|
||||||
|
|
||||||
@@ -512,7 +512,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Operand src1 = operation.GetSource(0);
|
Operand src1 = operation.GetSource(0);
|
||||||
Operand src2 = operation.GetSource(1);
|
Operand src2 = operation.GetSource(1);
|
||||||
|
|
||||||
if (dest.Type.IsInteger())
|
if (dest.Type.IsInteger)
|
||||||
{
|
{
|
||||||
// If Destination and Source 1 Operands are the same, perform a standard add as there are no benefits to using LEA.
|
// If Destination and Source 1 Operands are the same, perform a standard add as there are no benefits to using LEA.
|
||||||
if (dest.Kind == src1.Kind && dest.Value == src1.Value)
|
if (dest.Kind == src1.Kind && dest.Value == src1.Value)
|
||||||
@@ -567,7 +567,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
ValidateBinOp(dest, src1, src2);
|
ValidateBinOp(dest, src1, src2);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger);
|
||||||
|
|
||||||
// Note: GenerateCompareCommon makes the assumption that BitwiseAnd will emit only a single `and`
|
// Note: GenerateCompareCommon makes the assumption that BitwiseAnd will emit only a single `and`
|
||||||
// instruction.
|
// instruction.
|
||||||
@@ -582,7 +582,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
ValidateBinOp(dest, src1, src2);
|
ValidateBinOp(dest, src1, src2);
|
||||||
|
|
||||||
if (dest.Type.IsInteger())
|
if (dest.Type.IsInteger)
|
||||||
{
|
{
|
||||||
context.Assembler.Xor(dest, src2, dest.Type);
|
context.Assembler.Xor(dest, src2, dest.Type);
|
||||||
}
|
}
|
||||||
@@ -599,7 +599,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
ValidateUnOp(dest, source);
|
ValidateUnOp(dest, source);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Not(dest);
|
context.Assembler.Not(dest);
|
||||||
}
|
}
|
||||||
@@ -612,7 +612,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
ValidateBinOp(dest, src1, src2);
|
ValidateBinOp(dest, src1, src2);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Or(dest, src2, dest.Type);
|
context.Assembler.Or(dest, src2, dest.Type);
|
||||||
}
|
}
|
||||||
@@ -623,7 +623,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
Debug.Assert(comp.Kind == OperandKind.Constant);
|
Debug.Assert(comp.Kind == OperandKind.Constant);
|
||||||
|
|
||||||
X86Condition cond = ((Comparison)comp.AsInt32()).ToX86Condition();
|
X86Condition cond = ((Comparison)comp.AsInt32()).X86;
|
||||||
|
|
||||||
GenerateCompareCommon(context, operation);
|
GenerateCompareCommon(context, operation);
|
||||||
|
|
||||||
@@ -637,7 +637,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
ValidateUnOp(dest, source);
|
ValidateUnOp(dest, source);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Bswap(dest);
|
context.Assembler.Bswap(dest);
|
||||||
}
|
}
|
||||||
@@ -661,7 +661,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Debug.Assert(dest.Type == OperandType.I32);
|
Debug.Assert(dest.Type == OperandType.I32);
|
||||||
Debug.Assert(comp.Kind == OperandKind.Constant);
|
Debug.Assert(comp.Kind == OperandKind.Constant);
|
||||||
|
|
||||||
X86Condition cond = ((Comparison)comp.AsInt32()).ToX86Condition();
|
X86Condition cond = ((Comparison)comp.AsInt32()).X86;
|
||||||
|
|
||||||
GenerateCompareCommon(context, operation);
|
GenerateCompareCommon(context, operation);
|
||||||
|
|
||||||
@@ -676,7 +676,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
EnsureSameType(src1, src2);
|
EnsureSameType(src1, src2);
|
||||||
|
|
||||||
Debug.Assert(src1.Type.IsInteger());
|
Debug.Assert(src1.Type.IsInteger);
|
||||||
|
|
||||||
if (src2.Kind == OperandKind.Constant && src2.Value == 0)
|
if (src2.Kind == OperandKind.Constant && src2.Value == 0)
|
||||||
{
|
{
|
||||||
@@ -766,7 +766,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
EnsureSameReg(dest, src3);
|
EnsureSameReg(dest, src3);
|
||||||
EnsureSameType(dest, src2, src3);
|
EnsureSameType(dest, src2, src3);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger);
|
||||||
Debug.Assert(src1.Type == OperandType.I32);
|
Debug.Assert(src1.Type == OperandType.I32);
|
||||||
|
|
||||||
context.Assembler.Test(src1, src1, src1.Type);
|
context.Assembler.Test(src1, src1, src1.Type);
|
||||||
@@ -792,9 +792,9 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
if (dest.Type == OperandType.FP32)
|
if (dest.Type == OperandType.FP32)
|
||||||
{
|
{
|
||||||
Debug.Assert(source.Type.IsInteger() || source.Type == OperandType.FP64);
|
Debug.Assert(source.Type.IsInteger || source.Type == OperandType.FP64);
|
||||||
|
|
||||||
if (source.Type.IsInteger())
|
if (source.Type.IsInteger)
|
||||||
{
|
{
|
||||||
context.Assembler.Xorps(dest, dest, dest);
|
context.Assembler.Xorps(dest, dest, dest);
|
||||||
context.Assembler.Cvtsi2ss(dest, dest, source, source.Type);
|
context.Assembler.Cvtsi2ss(dest, dest, source, source.Type);
|
||||||
@@ -808,9 +808,9 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
}
|
}
|
||||||
else /* if (dest.Type == OperandType.FP64) */
|
else /* if (dest.Type == OperandType.FP64) */
|
||||||
{
|
{
|
||||||
Debug.Assert(source.Type.IsInteger() || source.Type == OperandType.FP32);
|
Debug.Assert(source.Type.IsInteger || source.Type == OperandType.FP32);
|
||||||
|
|
||||||
if (source.Type.IsInteger())
|
if (source.Type.IsInteger)
|
||||||
{
|
{
|
||||||
context.Assembler.Xorps(dest, dest, dest);
|
context.Assembler.Xorps(dest, dest, dest);
|
||||||
context.Assembler.Cvtsi2sd(dest, dest, source, source.Type);
|
context.Assembler.Cvtsi2sd(dest, dest, source, source.Type);
|
||||||
@@ -831,7 +831,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
EnsureSameType(dest, source);
|
EnsureSameType(dest, source);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger() || source.Kind != OperandKind.Constant);
|
Debug.Assert(dest.Type.IsInteger || source.Kind != OperandKind.Constant);
|
||||||
|
|
||||||
// Moves to the same register are useless.
|
// Moves to the same register are useless.
|
||||||
if (dest.Kind == source.Kind && dest.Value == source.Value)
|
if (dest.Kind == source.Kind && dest.Value == source.Value)
|
||||||
@@ -845,7 +845,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
// Assemble "mov reg, 0" as "xor reg, reg" as the later is more efficient.
|
// Assemble "mov reg, 0" as "xor reg, reg" as the later is more efficient.
|
||||||
context.Assembler.Xor(dest, dest, OperandType.I32);
|
context.Assembler.Xor(dest, dest, OperandType.I32);
|
||||||
}
|
}
|
||||||
else if (dest.Type.IsInteger())
|
else if (dest.Type.IsInteger)
|
||||||
{
|
{
|
||||||
context.Assembler.Mov(dest, source, dest.Type);
|
context.Assembler.Mov(dest, source, dest.Type);
|
||||||
}
|
}
|
||||||
@@ -862,7 +862,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
EnsureSameType(dest, source);
|
EnsureSameType(dest, source);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Bsr(dest, source, dest.Type);
|
context.Assembler.Bsr(dest, source, dest.Type);
|
||||||
|
|
||||||
@@ -894,12 +894,12 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Operand dividend = operation.GetSource(0);
|
Operand dividend = operation.GetSource(0);
|
||||||
Operand divisor = operation.GetSource(1);
|
Operand divisor = operation.GetSource(1);
|
||||||
|
|
||||||
if (!dest.Type.IsInteger())
|
if (!dest.Type.IsInteger)
|
||||||
{
|
{
|
||||||
ValidateBinOp(dest, dividend, divisor);
|
ValidateBinOp(dest, dividend, divisor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dest.Type.IsInteger())
|
if (dest.Type.IsInteger)
|
||||||
{
|
{
|
||||||
divisor = operation.GetSource(2);
|
divisor = operation.GetSource(2);
|
||||||
|
|
||||||
@@ -932,7 +932,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
Operand rdx = Register(X86Register.Rdx);
|
Operand rdx = Register(X86Register.Rdx);
|
||||||
|
|
||||||
Debug.Assert(divisor.Type.IsInteger());
|
Debug.Assert(divisor.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Xor(rdx, rdx, OperandType.I32);
|
context.Assembler.Xor(rdx, rdx, OperandType.I32);
|
||||||
context.Assembler.Div(divisor);
|
context.Assembler.Div(divisor);
|
||||||
@@ -967,7 +967,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Operand value = operation.Destination;
|
Operand value = operation.Destination;
|
||||||
Operand address = Memory(operation.GetSource(0), value.Type);
|
Operand address = Memory(operation.GetSource(0), value.Type);
|
||||||
|
|
||||||
Debug.Assert(value.Type.IsInteger());
|
Debug.Assert(value.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Movzx16(value, address, value.Type);
|
context.Assembler.Movzx16(value, address, value.Type);
|
||||||
}
|
}
|
||||||
@@ -977,7 +977,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Operand value = operation.Destination;
|
Operand value = operation.Destination;
|
||||||
Operand address = Memory(operation.GetSource(0), value.Type);
|
Operand address = Memory(operation.GetSource(0), value.Type);
|
||||||
|
|
||||||
Debug.Assert(value.Type.IsInteger());
|
Debug.Assert(value.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Movzx8(value, address, value.Type);
|
context.Assembler.Movzx8(value, address, value.Type);
|
||||||
}
|
}
|
||||||
@@ -1000,7 +1000,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
EnsureSameType(dest, src1, src2);
|
EnsureSameType(dest, src1, src2);
|
||||||
|
|
||||||
if (dest.Type.IsInteger())
|
if (dest.Type.IsInteger)
|
||||||
{
|
{
|
||||||
if (src2.Kind == OperandKind.Constant)
|
if (src2.Kind == OperandKind.Constant)
|
||||||
{
|
{
|
||||||
@@ -1046,7 +1046,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
ValidateUnOp(dest, source);
|
ValidateUnOp(dest, source);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Neg(dest);
|
context.Assembler.Neg(dest);
|
||||||
}
|
}
|
||||||
@@ -1107,7 +1107,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
Operand source = operation.GetSource(0);
|
Operand source = operation.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger && source.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Movsx16(dest, source, dest.Type);
|
context.Assembler.Movsx16(dest, source, dest.Type);
|
||||||
}
|
}
|
||||||
@@ -1117,7 +1117,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
Operand source = operation.GetSource(0);
|
Operand source = operation.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger && source.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Movsx32(dest, source, dest.Type);
|
context.Assembler.Movsx32(dest, source, dest.Type);
|
||||||
}
|
}
|
||||||
@@ -1127,7 +1127,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
Operand source = operation.GetSource(0);
|
Operand source = operation.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger && source.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Movsx8(dest, source, dest.Type);
|
context.Assembler.Movsx8(dest, source, dest.Type);
|
||||||
}
|
}
|
||||||
@@ -1187,7 +1187,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Operand value = operation.GetSource(1);
|
Operand value = operation.GetSource(1);
|
||||||
Operand address = Memory(operation.GetSource(0), value.Type);
|
Operand address = Memory(operation.GetSource(0), value.Type);
|
||||||
|
|
||||||
Debug.Assert(value.Type.IsInteger());
|
Debug.Assert(value.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Mov16(address, value);
|
context.Assembler.Mov16(address, value);
|
||||||
}
|
}
|
||||||
@@ -1197,7 +1197,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Operand value = operation.GetSource(1);
|
Operand value = operation.GetSource(1);
|
||||||
Operand address = Memory(operation.GetSource(0), value.Type);
|
Operand address = Memory(operation.GetSource(0), value.Type);
|
||||||
|
|
||||||
Debug.Assert(value.Type.IsInteger());
|
Debug.Assert(value.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Mov8(address, value);
|
context.Assembler.Mov8(address, value);
|
||||||
}
|
}
|
||||||
@@ -1210,7 +1210,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
ValidateBinOp(dest, src1, src2);
|
ValidateBinOp(dest, src1, src2);
|
||||||
|
|
||||||
if (dest.Type.IsInteger())
|
if (dest.Type.IsInteger)
|
||||||
{
|
{
|
||||||
context.Assembler.Sub(dest, src2, dest.Type);
|
context.Assembler.Sub(dest, src2, dest.Type);
|
||||||
}
|
}
|
||||||
@@ -1236,7 +1236,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
Operand source = operation.GetSource(0);
|
Operand source = operation.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(!dest.Type.IsInteger() && source.Type.IsInteger());
|
Debug.Assert(!dest.Type.IsInteger && source.Type.IsInteger);
|
||||||
|
|
||||||
if (source.Type == OperandType.I32)
|
if (source.Type == OperandType.I32)
|
||||||
{
|
{
|
||||||
@@ -1259,7 +1259,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
byte index = src2.AsByte();
|
byte index = src2.AsByte();
|
||||||
|
|
||||||
Debug.Assert(index < OperandType.V128.GetSizeInBytes() / dest.Type.GetSizeInBytes());
|
Debug.Assert(index < OperandType.V128.ByteSize / dest.Type.ByteSize);
|
||||||
|
|
||||||
if (dest.Type == OperandType.I32)
|
if (dest.Type == OperandType.I32)
|
||||||
{
|
{
|
||||||
@@ -1541,7 +1541,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
{
|
{
|
||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
|
|
||||||
Debug.Assert(!dest.Type.IsInteger());
|
Debug.Assert(!dest.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Pcmpeqw(dest, dest, dest);
|
context.Assembler.Pcmpeqw(dest, dest, dest);
|
||||||
}
|
}
|
||||||
@@ -1550,7 +1550,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
{
|
{
|
||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
|
|
||||||
Debug.Assert(!dest.Type.IsInteger());
|
Debug.Assert(!dest.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Xorps(dest, dest, dest);
|
context.Assembler.Xorps(dest, dest, dest);
|
||||||
}
|
}
|
||||||
@@ -1580,7 +1580,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
Operand source = operation.GetSource(0);
|
Operand source = operation.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger && source.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Movzx16(dest, source, OperandType.I32);
|
context.Assembler.Movzx16(dest, source, OperandType.I32);
|
||||||
}
|
}
|
||||||
@@ -1590,7 +1590,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
Operand source = operation.GetSource(0);
|
Operand source = operation.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger && source.Type.IsInteger);
|
||||||
|
|
||||||
// We can eliminate the move if source is already 32-bit and the registers are the same.
|
// We can eliminate the move if source is already 32-bit and the registers are the same.
|
||||||
if (dest.Value == source.Value && source.Type == OperandType.I32)
|
if (dest.Value == source.Value && source.Type == OperandType.I32)
|
||||||
@@ -1606,7 +1606,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
Operand source = operation.GetSource(0);
|
Operand source = operation.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
|
Debug.Assert(dest.Type.IsInteger && source.Type.IsInteger);
|
||||||
|
|
||||||
context.Assembler.Movzx8(dest, source, OperandType.I32);
|
context.Assembler.Movzx8(dest, source, OperandType.I32);
|
||||||
}
|
}
|
||||||
@@ -1713,12 +1713,12 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
EnsureSameReg(dest, src1);
|
EnsureSameReg(dest, src1);
|
||||||
EnsureSameType(dest, src1);
|
EnsureSameType(dest, src1);
|
||||||
|
|
||||||
Debug.Assert(dest.Type.IsInteger() && src2.Type == OperandType.I32);
|
Debug.Assert(dest.Type.IsInteger && src2.Type == OperandType.I32);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void EnsureSameReg(Operand op1, Operand op2)
|
private static void EnsureSameReg(Operand op1, Operand op2)
|
||||||
{
|
{
|
||||||
if (!op1.Type.IsInteger() && HardwareCapabilities.SupportsVexEncoding)
|
if (!op1.Type.IsInteger && HardwareCapabilities.SupportsVexEncoding)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.Negate:
|
case Instruction.Negate:
|
||||||
if (!node.GetSource(0).Type.IsInteger())
|
if (!node.GetSource(0).Type.IsInteger)
|
||||||
{
|
{
|
||||||
GenerateNegate(block.Operations, node);
|
GenerateNegate(block.Operations, node);
|
||||||
}
|
}
|
||||||
@@ -159,7 +159,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
if (src1.Kind == OperandKind.Constant)
|
if (src1.Kind == OperandKind.Constant)
|
||||||
{
|
{
|
||||||
if (!src1.Type.IsInteger())
|
if (!src1.Type.IsInteger)
|
||||||
{
|
{
|
||||||
// Handle non-integer types (FP32, FP64 and V128).
|
// Handle non-integer types (FP32, FP64 and V128).
|
||||||
// For instructions without an immediate operand, we do the following:
|
// For instructions without an immediate operand, we do the following:
|
||||||
@@ -208,7 +208,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
if (src2.Kind == OperandKind.Constant)
|
if (src2.Kind == OperandKind.Constant)
|
||||||
{
|
{
|
||||||
if (!src2.Type.IsInteger())
|
if (!src2.Type.IsInteger)
|
||||||
{
|
{
|
||||||
src2 = AddXmmCopy(nodes, node, src2);
|
src2 = AddXmmCopy(nodes, node, src2);
|
||||||
|
|
||||||
@@ -298,7 +298,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
// - The dividend is always in RDX:RAX.
|
// - The dividend is always in RDX:RAX.
|
||||||
// - The result is always in RAX.
|
// - The result is always in RAX.
|
||||||
// - Additionally it also writes the remainder in RDX.
|
// - Additionally it also writes the remainder in RDX.
|
||||||
if (dest.Type.IsInteger())
|
if (dest.Type.IsInteger)
|
||||||
{
|
{
|
||||||
Operand src1 = node.GetSource(0);
|
Operand src1 = node.GetSource(0);
|
||||||
|
|
||||||
@@ -466,7 +466,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Operand dest = node.Destination;
|
Operand dest = node.Destination;
|
||||||
Operand source = node.GetSource(0);
|
Operand source = node.GetSource(0);
|
||||||
|
|
||||||
Debug.Assert(source.Type.IsInteger(), $"Invalid source type \"{source.Type}\".");
|
Debug.Assert(source.Type.IsInteger, $"Invalid source type \"{source.Type}\".");
|
||||||
|
|
||||||
Operation currentNode = node;
|
Operation currentNode = node;
|
||||||
|
|
||||||
@@ -654,10 +654,10 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
switch (operation.Instruction)
|
switch (operation.Instruction)
|
||||||
{
|
{
|
||||||
case Instruction.Add:
|
case Instruction.Add:
|
||||||
return !HardwareCapabilities.SupportsVexEncoding && !operation.Destination.Type.IsInteger();
|
return !HardwareCapabilities.SupportsVexEncoding && !operation.Destination.Type.IsInteger;
|
||||||
case Instruction.Multiply:
|
case Instruction.Multiply:
|
||||||
case Instruction.Subtract:
|
case Instruction.Subtract:
|
||||||
return !HardwareCapabilities.SupportsVexEncoding || operation.Destination.Type.IsInteger();
|
return !HardwareCapabilities.SupportsVexEncoding || operation.Destination.Type.IsInteger;
|
||||||
|
|
||||||
case Instruction.BitwiseAnd:
|
case Instruction.BitwiseAnd:
|
||||||
case Instruction.BitwiseExclusiveOr:
|
case Instruction.BitwiseExclusiveOr:
|
||||||
@@ -672,7 +672,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Instruction.Divide:
|
case Instruction.Divide:
|
||||||
return !HardwareCapabilities.SupportsVexEncoding && !operation.Destination.Type.IsInteger();
|
return !HardwareCapabilities.SupportsVexEncoding && !operation.Destination.Type.IsInteger;
|
||||||
|
|
||||||
case Instruction.VectorInsert:
|
case Instruction.VectorInsert:
|
||||||
case Instruction.VectorInsert16:
|
case Instruction.VectorInsert16:
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
bool passOnReg;
|
bool passOnReg;
|
||||||
|
|
||||||
if (source.Type.IsInteger())
|
if (source.Type.IsInteger)
|
||||||
{
|
{
|
||||||
passOnReg = intCount < intMax;
|
passOnReg = intCount < intMax;
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
if (passOnReg)
|
if (passOnReg)
|
||||||
{
|
{
|
||||||
Operand argReg = source.Type.IsInteger()
|
Operand argReg = source.Type.IsInteger
|
||||||
? Gpr(CallingConvention.GetIntArgumentRegister(intCount++), source.Type)
|
? Gpr(CallingConvention.GetIntArgumentRegister(intCount++), source.Type)
|
||||||
: Xmm(CallingConvention.GetVecArgumentRegister(vecCount++), source.Type);
|
: Xmm(CallingConvention.GetVecArgumentRegister(vecCount++), source.Type);
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
InsertConstantRegCopies(nodes, nodes.AddBefore(node, spillOp));
|
InsertConstantRegCopies(nodes, nodes.AddBefore(node, spillOp));
|
||||||
|
|
||||||
stackOffset += source.Type.GetSizeInBytes();
|
stackOffset += source.Type.ByteSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Operand retReg = dest.Type.IsInteger()
|
Operand retReg = dest.Type.IsInteger
|
||||||
? Gpr(CallingConvention.GetIntReturnRegister(), dest.Type)
|
? Gpr(CallingConvention.GetIntReturnRegister(), dest.Type)
|
||||||
: Xmm(CallingConvention.GetVecReturnRegister(), dest.Type);
|
: Xmm(CallingConvention.GetVecReturnRegister(), dest.Type);
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
bool passOnReg;
|
bool passOnReg;
|
||||||
|
|
||||||
if (source.Type.IsInteger())
|
if (source.Type.IsInteger)
|
||||||
{
|
{
|
||||||
passOnReg = intCount + 1 < intMax;
|
passOnReg = intCount + 1 < intMax;
|
||||||
}
|
}
|
||||||
@@ -160,7 +160,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
if (passOnReg)
|
if (passOnReg)
|
||||||
{
|
{
|
||||||
Operand argReg = source.Type.IsInteger()
|
Operand argReg = source.Type.IsInteger
|
||||||
? Gpr(CallingConvention.GetIntArgumentRegister(intCount++), source.Type)
|
? Gpr(CallingConvention.GetIntArgumentRegister(intCount++), source.Type)
|
||||||
: Xmm(CallingConvention.GetVecArgumentRegister(vecCount++), source.Type);
|
: Xmm(CallingConvention.GetVecArgumentRegister(vecCount++), source.Type);
|
||||||
|
|
||||||
@@ -210,7 +210,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
{
|
{
|
||||||
OperandType argType = cctx.FuncArgTypes[cIndex];
|
OperandType argType = cctx.FuncArgTypes[cIndex];
|
||||||
|
|
||||||
if (argType.IsInteger())
|
if (argType.IsInteger)
|
||||||
{
|
{
|
||||||
intCount++;
|
intCount++;
|
||||||
}
|
}
|
||||||
@@ -226,7 +226,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
bool passOnReg;
|
bool passOnReg;
|
||||||
|
|
||||||
if (source.Type.IsInteger())
|
if (source.Type.IsInteger)
|
||||||
{
|
{
|
||||||
passOnReg = intCount < CallingConvention.GetIntArgumentsOnRegsCount();
|
passOnReg = intCount < CallingConvention.GetIntArgumentsOnRegsCount();
|
||||||
}
|
}
|
||||||
@@ -265,7 +265,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
{
|
{
|
||||||
Operand pArg = Local(dest.Type);
|
Operand pArg = Local(dest.Type);
|
||||||
|
|
||||||
Operand argReg = dest.Type.IsInteger()
|
Operand argReg = dest.Type.IsInteger
|
||||||
? Gpr(CallingConvention.GetIntArgumentRegister(intCount), dest.Type)
|
? Gpr(CallingConvention.GetIntArgumentRegister(intCount), dest.Type)
|
||||||
: Xmm(CallingConvention.GetVecArgumentRegister(vecCount), dest.Type);
|
: Xmm(CallingConvention.GetVecArgumentRegister(vecCount), dest.Type);
|
||||||
|
|
||||||
@@ -320,7 +320,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Operand retReg = source.Type.IsInteger()
|
Operand retReg = source.Type.IsInteger
|
||||||
? Gpr(CallingConvention.GetIntReturnRegister(), source.Type)
|
? Gpr(CallingConvention.GetIntReturnRegister(), source.Type)
|
||||||
: Xmm(CallingConvention.GetVecReturnRegister(), source.Type);
|
: Xmm(CallingConvention.GetVecReturnRegister(), source.Type);
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
if (dest != default && dest.Type == OperandType.V128)
|
if (dest != default && dest.Type == OperandType.V128)
|
||||||
{
|
{
|
||||||
int stackOffset = AllocateOnStack(dest.Type.GetSizeInBytes());
|
int stackOffset = AllocateOnStack(dest.Type.ByteSize);
|
||||||
|
|
||||||
arg0Reg = Gpr(CallingConvention.GetIntArgumentRegister(0), OperandType.I64);
|
arg0Reg = Gpr(CallingConvention.GetIntArgumentRegister(0), OperandType.I64);
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
{
|
{
|
||||||
Operand stackAddr = Local(OperandType.I64);
|
Operand stackAddr = Local(OperandType.I64);
|
||||||
|
|
||||||
int stackOffset = AllocateOnStack(source.Type.GetSizeInBytes());
|
int stackOffset = AllocateOnStack(source.Type.ByteSize);
|
||||||
|
|
||||||
nodes.AddBefore(node, Operation(Instruction.StackAlloc, stackAddr, Const(stackOffset)));
|
nodes.AddBefore(node, Operation(Instruction.StackAlloc, stackAddr, Const(stackOffset)));
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
int argIndex = index + retArgs;
|
int argIndex = index + retArgs;
|
||||||
|
|
||||||
if (source.Type.IsInteger())
|
if (source.Type.IsInteger)
|
||||||
{
|
{
|
||||||
argReg = Gpr(CallingConvention.GetIntArgumentRegister(argIndex), source.Type);
|
argReg = Gpr(CallingConvention.GetIntArgumentRegister(argIndex), source.Type);
|
||||||
}
|
}
|
||||||
@@ -140,7 +140,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Operand retReg = dest.Type.IsInteger()
|
Operand retReg = dest.Type.IsInteger
|
||||||
? Gpr(CallingConvention.GetIntReturnRegister(), dest.Type)
|
? Gpr(CallingConvention.GetIntReturnRegister(), dest.Type)
|
||||||
: Xmm(CallingConvention.GetVecReturnRegister(), dest.Type);
|
: Xmm(CallingConvention.GetVecReturnRegister(), dest.Type);
|
||||||
|
|
||||||
@@ -171,7 +171,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
for (int index = 0; index < argsCount; index++)
|
for (int index = 0; index < argsCount; index++)
|
||||||
{
|
{
|
||||||
Operand source = node.GetSource(1 + index);
|
Operand source = node.GetSource(1 + index);
|
||||||
Operand argReg = source.Type.IsInteger()
|
Operand argReg = source.Type.IsInteger
|
||||||
? Gpr(CallingConvention.GetIntArgumentRegister(index), source.Type)
|
? Gpr(CallingConvention.GetIntArgumentRegister(index), source.Type)
|
||||||
: Xmm(CallingConvention.GetVecArgumentRegister(index), source.Type);
|
: Xmm(CallingConvention.GetVecArgumentRegister(index), source.Type);
|
||||||
|
|
||||||
@@ -219,7 +219,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
{
|
{
|
||||||
Operand argReg, pArg;
|
Operand argReg, pArg;
|
||||||
|
|
||||||
if (dest.Type.IsInteger())
|
if (dest.Type.IsInteger)
|
||||||
{
|
{
|
||||||
argReg = Gpr(CallingConvention.GetIntArgumentRegister(index), dest.Type);
|
argReg = Gpr(CallingConvention.GetIntArgumentRegister(index), dest.Type);
|
||||||
pArg = Local(dest.Type);
|
pArg = Local(dest.Type);
|
||||||
@@ -283,7 +283,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Operand source = node.GetSource(0);
|
Operand source = node.GetSource(0);
|
||||||
Operand retReg;
|
Operand retReg;
|
||||||
|
|
||||||
if (source.Type.IsInteger())
|
if (source.Type.IsInteger)
|
||||||
{
|
{
|
||||||
retReg = Gpr(CallingConvention.GetIntReturnRegister(), source.Type);
|
retReg = Gpr(CallingConvention.GetIntReturnRegister(), source.Type);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
static class ComparisonX86Extensions
|
static class ComparisonX86Extensions
|
||||||
{
|
{
|
||||||
public static X86Condition ToX86Condition(this Comparison comp)
|
extension(Comparison comparison)
|
||||||
{
|
{
|
||||||
return comp switch
|
public X86Condition X86 => comparison switch
|
||||||
{
|
{
|
||||||
#pragma warning disable IDE0055 // Disable formatting
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
Comparison.Equal => X86Condition.Equal,
|
Comparison.Equal => X86Condition.Equal,
|
||||||
@@ -42,7 +42,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Comparison.LessUI => X86Condition.Below,
|
Comparison.LessUI => X86Condition.Below,
|
||||||
#pragma warning restore IDE0055
|
#pragma warning restore IDE0055
|
||||||
|
|
||||||
_ => throw new ArgumentException(null, nameof(comp)),
|
_ => throw new ArgumentException(null, nameof(comparison))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace ARMeilleure.CodeGen.X86
|
namespace ARMeilleure.CodeGen.X86
|
||||||
{
|
{
|
||||||
enum X86Register
|
enum X86Register
|
||||||
|
|||||||
@@ -22,11 +22,11 @@ namespace ARMeilleure.Decoders
|
|||||||
|
|
||||||
static class ConditionExtensions
|
static class ConditionExtensions
|
||||||
{
|
{
|
||||||
public static Condition Invert(this Condition cond)
|
extension(Condition condition)
|
||||||
{
|
{
|
||||||
// Bit 0 of all conditions is basically a negation bit, so
|
// Bit 0 of all conditions is basically a negation bit, so
|
||||||
// inverting this bit has the effect of inverting the condition.
|
// inverting this bit has the effect of inverting the condition.
|
||||||
return (Condition)((int)cond ^ 1);
|
public Condition Inverse => (Condition)((int)condition ^ 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
context.LoadFromContext();
|
context.LoadFromContext();
|
||||||
|
|
||||||
context.Return(Const(op.Address));
|
InstEmitFlowHelper.EmitReturn(context, Const(op.Address));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Svc(ArmEmitterContext context)
|
public static void Svc(ArmEmitterContext context)
|
||||||
@@ -49,7 +49,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
context.LoadFromContext();
|
context.LoadFromContext();
|
||||||
|
|
||||||
context.Return(Const(op.Address));
|
InstEmitFlowHelper.EmitReturn(context, Const(op.Address));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
context.LoadFromContext();
|
context.LoadFromContext();
|
||||||
|
|
||||||
context.Return(Const(context.CurrOp.Address));
|
InstEmitFlowHelper.EmitReturn(context, Const(context.CurrOp.Address));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
OpCodeBReg op = (OpCodeBReg)context.CurrOp;
|
OpCodeBReg op = (OpCodeBReg)context.CurrOp;
|
||||||
|
|
||||||
context.Return(GetIntOrZR(context, op.Rn));
|
EmitReturn(context, GetIntOrZR(context, op.Rn));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Tbnz(ArmEmitterContext context) => EmitTb(context, onNotZero: true);
|
public static void Tbnz(ArmEmitterContext context) => EmitTb(context, onNotZero: true);
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
static class InstEmitFlowHelper
|
static class InstEmitFlowHelper
|
||||||
{
|
{
|
||||||
|
// How many calls we can have in our call stack before we give up and return to the dispatcher.
|
||||||
|
// This prevents stack overflows caused by deep recursive calls.
|
||||||
|
private const int MaxCallDepth = 200;
|
||||||
|
|
||||||
public static void EmitCondBranch(ArmEmitterContext context, Operand target, Condition cond)
|
public static void EmitCondBranch(ArmEmitterContext context, Operand target, Condition cond)
|
||||||
{
|
{
|
||||||
if (cond != Condition.Al)
|
if (cond != Condition.Al)
|
||||||
@@ -182,12 +186,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
if (isReturn || context.IsSingleStep)
|
if (isReturn || context.IsSingleStep)
|
||||||
{
|
{
|
||||||
if (target.Type == OperandType.I32)
|
EmitReturn(context, target);
|
||||||
{
|
|
||||||
target = context.ZeroExtend32(OperandType.I64, target);
|
|
||||||
}
|
|
||||||
|
|
||||||
context.Return(target);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -195,6 +194,19 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void EmitReturn(ArmEmitterContext context, Operand target)
|
||||||
|
{
|
||||||
|
Operand nativeContext = context.LoadArgument(OperandType.I64, 0);
|
||||||
|
DecreaseCallDepth(context, nativeContext);
|
||||||
|
|
||||||
|
if (target.Type == OperandType.I32)
|
||||||
|
{
|
||||||
|
target = context.ZeroExtend32(OperandType.I64, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Return(target);
|
||||||
|
}
|
||||||
|
|
||||||
private static void EmitTableBranch(ArmEmitterContext context, Operand guestAddress, bool isJump)
|
private static void EmitTableBranch(ArmEmitterContext context, Operand guestAddress, bool isJump)
|
||||||
{
|
{
|
||||||
context.StoreToContext();
|
context.StoreToContext();
|
||||||
@@ -257,6 +269,8 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
if (isJump)
|
if (isJump)
|
||||||
{
|
{
|
||||||
|
DecreaseCallDepth(context, nativeContext);
|
||||||
|
|
||||||
context.Tailcall(hostAddress, nativeContext);
|
context.Tailcall(hostAddress, nativeContext);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -278,8 +292,42 @@ namespace ARMeilleure.Instructions
|
|||||||
Operand lblContinue = context.GetLabel(nextAddr.Value);
|
Operand lblContinue = context.GetLabel(nextAddr.Value);
|
||||||
context.BranchIf(lblContinue, returnAddress, nextAddr, Comparison.Equal, BasicBlockFrequency.Cold);
|
context.BranchIf(lblContinue, returnAddress, nextAddr, Comparison.Equal, BasicBlockFrequency.Cold);
|
||||||
|
|
||||||
|
DecreaseCallDepth(context, nativeContext);
|
||||||
|
|
||||||
context.Return(returnAddress);
|
context.Return(returnAddress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void EmitCallDepthCheckAndIncrement(EmitterContext context, Operand guestAddress)
|
||||||
|
{
|
||||||
|
if (!Optimizations.EnableDeepCallRecursionProtection)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Operand nativeContext = context.LoadArgument(OperandType.I64, 0);
|
||||||
|
Operand callDepthAddr = context.Add(nativeContext, Const((ulong)NativeContext.GetCallDepthOffset()));
|
||||||
|
Operand currentCallDepth = context.Load(OperandType.I32, callDepthAddr);
|
||||||
|
Operand lblDoCall = Label();
|
||||||
|
|
||||||
|
context.BranchIf(lblDoCall, currentCallDepth, Const(MaxCallDepth), Comparison.LessUI);
|
||||||
|
context.Store(callDepthAddr, context.Subtract(currentCallDepth, Const(1)));
|
||||||
|
context.Return(guestAddress);
|
||||||
|
|
||||||
|
context.MarkLabel(lblDoCall);
|
||||||
|
context.Store(callDepthAddr, context.Add(currentCallDepth, Const(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DecreaseCallDepth(EmitterContext context, Operand nativeContext)
|
||||||
|
{
|
||||||
|
if (!Optimizations.EnableDeepCallRecursionProtection)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Operand callDepthAddr = context.Add(nativeContext, Const((ulong)NativeContext.GetCallDepthOffset()));
|
||||||
|
Operand currentCallDepth = context.Load(OperandType.I32, callDepthAddr);
|
||||||
|
context.Store(callDepthAddr, context.Subtract(currentCallDepth, Const(1)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
public static Operand EmitCrc32(ArmEmitterContext context, Operand crc, Operand value, int size, bool castagnoli)
|
public static Operand EmitCrc32(ArmEmitterContext context, Operand crc, Operand value, int size, bool castagnoli)
|
||||||
{
|
{
|
||||||
Debug.Assert(crc.Type.IsInteger() && value.Type.IsInteger());
|
Debug.Assert(crc.Type.IsInteger && value.Type.IsInteger);
|
||||||
Debug.Assert(size is >= 0 and < 4);
|
Debug.Assert(size is >= 0 and < 4);
|
||||||
Debug.Assert((size < 3) || (value.Type == OperandType.I64));
|
Debug.Assert((size < 3) || (value.Type == OperandType.I64));
|
||||||
|
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
context.Copy(temp, value);
|
context.Copy(temp, value);
|
||||||
|
|
||||||
if (!context.Memory.Type.IsHostMappedOrTracked())
|
if (!context.Memory.Type.IsHostMappedOrTracked)
|
||||||
{
|
{
|
||||||
context.Branch(lblEnd);
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
SetInt(context, rt, value);
|
SetInt(context, rt, value);
|
||||||
|
|
||||||
if (!context.Memory.Type.IsHostMappedOrTracked())
|
if (!context.Memory.Type.IsHostMappedOrTracked)
|
||||||
{
|
{
|
||||||
context.Branch(lblEnd);
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
@@ -265,7 +265,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
context.Copy(GetVec(rt), value);
|
context.Copy(GetVec(rt), value);
|
||||||
|
|
||||||
if (!context.Memory.Type.IsHostMappedOrTracked())
|
if (!context.Memory.Type.IsHostMappedOrTracked)
|
||||||
{
|
{
|
||||||
context.Branch(lblEnd);
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
@@ -312,7 +312,7 @@ namespace ARMeilleure.Instructions
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!context.Memory.Type.IsHostMappedOrTracked())
|
if (!context.Memory.Type.IsHostMappedOrTracked)
|
||||||
{
|
{
|
||||||
context.Branch(lblEnd);
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
@@ -385,7 +385,7 @@ namespace ARMeilleure.Instructions
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!context.Memory.Type.IsHostMappedOrTracked())
|
if (!context.Memory.Type.IsHostMappedOrTracked)
|
||||||
{
|
{
|
||||||
context.Branch(lblEnd);
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
@@ -399,11 +399,11 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
public static Operand EmitPtPointerLoad(ArmEmitterContext context, Operand address, Operand lblSlowPath, bool write, int size)
|
public static Operand EmitPtPointerLoad(ArmEmitterContext context, Operand address, Operand lblSlowPath, bool write, int size)
|
||||||
{
|
{
|
||||||
if (context.Memory.Type.IsHostMapped())
|
if (context.Memory.Type.IsHostMapped)
|
||||||
{
|
{
|
||||||
return EmitHostMappedPointer(context, address);
|
return EmitHostMappedPointer(context, address);
|
||||||
}
|
}
|
||||||
else if (context.Memory.Type.IsHostTracked())
|
else if (context.Memory.Type.IsHostTracked)
|
||||||
{
|
{
|
||||||
if (address.Type == OperandType.I32)
|
if (address.Type == OperandType.I32)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using ARMeilleure.Decoders;
|
|||||||
using ARMeilleure.IntermediateRepresentation;
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
using ARMeilleure.Translation;
|
using ARMeilleure.Translation;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||||
|
|
||||||
namespace ARMeilleure.Instructions
|
namespace ARMeilleure.Instructions
|
||||||
|
|||||||
@@ -201,11 +201,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
ExecutionContext context = GetContext();
|
ExecutionContext context = GetContext();
|
||||||
|
|
||||||
// If debugging, we'll handle interrupts outside
|
context.CheckInterrupt();
|
||||||
if (!Optimizations.EnableDebugging)
|
|
||||||
{
|
|
||||||
context.CheckInterrupt();
|
|
||||||
}
|
|
||||||
|
|
||||||
Statistics.ResumeTimer();
|
Statistics.ResumeTimer();
|
||||||
|
|
||||||
|
|||||||
@@ -1,692 +0,0 @@
|
|||||||
using ARMeilleure.State;
|
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace ARMeilleure.Instructions
|
|
||||||
{
|
|
||||||
static class SoftFallback
|
|
||||||
{
|
|
||||||
#region "ShrImm64"
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static long SignedShrImm64(long value, long roundConst, int shift)
|
|
||||||
{
|
|
||||||
if (roundConst == 0L)
|
|
||||||
{
|
|
||||||
if (shift <= 63)
|
|
||||||
{
|
|
||||||
return value >> shift;
|
|
||||||
}
|
|
||||||
else /* if (shift == 64) */
|
|
||||||
{
|
|
||||||
if (value < 0L)
|
|
||||||
{
|
|
||||||
return -1L;
|
|
||||||
}
|
|
||||||
else /* if (value >= 0L) */
|
|
||||||
{
|
|
||||||
return 0L;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else /* if (roundConst == 1L << (shift - 1)) */
|
|
||||||
{
|
|
||||||
if (shift <= 63)
|
|
||||||
{
|
|
||||||
long add = value + roundConst;
|
|
||||||
|
|
||||||
if ((~value & (value ^ add)) < 0L)
|
|
||||||
{
|
|
||||||
return (long)((ulong)add >> shift);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return add >> shift;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else /* if (shift == 64) */
|
|
||||||
{
|
|
||||||
return 0L;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static ulong UnsignedShrImm64(ulong value, long roundConst, int shift)
|
|
||||||
{
|
|
||||||
if (roundConst == 0L)
|
|
||||||
{
|
|
||||||
if (shift <= 63)
|
|
||||||
{
|
|
||||||
return value >> shift;
|
|
||||||
}
|
|
||||||
else /* if (shift == 64) */
|
|
||||||
{
|
|
||||||
return 0UL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else /* if (roundConst == 1L << (shift - 1)) */
|
|
||||||
{
|
|
||||||
ulong add = value + (ulong)roundConst;
|
|
||||||
|
|
||||||
if ((add < value) && (add < (ulong)roundConst))
|
|
||||||
{
|
|
||||||
if (shift <= 63)
|
|
||||||
{
|
|
||||||
return (add >> shift) | (0x8000000000000000UL >> (shift - 1));
|
|
||||||
}
|
|
||||||
else /* if (shift == 64) */
|
|
||||||
{
|
|
||||||
return 1UL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (shift <= 63)
|
|
||||||
{
|
|
||||||
return add >> shift;
|
|
||||||
}
|
|
||||||
else /* if (shift == 64) */
|
|
||||||
{
|
|
||||||
return 0UL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region "Saturation"
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static int SatF32ToS32(float value)
|
|
||||||
{
|
|
||||||
if (float.IsNaN(value))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value >= int.MaxValue ? int.MaxValue :
|
|
||||||
value <= int.MinValue ? int.MinValue : (int)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static long SatF32ToS64(float value)
|
|
||||||
{
|
|
||||||
if (float.IsNaN(value))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value >= long.MaxValue ? long.MaxValue :
|
|
||||||
value <= long.MinValue ? long.MinValue : (long)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static uint SatF32ToU32(float value)
|
|
||||||
{
|
|
||||||
if (float.IsNaN(value))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value >= uint.MaxValue ? uint.MaxValue :
|
|
||||||
value <= uint.MinValue ? uint.MinValue : (uint)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static ulong SatF32ToU64(float value)
|
|
||||||
{
|
|
||||||
if (float.IsNaN(value))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value >= ulong.MaxValue ? ulong.MaxValue :
|
|
||||||
value <= ulong.MinValue ? ulong.MinValue : (ulong)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static int SatF64ToS32(double value)
|
|
||||||
{
|
|
||||||
if (double.IsNaN(value))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value >= int.MaxValue ? int.MaxValue :
|
|
||||||
value <= int.MinValue ? int.MinValue : (int)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static long SatF64ToS64(double value)
|
|
||||||
{
|
|
||||||
if (double.IsNaN(value))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value >= long.MaxValue ? long.MaxValue :
|
|
||||||
value <= long.MinValue ? long.MinValue : (long)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static uint SatF64ToU32(double value)
|
|
||||||
{
|
|
||||||
if (double.IsNaN(value))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value >= uint.MaxValue ? uint.MaxValue :
|
|
||||||
value <= uint.MinValue ? uint.MinValue : (uint)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static ulong SatF64ToU64(double value)
|
|
||||||
{
|
|
||||||
if (double.IsNaN(value))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value >= ulong.MaxValue ? ulong.MaxValue :
|
|
||||||
value <= ulong.MinValue ? ulong.MinValue : (ulong)value;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region "Count"
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static ulong CountLeadingSigns(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
|
|
||||||
{
|
|
||||||
value ^= value >> 1;
|
|
||||||
|
|
||||||
int highBit = size - 2;
|
|
||||||
|
|
||||||
for (int bit = highBit; bit >= 0; bit--)
|
|
||||||
{
|
|
||||||
if (((int)(value >> bit) & 0b1) != 0)
|
|
||||||
{
|
|
||||||
return (ulong)(highBit - bit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (ulong)(size - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ReadOnlySpan<byte> ClzNibbleTbl => [4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static ulong CountLeadingZeros(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
|
|
||||||
{
|
|
||||||
if (value == 0ul)
|
|
||||||
{
|
|
||||||
return (ulong)size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int nibbleIdx = size;
|
|
||||||
int preCount, count = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
nibbleIdx -= 4;
|
|
||||||
preCount = ClzNibbleTbl[(int)(value >> nibbleIdx) & 0b1111];
|
|
||||||
count += preCount;
|
|
||||||
}
|
|
||||||
while (preCount == 4);
|
|
||||||
|
|
||||||
return (ulong)count;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region "Table"
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 Tbl1(V128 vector, int bytes, V128 tb0)
|
|
||||||
{
|
|
||||||
return TblOrTbx(default, vector, bytes, tb0);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 Tbl2(V128 vector, int bytes, V128 tb0, V128 tb1)
|
|
||||||
{
|
|
||||||
return TblOrTbx(default, vector, bytes, tb0, tb1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 Tbl3(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2)
|
|
||||||
{
|
|
||||||
return TblOrTbx(default, vector, bytes, tb0, tb1, tb2);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 Tbl4(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3)
|
|
||||||
{
|
|
||||||
return TblOrTbx(default, vector, bytes, tb0, tb1, tb2, tb3);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 Tbx1(V128 dest, V128 vector, int bytes, V128 tb0)
|
|
||||||
{
|
|
||||||
return TblOrTbx(dest, vector, bytes, tb0);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 Tbx2(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1)
|
|
||||||
{
|
|
||||||
return TblOrTbx(dest, vector, bytes, tb0, tb1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 Tbx3(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2)
|
|
||||||
{
|
|
||||||
return TblOrTbx(dest, vector, bytes, tb0, tb1, tb2);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 Tbx4(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3)
|
|
||||||
{
|
|
||||||
return TblOrTbx(dest, vector, bytes, tb0, tb1, tb2, tb3);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static V128 TblOrTbx(V128 dest, V128 vector, int bytes, params ReadOnlySpan<V128> tb)
|
|
||||||
{
|
|
||||||
byte[] res = new byte[16];
|
|
||||||
|
|
||||||
if (dest != default)
|
|
||||||
{
|
|
||||||
Buffer.BlockCopy(dest.ToArray(), 0, res, 0, bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] table = new byte[tb.Length * 16];
|
|
||||||
|
|
||||||
for (byte index = 0; index < tb.Length; index++)
|
|
||||||
{
|
|
||||||
Buffer.BlockCopy(tb[index].ToArray(), 0, table, index * 16, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] v = vector.ToArray();
|
|
||||||
|
|
||||||
for (byte index = 0; index < bytes; index++)
|
|
||||||
{
|
|
||||||
byte tblIndex = v[index];
|
|
||||||
|
|
||||||
if (tblIndex < table.Length)
|
|
||||||
{
|
|
||||||
res[index] = table[tblIndex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new V128(res);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region "Crc32"
|
|
||||||
private const uint Crc32RevPoly = 0xedb88320;
|
|
||||||
private const uint Crc32cRevPoly = 0x82f63b78;
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static uint Crc32b(uint crc, byte value) => Crc32(crc, Crc32RevPoly, value);
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static uint Crc32h(uint crc, ushort value) => Crc32h(crc, Crc32RevPoly, value);
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static uint Crc32w(uint crc, uint value) => Crc32w(crc, Crc32RevPoly, value);
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static uint Crc32x(uint crc, ulong value) => Crc32x(crc, Crc32RevPoly, value);
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static uint Crc32cb(uint crc, byte value) => Crc32(crc, Crc32cRevPoly, value);
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static uint Crc32ch(uint crc, ushort value) => Crc32h(crc, Crc32cRevPoly, value);
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static uint Crc32cw(uint crc, uint value) => Crc32w(crc, Crc32cRevPoly, value);
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static uint Crc32cx(uint crc, ulong value) => Crc32x(crc, Crc32cRevPoly, value);
|
|
||||||
|
|
||||||
private static uint Crc32h(uint crc, uint poly, ushort val)
|
|
||||||
{
|
|
||||||
crc = Crc32(crc, poly, (byte)(val >> 0));
|
|
||||||
crc = Crc32(crc, poly, (byte)(val >> 8));
|
|
||||||
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static uint Crc32w(uint crc, uint poly, uint val)
|
|
||||||
{
|
|
||||||
crc = Crc32(crc, poly, (byte)(val >> 0));
|
|
||||||
crc = Crc32(crc, poly, (byte)(val >> 8));
|
|
||||||
crc = Crc32(crc, poly, (byte)(val >> 16));
|
|
||||||
crc = Crc32(crc, poly, (byte)(val >> 24));
|
|
||||||
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static uint Crc32x(uint crc, uint poly, ulong val)
|
|
||||||
{
|
|
||||||
crc = Crc32(crc, poly, (byte)(val >> 0));
|
|
||||||
crc = Crc32(crc, poly, (byte)(val >> 8));
|
|
||||||
crc = Crc32(crc, poly, (byte)(val >> 16));
|
|
||||||
crc = Crc32(crc, poly, (byte)(val >> 24));
|
|
||||||
crc = Crc32(crc, poly, (byte)(val >> 32));
|
|
||||||
crc = Crc32(crc, poly, (byte)(val >> 40));
|
|
||||||
crc = Crc32(crc, poly, (byte)(val >> 48));
|
|
||||||
crc = Crc32(crc, poly, (byte)(val >> 56));
|
|
||||||
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static uint Crc32(uint crc, uint poly, byte val)
|
|
||||||
{
|
|
||||||
crc ^= val;
|
|
||||||
|
|
||||||
for (int bit = 7; bit >= 0; bit--)
|
|
||||||
{
|
|
||||||
uint mask = (uint)(-(int)(crc & 1));
|
|
||||||
|
|
||||||
crc = (crc >> 1) ^ (poly & mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region "Aes"
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 Decrypt(V128 value, V128 roundKey)
|
|
||||||
{
|
|
||||||
return CryptoHelper.AesInvSubBytes(CryptoHelper.AesInvShiftRows(value ^ roundKey));
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 Encrypt(V128 value, V128 roundKey)
|
|
||||||
{
|
|
||||||
return CryptoHelper.AesSubBytes(CryptoHelper.AesShiftRows(value ^ roundKey));
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 InverseMixColumns(V128 value)
|
|
||||||
{
|
|
||||||
return CryptoHelper.AesInvMixColumns(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 MixColumns(V128 value)
|
|
||||||
{
|
|
||||||
return CryptoHelper.AesMixColumns(value);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region "Sha1"
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 HashChoose(V128 hash_abcd, uint hash_e, V128 wk)
|
|
||||||
{
|
|
||||||
for (int e = 0; e <= 3; e++)
|
|
||||||
{
|
|
||||||
uint t = ShaChoose(hash_abcd.Extract<uint>(1),
|
|
||||||
hash_abcd.Extract<uint>(2),
|
|
||||||
hash_abcd.Extract<uint>(3));
|
|
||||||
|
|
||||||
hash_e += Rol(hash_abcd.Extract<uint>(0), 5) + t + wk.Extract<uint>(e);
|
|
||||||
|
|
||||||
t = Rol(hash_abcd.Extract<uint>(1), 30);
|
|
||||||
|
|
||||||
hash_abcd.Insert(1, t);
|
|
||||||
|
|
||||||
Rol32_160(ref hash_e, ref hash_abcd);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash_abcd;
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static uint FixedRotate(uint hash_e)
|
|
||||||
{
|
|
||||||
return hash_e.Rol(30);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 HashMajority(V128 hash_abcd, uint hash_e, V128 wk)
|
|
||||||
{
|
|
||||||
for (int e = 0; e <= 3; e++)
|
|
||||||
{
|
|
||||||
uint t = ShaMajority(hash_abcd.Extract<uint>(1),
|
|
||||||
hash_abcd.Extract<uint>(2),
|
|
||||||
hash_abcd.Extract<uint>(3));
|
|
||||||
|
|
||||||
hash_e += Rol(hash_abcd.Extract<uint>(0), 5) + t + wk.Extract<uint>(e);
|
|
||||||
|
|
||||||
t = Rol(hash_abcd.Extract<uint>(1), 30);
|
|
||||||
|
|
||||||
hash_abcd.Insert(1, t);
|
|
||||||
|
|
||||||
Rol32_160(ref hash_e, ref hash_abcd);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash_abcd;
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 HashParity(V128 hash_abcd, uint hash_e, V128 wk)
|
|
||||||
{
|
|
||||||
for (int e = 0; e <= 3; e++)
|
|
||||||
{
|
|
||||||
uint t = ShaParity(hash_abcd.Extract<uint>(1),
|
|
||||||
hash_abcd.Extract<uint>(2),
|
|
||||||
hash_abcd.Extract<uint>(3));
|
|
||||||
|
|
||||||
hash_e += Rol(hash_abcd.Extract<uint>(0), 5) + t + wk.Extract<uint>(e);
|
|
||||||
|
|
||||||
t = Rol(hash_abcd.Extract<uint>(1), 30);
|
|
||||||
|
|
||||||
hash_abcd.Insert(1, t);
|
|
||||||
|
|
||||||
Rol32_160(ref hash_e, ref hash_abcd);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash_abcd;
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 Sha1SchedulePart1(V128 w0_3, V128 w4_7, V128 w8_11)
|
|
||||||
{
|
|
||||||
ulong t2 = w4_7.Extract<ulong>(0);
|
|
||||||
ulong t1 = w0_3.Extract<ulong>(1);
|
|
||||||
|
|
||||||
V128 result = new(t1, t2);
|
|
||||||
|
|
||||||
return result ^ (w0_3 ^ w8_11);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 Sha1SchedulePart2(V128 tw0_3, V128 w12_15)
|
|
||||||
{
|
|
||||||
V128 t = tw0_3 ^ (w12_15 >> 32);
|
|
||||||
|
|
||||||
uint tE0 = t.Extract<uint>(0);
|
|
||||||
uint tE1 = t.Extract<uint>(1);
|
|
||||||
uint tE2 = t.Extract<uint>(2);
|
|
||||||
uint tE3 = t.Extract<uint>(3);
|
|
||||||
|
|
||||||
return new V128(tE0.Rol(1), tE1.Rol(1), tE2.Rol(1), tE3.Rol(1) ^ tE0.Rol(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void Rol32_160(ref uint y, ref V128 x)
|
|
||||||
{
|
|
||||||
uint xE3 = x.Extract<uint>(3);
|
|
||||||
|
|
||||||
x <<= 32;
|
|
||||||
x.Insert(0, y);
|
|
||||||
|
|
||||||
y = xE3;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static uint ShaChoose(uint x, uint y, uint z)
|
|
||||||
{
|
|
||||||
return ((y ^ z) & x) ^ z;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static uint ShaMajority(uint x, uint y, uint z)
|
|
||||||
{
|
|
||||||
return (x & y) | ((x | y) & z);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static uint ShaParity(uint x, uint y, uint z)
|
|
||||||
{
|
|
||||||
return x ^ y ^ z;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static uint Rol(this uint value, int count)
|
|
||||||
{
|
|
||||||
return (value << count) | (value >> (32 - count));
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region "Sha256"
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 HashLower(V128 hash_abcd, V128 hash_efgh, V128 wk)
|
|
||||||
{
|
|
||||||
return Sha256Hash(hash_abcd, hash_efgh, wk, part1: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 HashUpper(V128 hash_abcd, V128 hash_efgh, V128 wk)
|
|
||||||
{
|
|
||||||
return Sha256Hash(hash_abcd, hash_efgh, wk, part1: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 Sha256SchedulePart1(V128 w0_3, V128 w4_7)
|
|
||||||
{
|
|
||||||
V128 result = new();
|
|
||||||
|
|
||||||
for (int e = 0; e <= 3; e++)
|
|
||||||
{
|
|
||||||
uint elt = (e <= 2 ? w0_3 : w4_7).Extract<uint>(e <= 2 ? e + 1 : 0);
|
|
||||||
|
|
||||||
elt = elt.Ror(7) ^ elt.Ror(18) ^ elt.Lsr(3);
|
|
||||||
|
|
||||||
elt += w0_3.Extract<uint>(e);
|
|
||||||
|
|
||||||
result.Insert(e, elt);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 Sha256SchedulePart2(V128 w0_3, V128 w8_11, V128 w12_15)
|
|
||||||
{
|
|
||||||
V128 result = new();
|
|
||||||
|
|
||||||
ulong t1 = w12_15.Extract<ulong>(1);
|
|
||||||
|
|
||||||
for (int e = 0; e <= 1; e++)
|
|
||||||
{
|
|
||||||
uint elt = t1.ULongPart(e);
|
|
||||||
|
|
||||||
elt = elt.Ror(17) ^ elt.Ror(19) ^ elt.Lsr(10);
|
|
||||||
|
|
||||||
elt += w0_3.Extract<uint>(e) + w8_11.Extract<uint>(e + 1);
|
|
||||||
|
|
||||||
result.Insert(e, elt);
|
|
||||||
}
|
|
||||||
|
|
||||||
t1 = result.Extract<ulong>(0);
|
|
||||||
|
|
||||||
for (int e = 2; e <= 3; e++)
|
|
||||||
{
|
|
||||||
uint elt = t1.ULongPart(e - 2);
|
|
||||||
|
|
||||||
elt = elt.Ror(17) ^ elt.Ror(19) ^ elt.Lsr(10);
|
|
||||||
|
|
||||||
elt += w0_3.Extract<uint>(e) + (e == 2 ? w8_11 : w12_15).Extract<uint>(e == 2 ? 3 : 0);
|
|
||||||
|
|
||||||
result.Insert(e, elt);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static V128 Sha256Hash(V128 x, V128 y, V128 w, bool part1)
|
|
||||||
{
|
|
||||||
for (int e = 0; e <= 3; e++)
|
|
||||||
{
|
|
||||||
uint chs = ShaChoose(y.Extract<uint>(0),
|
|
||||||
y.Extract<uint>(1),
|
|
||||||
y.Extract<uint>(2));
|
|
||||||
|
|
||||||
uint maj = ShaMajority(x.Extract<uint>(0),
|
|
||||||
x.Extract<uint>(1),
|
|
||||||
x.Extract<uint>(2));
|
|
||||||
|
|
||||||
uint t1 = y.Extract<uint>(3) + ShaHashSigma1(y.Extract<uint>(0)) + chs + w.Extract<uint>(e);
|
|
||||||
|
|
||||||
uint t2 = t1 + x.Extract<uint>(3);
|
|
||||||
|
|
||||||
x.Insert(3, t2);
|
|
||||||
|
|
||||||
t2 = t1 + ShaHashSigma0(x.Extract<uint>(0)) + maj;
|
|
||||||
|
|
||||||
y.Insert(3, t2);
|
|
||||||
|
|
||||||
Rol32_256(ref y, ref x);
|
|
||||||
}
|
|
||||||
|
|
||||||
return part1 ? x : y;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void Rol32_256(ref V128 y, ref V128 x)
|
|
||||||
{
|
|
||||||
uint yE3 = y.Extract<uint>(3);
|
|
||||||
uint xE3 = x.Extract<uint>(3);
|
|
||||||
|
|
||||||
y <<= 32;
|
|
||||||
x <<= 32;
|
|
||||||
|
|
||||||
y.Insert(0, xE3);
|
|
||||||
x.Insert(0, yE3);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static uint ShaHashSigma0(uint x)
|
|
||||||
{
|
|
||||||
return x.Ror(2) ^ x.Ror(13) ^ x.Ror(22);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static uint ShaHashSigma1(uint x)
|
|
||||||
{
|
|
||||||
return x.Ror(6) ^ x.Ror(11) ^ x.Ror(25);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static uint Ror(this uint value, int count)
|
|
||||||
{
|
|
||||||
return (value >> count) | (value << (32 - count));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static uint Lsr(this uint value, int count)
|
|
||||||
{
|
|
||||||
return value >> count;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static uint ULongPart(this ulong value, int part)
|
|
||||||
{
|
|
||||||
return part == 0
|
|
||||||
? (uint)(value & 0xFFFFFFFFUL)
|
|
||||||
: (uint)(value >> 32);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static V128 PolynomialMult64_128(ulong op1, ulong op2)
|
|
||||||
{
|
|
||||||
V128 result = V128.Zero;
|
|
||||||
|
|
||||||
V128 op2_128 = new(op2, 0);
|
|
||||||
|
|
||||||
for (int i = 0; i < 64; i++)
|
|
||||||
{
|
|
||||||
if (((op1 >> i) & 1) == 1)
|
|
||||||
{
|
|
||||||
result ^= op2_128 << i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
using ARMeilleure.State;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Instructions
|
||||||
|
{
|
||||||
|
static partial class SoftFallback
|
||||||
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 Decrypt(V128 value, V128 roundKey)
|
||||||
|
{
|
||||||
|
return CryptoHelper.AesInvSubBytes(CryptoHelper.AesInvShiftRows(value ^ roundKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 Encrypt(V128 value, V128 roundKey)
|
||||||
|
{
|
||||||
|
return CryptoHelper.AesSubBytes(CryptoHelper.AesShiftRows(value ^ roundKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 InverseMixColumns(V128 value)
|
||||||
|
{
|
||||||
|
return CryptoHelper.AesInvMixColumns(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 MixColumns(V128 value)
|
||||||
|
{
|
||||||
|
return CryptoHelper.AesMixColumns(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Instructions
|
||||||
|
{
|
||||||
|
static partial class SoftFallback
|
||||||
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static ulong CountLeadingSigns(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
|
||||||
|
{
|
||||||
|
value ^= value >> 1;
|
||||||
|
|
||||||
|
int highBit = size - 2;
|
||||||
|
|
||||||
|
for (int bit = highBit; bit >= 0; bit--)
|
||||||
|
{
|
||||||
|
if (((int)(value >> bit) & 0b1) != 0)
|
||||||
|
{
|
||||||
|
return (ulong)(highBit - bit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ulong)(size - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlySpan<byte> ClzNibbleTbl => [4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static ulong CountLeadingZeros(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
|
||||||
|
{
|
||||||
|
if (value == 0ul)
|
||||||
|
{
|
||||||
|
return (ulong)size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nibbleIdx = size;
|
||||||
|
int preCount, count = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
nibbleIdx -= 4;
|
||||||
|
preCount = ClzNibbleTbl[(int)(value >> nibbleIdx) & 0b1111];
|
||||||
|
count += preCount;
|
||||||
|
}
|
||||||
|
while (preCount == 4);
|
||||||
|
|
||||||
|
return (ulong)count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Instructions
|
||||||
|
{
|
||||||
|
static partial class SoftFallback
|
||||||
|
{
|
||||||
|
private const uint Crc32RevPoly = 0xedb88320;
|
||||||
|
private const uint Crc32cRevPoly = 0x82f63b78;
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static uint Crc32b(uint crc, byte value) => Crc32(crc, Crc32RevPoly, value);
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static uint Crc32h(uint crc, ushort value) => Crc32h(crc, Crc32RevPoly, value);
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static uint Crc32w(uint crc, uint value) => Crc32w(crc, Crc32RevPoly, value);
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static uint Crc32x(uint crc, ulong value) => Crc32x(crc, Crc32RevPoly, value);
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static uint Crc32cb(uint crc, byte value) => Crc32(crc, Crc32cRevPoly, value);
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static uint Crc32ch(uint crc, ushort value) => Crc32h(crc, Crc32cRevPoly, value);
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static uint Crc32cw(uint crc, uint value) => Crc32w(crc, Crc32cRevPoly, value);
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static uint Crc32cx(uint crc, ulong value) => Crc32x(crc, Crc32cRevPoly, value);
|
||||||
|
|
||||||
|
private static uint Crc32h(uint crc, uint poly, ushort val)
|
||||||
|
{
|
||||||
|
crc = Crc32(crc, poly, (byte)(val >> 0));
|
||||||
|
crc = Crc32(crc, poly, (byte)(val >> 8));
|
||||||
|
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint Crc32w(uint crc, uint poly, uint val)
|
||||||
|
{
|
||||||
|
crc = Crc32(crc, poly, (byte)(val >> 0));
|
||||||
|
crc = Crc32(crc, poly, (byte)(val >> 8));
|
||||||
|
crc = Crc32(crc, poly, (byte)(val >> 16));
|
||||||
|
crc = Crc32(crc, poly, (byte)(val >> 24));
|
||||||
|
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint Crc32x(uint crc, uint poly, ulong val)
|
||||||
|
{
|
||||||
|
crc = Crc32(crc, poly, (byte)(val >> 0));
|
||||||
|
crc = Crc32(crc, poly, (byte)(val >> 8));
|
||||||
|
crc = Crc32(crc, poly, (byte)(val >> 16));
|
||||||
|
crc = Crc32(crc, poly, (byte)(val >> 24));
|
||||||
|
crc = Crc32(crc, poly, (byte)(val >> 32));
|
||||||
|
crc = Crc32(crc, poly, (byte)(val >> 40));
|
||||||
|
crc = Crc32(crc, poly, (byte)(val >> 48));
|
||||||
|
crc = Crc32(crc, poly, (byte)(val >> 56));
|
||||||
|
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint Crc32(uint crc, uint poly, byte val)
|
||||||
|
{
|
||||||
|
crc ^= val;
|
||||||
|
|
||||||
|
for (int bit = 7; bit >= 0; bit--)
|
||||||
|
{
|
||||||
|
uint mask = (uint)(-(int)(crc & 1));
|
||||||
|
|
||||||
|
crc = (crc >> 1) ^ (poly & mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Instructions
|
||||||
|
{
|
||||||
|
static partial class SoftFallback
|
||||||
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static int SatF32ToS32(float value)
|
||||||
|
{
|
||||||
|
if (float.IsNaN(value))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value >= int.MaxValue ? int.MaxValue :
|
||||||
|
value <= int.MinValue ? int.MinValue : (int)value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static long SatF32ToS64(float value)
|
||||||
|
{
|
||||||
|
if (float.IsNaN(value))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value >= long.MaxValue ? long.MaxValue :
|
||||||
|
value <= long.MinValue ? long.MinValue : (long)value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static uint SatF32ToU32(float value)
|
||||||
|
{
|
||||||
|
if (float.IsNaN(value))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value >= uint.MaxValue ? uint.MaxValue :
|
||||||
|
value <= uint.MinValue ? uint.MinValue : (uint)value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static ulong SatF32ToU64(float value)
|
||||||
|
{
|
||||||
|
if (float.IsNaN(value))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value >= ulong.MaxValue ? ulong.MaxValue :
|
||||||
|
value <= ulong.MinValue ? ulong.MinValue : (ulong)value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static int SatF64ToS32(double value)
|
||||||
|
{
|
||||||
|
if (double.IsNaN(value))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value >= int.MaxValue ? int.MaxValue :
|
||||||
|
value <= int.MinValue ? int.MinValue : (int)value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static long SatF64ToS64(double value)
|
||||||
|
{
|
||||||
|
if (double.IsNaN(value))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value >= long.MaxValue ? long.MaxValue :
|
||||||
|
value <= long.MinValue ? long.MinValue : (long)value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static uint SatF64ToU32(double value)
|
||||||
|
{
|
||||||
|
if (double.IsNaN(value))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value >= uint.MaxValue ? uint.MaxValue :
|
||||||
|
value <= uint.MinValue ? uint.MinValue : (uint)value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static ulong SatF64ToU64(double value)
|
||||||
|
{
|
||||||
|
if (double.IsNaN(value))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value >= ulong.MaxValue ? ulong.MaxValue :
|
||||||
|
value <= ulong.MinValue ? ulong.MinValue : (ulong)value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
131
src/ARMeilleure/Instructions/SoftFallback/SoftFallback.Sha1.cs
Normal file
131
src/ARMeilleure/Instructions/SoftFallback/SoftFallback.Sha1.cs
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
using ARMeilleure.State;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Instructions
|
||||||
|
{
|
||||||
|
static partial class SoftFallback
|
||||||
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 HashChoose(V128 hash_abcd, uint hash_e, V128 wk)
|
||||||
|
{
|
||||||
|
for (int e = 0; e <= 3; e++)
|
||||||
|
{
|
||||||
|
uint t = ShaChoose(hash_abcd.Extract<uint>(1),
|
||||||
|
hash_abcd.Extract<uint>(2),
|
||||||
|
hash_abcd.Extract<uint>(3));
|
||||||
|
|
||||||
|
hash_e += Rol(hash_abcd.Extract<uint>(0), 5) + t + wk.Extract<uint>(e);
|
||||||
|
|
||||||
|
t = Rol(hash_abcd.Extract<uint>(1), 30);
|
||||||
|
|
||||||
|
hash_abcd.Insert(1, t);
|
||||||
|
|
||||||
|
Rol32_160(ref hash_e, ref hash_abcd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash_abcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static uint FixedRotate(uint hash_e)
|
||||||
|
{
|
||||||
|
return hash_e.Rol(30);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 HashMajority(V128 hash_abcd, uint hash_e, V128 wk)
|
||||||
|
{
|
||||||
|
for (int e = 0; e <= 3; e++)
|
||||||
|
{
|
||||||
|
uint t = ShaMajority(hash_abcd.Extract<uint>(1),
|
||||||
|
hash_abcd.Extract<uint>(2),
|
||||||
|
hash_abcd.Extract<uint>(3));
|
||||||
|
|
||||||
|
hash_e += Rol(hash_abcd.Extract<uint>(0), 5) + t + wk.Extract<uint>(e);
|
||||||
|
|
||||||
|
t = Rol(hash_abcd.Extract<uint>(1), 30);
|
||||||
|
|
||||||
|
hash_abcd.Insert(1, t);
|
||||||
|
|
||||||
|
Rol32_160(ref hash_e, ref hash_abcd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash_abcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 HashParity(V128 hash_abcd, uint hash_e, V128 wk)
|
||||||
|
{
|
||||||
|
for (int e = 0; e <= 3; e++)
|
||||||
|
{
|
||||||
|
uint t = ShaParity(hash_abcd.Extract<uint>(1),
|
||||||
|
hash_abcd.Extract<uint>(2),
|
||||||
|
hash_abcd.Extract<uint>(3));
|
||||||
|
|
||||||
|
hash_e += Rol(hash_abcd.Extract<uint>(0), 5) + t + wk.Extract<uint>(e);
|
||||||
|
|
||||||
|
t = Rol(hash_abcd.Extract<uint>(1), 30);
|
||||||
|
|
||||||
|
hash_abcd.Insert(1, t);
|
||||||
|
|
||||||
|
Rol32_160(ref hash_e, ref hash_abcd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash_abcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 Sha1SchedulePart1(V128 w0_3, V128 w4_7, V128 w8_11)
|
||||||
|
{
|
||||||
|
ulong t2 = w4_7.Extract<ulong>(0);
|
||||||
|
ulong t1 = w0_3.Extract<ulong>(1);
|
||||||
|
|
||||||
|
V128 result = new(t1, t2);
|
||||||
|
|
||||||
|
return result ^ (w0_3 ^ w8_11);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 Sha1SchedulePart2(V128 tw0_3, V128 w12_15)
|
||||||
|
{
|
||||||
|
V128 t = tw0_3 ^ (w12_15 >> 32);
|
||||||
|
|
||||||
|
uint tE0 = t.Extract<uint>(0);
|
||||||
|
uint tE1 = t.Extract<uint>(1);
|
||||||
|
uint tE2 = t.Extract<uint>(2);
|
||||||
|
uint tE3 = t.Extract<uint>(3);
|
||||||
|
|
||||||
|
return new V128(tE0.Rol(1), tE1.Rol(1), tE2.Rol(1), tE3.Rol(1) ^ tE0.Rol(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Rol32_160(ref uint y, ref V128 x)
|
||||||
|
{
|
||||||
|
uint xE3 = x.Extract<uint>(3);
|
||||||
|
|
||||||
|
x <<= 32;
|
||||||
|
x.Insert(0, y);
|
||||||
|
|
||||||
|
y = xE3;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint ShaChoose(uint x, uint y, uint z)
|
||||||
|
{
|
||||||
|
return ((y ^ z) & x) ^ z;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint ShaMajority(uint x, uint y, uint z)
|
||||||
|
{
|
||||||
|
return (x & y) | ((x | y) & z);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint ShaParity(uint x, uint y, uint z)
|
||||||
|
{
|
||||||
|
return x ^ y ^ z;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint Rol(this uint value, int count)
|
||||||
|
{
|
||||||
|
return (value << count) | (value >> (32 - count));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
140
src/ARMeilleure/Instructions/SoftFallback/SoftFallback.Sha256.cs
Normal file
140
src/ARMeilleure/Instructions/SoftFallback/SoftFallback.Sha256.cs
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
using ARMeilleure.State;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Instructions
|
||||||
|
{
|
||||||
|
static partial class SoftFallback
|
||||||
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 HashLower(V128 hash_abcd, V128 hash_efgh, V128 wk)
|
||||||
|
{
|
||||||
|
return Sha256Hash(hash_abcd, hash_efgh, wk, part1: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 HashUpper(V128 hash_abcd, V128 hash_efgh, V128 wk)
|
||||||
|
{
|
||||||
|
return Sha256Hash(hash_abcd, hash_efgh, wk, part1: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 Sha256SchedulePart1(V128 w0_3, V128 w4_7)
|
||||||
|
{
|
||||||
|
V128 result = new();
|
||||||
|
|
||||||
|
for (int e = 0; e <= 3; e++)
|
||||||
|
{
|
||||||
|
uint elt = (e <= 2 ? w0_3 : w4_7).Extract<uint>(e <= 2 ? e + 1 : 0);
|
||||||
|
|
||||||
|
elt = elt.Ror(7) ^ elt.Ror(18) ^ elt.Lsr(3);
|
||||||
|
|
||||||
|
elt += w0_3.Extract<uint>(e);
|
||||||
|
|
||||||
|
result.Insert(e, elt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 Sha256SchedulePart2(V128 w0_3, V128 w8_11, V128 w12_15)
|
||||||
|
{
|
||||||
|
V128 result = new();
|
||||||
|
|
||||||
|
ulong t1 = w12_15.Extract<ulong>(1);
|
||||||
|
|
||||||
|
for (int e = 0; e <= 1; e++)
|
||||||
|
{
|
||||||
|
uint elt = t1.ULongPart(e);
|
||||||
|
|
||||||
|
elt = elt.Ror(17) ^ elt.Ror(19) ^ elt.Lsr(10);
|
||||||
|
|
||||||
|
elt += w0_3.Extract<uint>(e) + w8_11.Extract<uint>(e + 1);
|
||||||
|
|
||||||
|
result.Insert(e, elt);
|
||||||
|
}
|
||||||
|
|
||||||
|
t1 = result.Extract<ulong>(0);
|
||||||
|
|
||||||
|
for (int e = 2; e <= 3; e++)
|
||||||
|
{
|
||||||
|
uint elt = t1.ULongPart(e - 2);
|
||||||
|
|
||||||
|
elt = elt.Ror(17) ^ elt.Ror(19) ^ elt.Lsr(10);
|
||||||
|
|
||||||
|
elt += w0_3.Extract<uint>(e) + (e == 2 ? w8_11 : w12_15).Extract<uint>(e == 2 ? 3 : 0);
|
||||||
|
|
||||||
|
result.Insert(e, elt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static V128 Sha256Hash(V128 x, V128 y, V128 w, bool part1)
|
||||||
|
{
|
||||||
|
for (int e = 0; e <= 3; e++)
|
||||||
|
{
|
||||||
|
uint chs = ShaChoose(y.Extract<uint>(0),
|
||||||
|
y.Extract<uint>(1),
|
||||||
|
y.Extract<uint>(2));
|
||||||
|
|
||||||
|
uint maj = ShaMajority(x.Extract<uint>(0),
|
||||||
|
x.Extract<uint>(1),
|
||||||
|
x.Extract<uint>(2));
|
||||||
|
|
||||||
|
uint t1 = y.Extract<uint>(3) + ShaHashSigma1(y.Extract<uint>(0)) + chs + w.Extract<uint>(e);
|
||||||
|
|
||||||
|
uint t2 = t1 + x.Extract<uint>(3);
|
||||||
|
|
||||||
|
x.Insert(3, t2);
|
||||||
|
|
||||||
|
t2 = t1 + ShaHashSigma0(x.Extract<uint>(0)) + maj;
|
||||||
|
|
||||||
|
y.Insert(3, t2);
|
||||||
|
|
||||||
|
Rol32_256(ref y, ref x);
|
||||||
|
}
|
||||||
|
|
||||||
|
return part1 ? x : y;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Rol32_256(ref V128 y, ref V128 x)
|
||||||
|
{
|
||||||
|
uint yE3 = y.Extract<uint>(3);
|
||||||
|
uint xE3 = x.Extract<uint>(3);
|
||||||
|
|
||||||
|
y <<= 32;
|
||||||
|
x <<= 32;
|
||||||
|
|
||||||
|
y.Insert(0, xE3);
|
||||||
|
x.Insert(0, yE3);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint ShaHashSigma0(uint x)
|
||||||
|
{
|
||||||
|
return x.Ror(2) ^ x.Ror(13) ^ x.Ror(22);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint ShaHashSigma1(uint x)
|
||||||
|
{
|
||||||
|
return x.Ror(6) ^ x.Ror(11) ^ x.Ror(25);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint Ror(this uint value, int count)
|
||||||
|
{
|
||||||
|
return (value >> count) | (value << (32 - count));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint Lsr(this uint value, int count)
|
||||||
|
{
|
||||||
|
return value >> count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint ULongPart(this ulong value, int part)
|
||||||
|
{
|
||||||
|
return part == 0
|
||||||
|
? (uint)(value & 0xFFFFFFFFUL)
|
||||||
|
: (uint)(value >> 32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Instructions
|
||||||
|
{
|
||||||
|
static partial class SoftFallback
|
||||||
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static long SignedShrImm64(long value, long roundConst, int shift)
|
||||||
|
{
|
||||||
|
if (roundConst == 0L)
|
||||||
|
{
|
||||||
|
if (shift <= 63)
|
||||||
|
{
|
||||||
|
return value >> shift;
|
||||||
|
}
|
||||||
|
else /* if (shift == 64) */
|
||||||
|
{
|
||||||
|
if (value < 0L)
|
||||||
|
{
|
||||||
|
return -1L;
|
||||||
|
}
|
||||||
|
else /* if (value >= 0L) */
|
||||||
|
{
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* if (roundConst == 1L << (shift - 1)) */
|
||||||
|
{
|
||||||
|
if (shift <= 63)
|
||||||
|
{
|
||||||
|
long add = value + roundConst;
|
||||||
|
|
||||||
|
if ((~value & (value ^ add)) < 0L)
|
||||||
|
{
|
||||||
|
return (long)((ulong)add >> shift);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return add >> shift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* if (shift == 64) */
|
||||||
|
{
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static ulong UnsignedShrImm64(ulong value, long roundConst, int shift)
|
||||||
|
{
|
||||||
|
if (roundConst == 0L)
|
||||||
|
{
|
||||||
|
if (shift <= 63)
|
||||||
|
{
|
||||||
|
return value >> shift;
|
||||||
|
}
|
||||||
|
else /* if (shift == 64) */
|
||||||
|
{
|
||||||
|
return 0UL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* if (roundConst == 1L << (shift - 1)) */
|
||||||
|
{
|
||||||
|
ulong add = value + (ulong)roundConst;
|
||||||
|
|
||||||
|
if ((add < value) && (add < (ulong)roundConst))
|
||||||
|
{
|
||||||
|
if (shift <= 63)
|
||||||
|
{
|
||||||
|
return (add >> shift) | (0x8000000000000000UL >> (shift - 1));
|
||||||
|
}
|
||||||
|
else /* if (shift == 64) */
|
||||||
|
{
|
||||||
|
return 1UL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (shift <= 63)
|
||||||
|
{
|
||||||
|
return add >> shift;
|
||||||
|
}
|
||||||
|
else /* if (shift == 64) */
|
||||||
|
{
|
||||||
|
return 0UL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
using ARMeilleure.State;
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Instructions
|
||||||
|
{
|
||||||
|
static partial class SoftFallback
|
||||||
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 Tbl1(V128 vector, int bytes, V128 tb0)
|
||||||
|
{
|
||||||
|
return TblOrTbx(default, vector, bytes, tb0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 Tbl2(V128 vector, int bytes, V128 tb0, V128 tb1)
|
||||||
|
{
|
||||||
|
return TblOrTbx(default, vector, bytes, tb0, tb1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 Tbl3(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2)
|
||||||
|
{
|
||||||
|
return TblOrTbx(default, vector, bytes, tb0, tb1, tb2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 Tbl4(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3)
|
||||||
|
{
|
||||||
|
return TblOrTbx(default, vector, bytes, tb0, tb1, tb2, tb3);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 Tbx1(V128 dest, V128 vector, int bytes, V128 tb0)
|
||||||
|
{
|
||||||
|
return TblOrTbx(dest, vector, bytes, tb0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 Tbx2(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1)
|
||||||
|
{
|
||||||
|
return TblOrTbx(dest, vector, bytes, tb0, tb1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 Tbx3(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2)
|
||||||
|
{
|
||||||
|
return TblOrTbx(dest, vector, bytes, tb0, tb1, tb2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 Tbx4(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3)
|
||||||
|
{
|
||||||
|
return TblOrTbx(dest, vector, bytes, tb0, tb1, tb2, tb3);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static V128 TblOrTbx(V128 dest, V128 vector, int bytes, params ReadOnlySpan<V128> tb)
|
||||||
|
{
|
||||||
|
byte[] res = new byte[16];
|
||||||
|
|
||||||
|
if (dest != default)
|
||||||
|
{
|
||||||
|
Buffer.BlockCopy(dest.ToArray(), 0, res, 0, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] table = new byte[tb.Length * 16];
|
||||||
|
|
||||||
|
for (byte index = 0; index < tb.Length; index++)
|
||||||
|
{
|
||||||
|
Buffer.BlockCopy(tb[index].ToArray(), 0, table, index * 16, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] v = vector.ToArray();
|
||||||
|
|
||||||
|
for (byte index = 0; index < bytes; index++)
|
||||||
|
{
|
||||||
|
byte tblIndex = v[index];
|
||||||
|
|
||||||
|
if (tblIndex < table.Length)
|
||||||
|
{
|
||||||
|
res[index] = table[tblIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new V128(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/ARMeilleure/Instructions/SoftFallback/SoftFallback.cs
Normal file
26
src/ARMeilleure/Instructions/SoftFallback/SoftFallback.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
using ARMeilleure.State;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Instructions
|
||||||
|
{
|
||||||
|
static partial class SoftFallback
|
||||||
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static V128 PolynomialMult64_128(ulong op1, ulong op2)
|
||||||
|
{
|
||||||
|
V128 result = V128.Zero;
|
||||||
|
|
||||||
|
V128 op2_128 = new(op2, 0);
|
||||||
|
|
||||||
|
for (int i = 0; i < 64; i++)
|
||||||
|
{
|
||||||
|
if (((op1 >> i) & 1) == 1)
|
||||||
|
{
|
||||||
|
result ^= op2_128 << i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
111
src/ARMeilleure/Instructions/SoftFloat/SoftFloat.cs
Normal file
111
src/ARMeilleure/Instructions/SoftFloat/SoftFloat.cs
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
using ARMeilleure.State;
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Instructions
|
||||||
|
{
|
||||||
|
static class SoftFloat
|
||||||
|
{
|
||||||
|
static SoftFloat()
|
||||||
|
{
|
||||||
|
RecipEstimateTable = BuildRecipEstimateTable();
|
||||||
|
RecipSqrtEstimateTable = BuildRecipSqrtEstimateTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly byte[] RecipEstimateTable;
|
||||||
|
public static readonly byte[] RecipSqrtEstimateTable;
|
||||||
|
|
||||||
|
private static byte[] BuildRecipEstimateTable()
|
||||||
|
{
|
||||||
|
byte[] tbl = new byte[256];
|
||||||
|
|
||||||
|
for (int idx = 0; idx < 256; idx++)
|
||||||
|
{
|
||||||
|
uint src = (uint)idx + 256u;
|
||||||
|
|
||||||
|
Debug.Assert(src is >= 256u and < 512u);
|
||||||
|
|
||||||
|
src = (src << 1) + 1u;
|
||||||
|
|
||||||
|
uint aux = (1u << 19) / src;
|
||||||
|
|
||||||
|
uint dst = (aux + 1u) >> 1;
|
||||||
|
|
||||||
|
Debug.Assert(dst is >= 256u and < 512u);
|
||||||
|
|
||||||
|
tbl[idx] = (byte)(dst - 256u);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tbl;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] BuildRecipSqrtEstimateTable()
|
||||||
|
{
|
||||||
|
byte[] tbl = new byte[384];
|
||||||
|
|
||||||
|
for (int idx = 0; idx < 384; idx++)
|
||||||
|
{
|
||||||
|
uint src = (uint)idx + 128u;
|
||||||
|
|
||||||
|
Debug.Assert(src is >= 128u and < 512u);
|
||||||
|
|
||||||
|
if (src < 256u)
|
||||||
|
{
|
||||||
|
src = (src << 1) + 1u;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
src = (src >> 1) << 1;
|
||||||
|
src = (src + 1u) << 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint aux = 512u;
|
||||||
|
|
||||||
|
while (src * (aux + 1u) * (aux + 1u) < (1u << 28))
|
||||||
|
{
|
||||||
|
aux++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint dst = (aux + 1u) >> 1;
|
||||||
|
|
||||||
|
Debug.Assert(dst is >= 256u and < 512u);
|
||||||
|
|
||||||
|
tbl[idx] = (byte)(dst - 256u);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tbl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void FPProcessException(FPException exc, ExecutionContext context)
|
||||||
|
{
|
||||||
|
FPProcessException(exc, context, context.Fpcr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void FPProcessException(FPException exc, ExecutionContext context, FPCR fpcr)
|
||||||
|
{
|
||||||
|
int enable = (int)exc + 8;
|
||||||
|
|
||||||
|
if ((fpcr & (FPCR)(1 << enable)) != 0)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("Floating-point trap handling.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context.Fpsr |= (FPSR)(1 << (int)exc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension(FPCR fpcr)
|
||||||
|
{
|
||||||
|
public FPRoundingMode RoundingMode
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
const int RModeShift = 22;
|
||||||
|
|
||||||
|
return (FPRoundingMode)(((uint)fpcr >> RModeShift) & 3u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
212
src/ARMeilleure/Instructions/SoftFloat/SoftFloat16.cs
Normal file
212
src/ARMeilleure/Instructions/SoftFloat/SoftFloat16.cs
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
using ARMeilleure.State;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Instructions
|
||||||
|
{
|
||||||
|
static class SoftFloat16
|
||||||
|
{
|
||||||
|
public static ushort FPDefaultNaN()
|
||||||
|
{
|
||||||
|
return (ushort)0x7E00u;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ushort FPInfinity(bool sign)
|
||||||
|
{
|
||||||
|
return sign ? (ushort)0xFC00u : (ushort)0x7C00u;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ushort FPZero(bool sign)
|
||||||
|
{
|
||||||
|
return sign ? (ushort)0x8000u : (ushort)0x0000u;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ushort FPMaxNormal(bool sign)
|
||||||
|
{
|
||||||
|
return sign ? (ushort)0xFBFFu : (ushort)0x7BFFu;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double FPUnpackCv(
|
||||||
|
this ushort valueBits,
|
||||||
|
out FPType type,
|
||||||
|
out bool sign,
|
||||||
|
ExecutionContext context)
|
||||||
|
{
|
||||||
|
sign = (~(uint)valueBits & 0x8000u) == 0u;
|
||||||
|
|
||||||
|
uint exp16 = ((uint)valueBits & 0x7C00u) >> 10;
|
||||||
|
uint frac16 = (uint)valueBits & 0x03FFu;
|
||||||
|
|
||||||
|
double real;
|
||||||
|
|
||||||
|
if (exp16 == 0u)
|
||||||
|
{
|
||||||
|
if (frac16 == 0u)
|
||||||
|
{
|
||||||
|
type = FPType.Zero;
|
||||||
|
real = 0d;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
type = FPType.Nonzero; // Subnormal.
|
||||||
|
real = Math.Pow(2d, -14) * ((double)frac16 * Math.Pow(2d, -10));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (exp16 == 0x1Fu && (context.Fpcr & FPCR.Ahp) == 0)
|
||||||
|
{
|
||||||
|
if (frac16 == 0u)
|
||||||
|
{
|
||||||
|
type = FPType.Infinity;
|
||||||
|
real = Math.Pow(2d, 1000);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
type = (~frac16 & 0x0200u) == 0u ? FPType.QNaN : FPType.SNaN;
|
||||||
|
real = 0d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
type = FPType.Nonzero; // Normal.
|
||||||
|
real = Math.Pow(2d, (int)exp16 - 15) * (1d + (double)frac16 * Math.Pow(2d, -10));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sign ? -real : real;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ushort FPRoundCv(double real, ExecutionContext context)
|
||||||
|
{
|
||||||
|
const int MinimumExp = -14;
|
||||||
|
|
||||||
|
const int E = 5;
|
||||||
|
const int F = 10;
|
||||||
|
|
||||||
|
bool sign;
|
||||||
|
double mantissa;
|
||||||
|
|
||||||
|
if (real < 0d)
|
||||||
|
{
|
||||||
|
sign = true;
|
||||||
|
mantissa = -real;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sign = false;
|
||||||
|
mantissa = real;
|
||||||
|
}
|
||||||
|
|
||||||
|
int exponent = 0;
|
||||||
|
|
||||||
|
while (mantissa < 1d)
|
||||||
|
{
|
||||||
|
mantissa *= 2d;
|
||||||
|
exponent--;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (mantissa >= 2d)
|
||||||
|
{
|
||||||
|
mantissa /= 2d;
|
||||||
|
exponent++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint biasedExp = (uint)Math.Max(exponent - MinimumExp + 1, 0);
|
||||||
|
|
||||||
|
if (biasedExp == 0u)
|
||||||
|
{
|
||||||
|
mantissa /= Math.Pow(2d, MinimumExp - exponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint intMant = (uint)Math.Floor(mantissa * Math.Pow(2d, F));
|
||||||
|
double error = mantissa * Math.Pow(2d, F) - (double)intMant;
|
||||||
|
|
||||||
|
if (biasedExp == 0u && (error != 0d || (context.Fpcr & FPCR.Ufe) != 0))
|
||||||
|
{
|
||||||
|
SoftFloat.FPProcessException(FPException.Underflow, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool overflowToInf;
|
||||||
|
bool roundUp;
|
||||||
|
|
||||||
|
switch (context.Fpcr.RoundingMode)
|
||||||
|
{
|
||||||
|
case FPRoundingMode.ToNearest:
|
||||||
|
roundUp = (error > 0.5d || (error == 0.5d && (intMant & 1u) == 1u));
|
||||||
|
overflowToInf = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FPRoundingMode.TowardsPlusInfinity:
|
||||||
|
roundUp = (error != 0d && !sign);
|
||||||
|
overflowToInf = !sign;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FPRoundingMode.TowardsMinusInfinity:
|
||||||
|
roundUp = (error != 0d && sign);
|
||||||
|
overflowToInf = sign;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FPRoundingMode.TowardsZero:
|
||||||
|
roundUp = false;
|
||||||
|
overflowToInf = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentException($"Invalid rounding mode \"{context.Fpcr.RoundingMode}\".");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (roundUp)
|
||||||
|
{
|
||||||
|
intMant++;
|
||||||
|
|
||||||
|
if (intMant == 1u << F)
|
||||||
|
{
|
||||||
|
biasedExp = 1u;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intMant == 1u << (F + 1))
|
||||||
|
{
|
||||||
|
biasedExp++;
|
||||||
|
intMant >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ushort resultBits;
|
||||||
|
|
||||||
|
if ((context.Fpcr & FPCR.Ahp) == 0)
|
||||||
|
{
|
||||||
|
if (biasedExp >= (1u << E) - 1u)
|
||||||
|
{
|
||||||
|
resultBits = overflowToInf ? FPInfinity(sign) : FPMaxNormal(sign);
|
||||||
|
|
||||||
|
SoftFloat.FPProcessException(FPException.Overflow, context);
|
||||||
|
|
||||||
|
error = 1d;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resultBits = (ushort)((sign ? 1u : 0u) << 15 | (biasedExp & 0x1Fu) << 10 | (intMant & 0x03FFu));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (biasedExp >= 1u << E)
|
||||||
|
{
|
||||||
|
resultBits = (ushort)((sign ? 1u : 0u) << 15 | 0x7FFFu);
|
||||||
|
|
||||||
|
SoftFloat.FPProcessException(FPException.InvalidOp, context);
|
||||||
|
|
||||||
|
error = 0d;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resultBits = (ushort)((sign ? 1u : 0u) << 15 | (biasedExp & 0x1Fu) << 10 | (intMant & 0x03FFu));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error != 0d)
|
||||||
|
{
|
||||||
|
SoftFloat.FPProcessException(FPException.Inexact, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultBits;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
182
src/ARMeilleure/Instructions/SoftFloat/SoftFloat16_32.cs
Normal file
182
src/ARMeilleure/Instructions/SoftFloat/SoftFloat16_32.cs
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
using ARMeilleure.State;
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Instructions
|
||||||
|
{
|
||||||
|
static class SoftFloat16_32
|
||||||
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static float FPConvert(ushort valueBits)
|
||||||
|
{
|
||||||
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
|
|
||||||
|
double real = valueBits.FPUnpackCv(out FPType type, out bool sign, context);
|
||||||
|
|
||||||
|
float result;
|
||||||
|
|
||||||
|
if (type is FPType.SNaN or FPType.QNaN)
|
||||||
|
{
|
||||||
|
if ((context.Fpcr & FPCR.Dn) != 0)
|
||||||
|
{
|
||||||
|
result = SoftFloat32.FPDefaultNaN();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = FPConvertNaN(valueBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == FPType.SNaN)
|
||||||
|
{
|
||||||
|
SoftFloat.FPProcessException(FPException.InvalidOp, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == FPType.Infinity)
|
||||||
|
{
|
||||||
|
result = SoftFloat32.FPInfinity(sign);
|
||||||
|
}
|
||||||
|
else if (type == FPType.Zero)
|
||||||
|
{
|
||||||
|
result = SoftFloat32.FPZero(sign);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = FPRoundCv(real, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float FPRoundCv(double real, ExecutionContext context)
|
||||||
|
{
|
||||||
|
const int MinimumExp = -126;
|
||||||
|
|
||||||
|
const int E = 8;
|
||||||
|
const int F = 23;
|
||||||
|
|
||||||
|
bool sign;
|
||||||
|
double mantissa;
|
||||||
|
|
||||||
|
if (real < 0d)
|
||||||
|
{
|
||||||
|
sign = true;
|
||||||
|
mantissa = -real;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sign = false;
|
||||||
|
mantissa = real;
|
||||||
|
}
|
||||||
|
|
||||||
|
int exponent = 0;
|
||||||
|
|
||||||
|
while (mantissa < 1d)
|
||||||
|
{
|
||||||
|
mantissa *= 2d;
|
||||||
|
exponent--;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (mantissa >= 2d)
|
||||||
|
{
|
||||||
|
mantissa /= 2d;
|
||||||
|
exponent++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((context.Fpcr & FPCR.Fz) != 0 && exponent < MinimumExp)
|
||||||
|
{
|
||||||
|
context.Fpsr |= FPSR.Ufc;
|
||||||
|
|
||||||
|
return SoftFloat32.FPZero(sign);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint biasedExp = (uint)Math.Max(exponent - MinimumExp + 1, 0);
|
||||||
|
|
||||||
|
if (biasedExp == 0u)
|
||||||
|
{
|
||||||
|
mantissa /= Math.Pow(2d, MinimumExp - exponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint intMant = (uint)Math.Floor(mantissa * Math.Pow(2d, F));
|
||||||
|
double error = mantissa * Math.Pow(2d, F) - (double)intMant;
|
||||||
|
|
||||||
|
if (biasedExp == 0u && (error != 0d || (context.Fpcr & FPCR.Ufe) != 0))
|
||||||
|
{
|
||||||
|
SoftFloat.FPProcessException(FPException.Underflow, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool overflowToInf;
|
||||||
|
bool roundUp;
|
||||||
|
|
||||||
|
switch (context.Fpcr.RoundingMode)
|
||||||
|
{
|
||||||
|
case FPRoundingMode.ToNearest:
|
||||||
|
roundUp = (error > 0.5d || (error == 0.5d && (intMant & 1u) == 1u));
|
||||||
|
overflowToInf = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FPRoundingMode.TowardsPlusInfinity:
|
||||||
|
roundUp = (error != 0d && !sign);
|
||||||
|
overflowToInf = !sign;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FPRoundingMode.TowardsMinusInfinity:
|
||||||
|
roundUp = (error != 0d && sign);
|
||||||
|
overflowToInf = sign;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FPRoundingMode.TowardsZero:
|
||||||
|
roundUp = false;
|
||||||
|
overflowToInf = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentException($"Invalid rounding mode \"{context.Fpcr.RoundingMode}\".");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (roundUp)
|
||||||
|
{
|
||||||
|
intMant++;
|
||||||
|
|
||||||
|
if (intMant == 1u << F)
|
||||||
|
{
|
||||||
|
biasedExp = 1u;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intMant == 1u << (F + 1))
|
||||||
|
{
|
||||||
|
biasedExp++;
|
||||||
|
intMant >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float result;
|
||||||
|
|
||||||
|
if (biasedExp >= (1u << E) - 1u)
|
||||||
|
{
|
||||||
|
result = overflowToInf ? SoftFloat32.FPInfinity(sign) : SoftFloat32.FPMaxNormal(sign);
|
||||||
|
|
||||||
|
SoftFloat.FPProcessException(FPException.Overflow, context);
|
||||||
|
|
||||||
|
error = 1d;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = BitConverter.Int32BitsToSingle(
|
||||||
|
(int)((sign ? 1u : 0u) << 31 | (biasedExp & 0xFFu) << 23 | (intMant & 0x007FFFFFu)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error != 0d)
|
||||||
|
{
|
||||||
|
SoftFloat.FPProcessException(FPException.Inexact, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float FPConvertNaN(ushort valueBits)
|
||||||
|
{
|
||||||
|
return BitConverter.Int32BitsToSingle(
|
||||||
|
(int)(((uint)valueBits & 0x8000u) << 16 | 0x7FC00000u | ((uint)valueBits & 0x01FFu) << 13));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
182
src/ARMeilleure/Instructions/SoftFloat/SoftFloat16_64.cs
Normal file
182
src/ARMeilleure/Instructions/SoftFloat/SoftFloat16_64.cs
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
using ARMeilleure.State;
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Instructions
|
||||||
|
{
|
||||||
|
static class SoftFloat16_64
|
||||||
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static double FPConvert(ushort valueBits)
|
||||||
|
{
|
||||||
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
|
|
||||||
|
double real = valueBits.FPUnpackCv(out FPType type, out bool sign, context);
|
||||||
|
|
||||||
|
double result;
|
||||||
|
|
||||||
|
if (type is FPType.SNaN or FPType.QNaN)
|
||||||
|
{
|
||||||
|
if ((context.Fpcr & FPCR.Dn) != 0)
|
||||||
|
{
|
||||||
|
result = SoftFloat64.FPDefaultNaN();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = FPConvertNaN(valueBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == FPType.SNaN)
|
||||||
|
{
|
||||||
|
SoftFloat.FPProcessException(FPException.InvalidOp, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == FPType.Infinity)
|
||||||
|
{
|
||||||
|
result = SoftFloat64.FPInfinity(sign);
|
||||||
|
}
|
||||||
|
else if (type == FPType.Zero)
|
||||||
|
{
|
||||||
|
result = SoftFloat64.FPZero(sign);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = FPRoundCv(real, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double FPRoundCv(double real, ExecutionContext context)
|
||||||
|
{
|
||||||
|
const int MinimumExp = -1022;
|
||||||
|
|
||||||
|
const int E = 11;
|
||||||
|
const int F = 52;
|
||||||
|
|
||||||
|
bool sign;
|
||||||
|
double mantissa;
|
||||||
|
|
||||||
|
if (real < 0d)
|
||||||
|
{
|
||||||
|
sign = true;
|
||||||
|
mantissa = -real;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sign = false;
|
||||||
|
mantissa = real;
|
||||||
|
}
|
||||||
|
|
||||||
|
int exponent = 0;
|
||||||
|
|
||||||
|
while (mantissa < 1d)
|
||||||
|
{
|
||||||
|
mantissa *= 2d;
|
||||||
|
exponent--;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (mantissa >= 2d)
|
||||||
|
{
|
||||||
|
mantissa /= 2d;
|
||||||
|
exponent++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((context.Fpcr & FPCR.Fz) != 0 && exponent < MinimumExp)
|
||||||
|
{
|
||||||
|
context.Fpsr |= FPSR.Ufc;
|
||||||
|
|
||||||
|
return SoftFloat64.FPZero(sign);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint biasedExp = (uint)Math.Max(exponent - MinimumExp + 1, 0);
|
||||||
|
|
||||||
|
if (biasedExp == 0u)
|
||||||
|
{
|
||||||
|
mantissa /= Math.Pow(2d, MinimumExp - exponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong intMant = (ulong)Math.Floor(mantissa * Math.Pow(2d, F));
|
||||||
|
double error = mantissa * Math.Pow(2d, F) - (double)intMant;
|
||||||
|
|
||||||
|
if (biasedExp == 0u && (error != 0d || (context.Fpcr & FPCR.Ufe) != 0))
|
||||||
|
{
|
||||||
|
SoftFloat.FPProcessException(FPException.Underflow, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool overflowToInf;
|
||||||
|
bool roundUp;
|
||||||
|
|
||||||
|
switch (context.Fpcr.RoundingMode)
|
||||||
|
{
|
||||||
|
case FPRoundingMode.ToNearest:
|
||||||
|
roundUp = (error > 0.5d || (error == 0.5d && (intMant & 1u) == 1u));
|
||||||
|
overflowToInf = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FPRoundingMode.TowardsPlusInfinity:
|
||||||
|
roundUp = (error != 0d && !sign);
|
||||||
|
overflowToInf = !sign;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FPRoundingMode.TowardsMinusInfinity:
|
||||||
|
roundUp = (error != 0d && sign);
|
||||||
|
overflowToInf = sign;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FPRoundingMode.TowardsZero:
|
||||||
|
roundUp = false;
|
||||||
|
overflowToInf = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentException($"Invalid rounding mode \"{context.Fpcr.RoundingMode}\".");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (roundUp)
|
||||||
|
{
|
||||||
|
intMant++;
|
||||||
|
|
||||||
|
if (intMant == 1ul << F)
|
||||||
|
{
|
||||||
|
biasedExp = 1u;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intMant == 1ul << (F + 1))
|
||||||
|
{
|
||||||
|
biasedExp++;
|
||||||
|
intMant >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double result;
|
||||||
|
|
||||||
|
if (biasedExp >= (1u << E) - 1u)
|
||||||
|
{
|
||||||
|
result = overflowToInf ? SoftFloat64.FPInfinity(sign) : SoftFloat64.FPMaxNormal(sign);
|
||||||
|
|
||||||
|
SoftFloat.FPProcessException(FPException.Overflow, context);
|
||||||
|
|
||||||
|
error = 1d;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = BitConverter.Int64BitsToDouble(
|
||||||
|
(long)((sign ? 1ul : 0ul) << 63 | (biasedExp & 0x7FFul) << 52 | (intMant & 0x000FFFFFFFFFFFFFul)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error != 0d)
|
||||||
|
{
|
||||||
|
SoftFloat.FPProcessException(FPException.Inexact, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double FPConvertNaN(ushort valueBits)
|
||||||
|
{
|
||||||
|
return BitConverter.Int64BitsToDouble(
|
||||||
|
(long)(((ulong)valueBits & 0x8000ul) << 48 | 0x7FF8000000000000ul | ((ulong)valueBits & 0x01FFul) << 42));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1421
src/ARMeilleure/Instructions/SoftFloat/SoftFloat32.cs
Normal file
1421
src/ARMeilleure/Instructions/SoftFloat/SoftFloat32.cs
Normal file
File diff suppressed because it is too large
Load Diff
126
src/ARMeilleure/Instructions/SoftFloat/SoftFloat32_16.cs
Normal file
126
src/ARMeilleure/Instructions/SoftFloat/SoftFloat32_16.cs
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
using ARMeilleure.State;
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Instructions
|
||||||
|
{
|
||||||
|
static class SoftFloat32_16
|
||||||
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static ushort FPConvert(float value)
|
||||||
|
{
|
||||||
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
|
|
||||||
|
double real = value.FPUnpackCv(out FPType type, out bool sign, out uint valueBits, context);
|
||||||
|
|
||||||
|
bool altHp = (context.Fpcr & FPCR.Ahp) != 0;
|
||||||
|
|
||||||
|
ushort resultBits;
|
||||||
|
|
||||||
|
if (type is FPType.SNaN or FPType.QNaN)
|
||||||
|
{
|
||||||
|
if (altHp)
|
||||||
|
{
|
||||||
|
resultBits = SoftFloat16.FPZero(sign);
|
||||||
|
}
|
||||||
|
else if ((context.Fpcr & FPCR.Dn) != 0)
|
||||||
|
{
|
||||||
|
resultBits = SoftFloat16.FPDefaultNaN();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resultBits = FPConvertNaN(valueBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == FPType.SNaN || altHp)
|
||||||
|
{
|
||||||
|
SoftFloat.FPProcessException(FPException.InvalidOp, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == FPType.Infinity)
|
||||||
|
{
|
||||||
|
if (altHp)
|
||||||
|
{
|
||||||
|
resultBits = (ushort)((sign ? 1u : 0u) << 15 | 0x7FFFu);
|
||||||
|
|
||||||
|
SoftFloat.FPProcessException(FPException.InvalidOp, context);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resultBits = SoftFloat16.FPInfinity(sign);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == FPType.Zero)
|
||||||
|
{
|
||||||
|
resultBits = SoftFloat16.FPZero(sign);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resultBits = SoftFloat16.FPRoundCv(real, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double FPUnpackCv(
|
||||||
|
this float value,
|
||||||
|
out FPType type,
|
||||||
|
out bool sign,
|
||||||
|
out uint valueBits,
|
||||||
|
ExecutionContext context)
|
||||||
|
{
|
||||||
|
valueBits = (uint)BitConverter.SingleToInt32Bits(value);
|
||||||
|
|
||||||
|
sign = (~valueBits & 0x80000000u) == 0u;
|
||||||
|
|
||||||
|
uint exp32 = (valueBits & 0x7F800000u) >> 23;
|
||||||
|
uint frac32 = valueBits & 0x007FFFFFu;
|
||||||
|
|
||||||
|
double real;
|
||||||
|
|
||||||
|
if (exp32 == 0u)
|
||||||
|
{
|
||||||
|
if (frac32 == 0u || (context.Fpcr & FPCR.Fz) != 0)
|
||||||
|
{
|
||||||
|
type = FPType.Zero;
|
||||||
|
real = 0d;
|
||||||
|
|
||||||
|
if (frac32 != 0u)
|
||||||
|
{
|
||||||
|
SoftFloat.FPProcessException(FPException.InputDenorm, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
type = FPType.Nonzero; // Subnormal.
|
||||||
|
real = Math.Pow(2d, -126) * ((double)frac32 * Math.Pow(2d, -23));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (exp32 == 0xFFu)
|
||||||
|
{
|
||||||
|
if (frac32 == 0u)
|
||||||
|
{
|
||||||
|
type = FPType.Infinity;
|
||||||
|
real = Math.Pow(2d, 1000);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
type = (~frac32 & 0x00400000u) == 0u ? FPType.QNaN : FPType.SNaN;
|
||||||
|
real = 0d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
type = FPType.Nonzero; // Normal.
|
||||||
|
real = Math.Pow(2d, (int)exp32 - 127) * (1d + (double)frac32 * Math.Pow(2d, -23));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sign ? -real : real;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ushort FPConvertNaN(uint valueBits)
|
||||||
|
{
|
||||||
|
return (ushort)((valueBits & 0x80000000u) >> 16 | 0x7E00u | (valueBits & 0x003FE000u) >> 13);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1421
src/ARMeilleure/Instructions/SoftFloat/SoftFloat64.cs
Normal file
1421
src/ARMeilleure/Instructions/SoftFloat/SoftFloat64.cs
Normal file
File diff suppressed because it is too large
Load Diff
127
src/ARMeilleure/Instructions/SoftFloat/SoftFloat64_16.cs
Normal file
127
src/ARMeilleure/Instructions/SoftFloat/SoftFloat64_16.cs
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
using ARMeilleure.State;
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Instructions
|
||||||
|
{
|
||||||
|
static class SoftFloat64_16
|
||||||
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static ushort FPConvert(double value)
|
||||||
|
{
|
||||||
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
|
|
||||||
|
double real = value.FPUnpackCv(out FPType type, out bool sign, out ulong valueBits, context);
|
||||||
|
|
||||||
|
bool altHp = (context.Fpcr & FPCR.Ahp) != 0;
|
||||||
|
|
||||||
|
ushort resultBits;
|
||||||
|
|
||||||
|
if (type is FPType.SNaN or FPType.QNaN)
|
||||||
|
{
|
||||||
|
if (altHp)
|
||||||
|
{
|
||||||
|
resultBits = SoftFloat16.FPZero(sign);
|
||||||
|
}
|
||||||
|
else if ((context.Fpcr & FPCR.Dn) != 0)
|
||||||
|
{
|
||||||
|
resultBits = SoftFloat16.FPDefaultNaN();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resultBits = FPConvertNaN(valueBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == FPType.SNaN || altHp)
|
||||||
|
{
|
||||||
|
SoftFloat.FPProcessException(FPException.InvalidOp, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == FPType.Infinity)
|
||||||
|
{
|
||||||
|
if (altHp)
|
||||||
|
{
|
||||||
|
resultBits = (ushort)((sign ? 1u : 0u) << 15 | 0x7FFFu);
|
||||||
|
|
||||||
|
SoftFloat.FPProcessException(FPException.InvalidOp, context);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resultBits = SoftFloat16.FPInfinity(sign);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == FPType.Zero)
|
||||||
|
{
|
||||||
|
resultBits = SoftFloat16.FPZero(sign);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resultBits = SoftFloat16.FPRoundCv(real, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double FPUnpackCv(
|
||||||
|
this double value,
|
||||||
|
out FPType type,
|
||||||
|
out bool sign,
|
||||||
|
out ulong valueBits,
|
||||||
|
ExecutionContext context)
|
||||||
|
{
|
||||||
|
valueBits = (ulong)BitConverter.DoubleToInt64Bits(value);
|
||||||
|
|
||||||
|
sign = (~valueBits & 0x8000000000000000ul) == 0u;
|
||||||
|
|
||||||
|
ulong exp64 = (valueBits & 0x7FF0000000000000ul) >> 52;
|
||||||
|
ulong frac64 = valueBits & 0x000FFFFFFFFFFFFFul;
|
||||||
|
|
||||||
|
double real;
|
||||||
|
|
||||||
|
if (exp64 == 0u)
|
||||||
|
{
|
||||||
|
if (frac64 == 0u || (context.Fpcr & FPCR.Fz) != 0)
|
||||||
|
{
|
||||||
|
type = FPType.Zero;
|
||||||
|
real = 0d;
|
||||||
|
|
||||||
|
if (frac64 != 0u)
|
||||||
|
{
|
||||||
|
SoftFloat.FPProcessException(FPException.InputDenorm, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
type = FPType.Nonzero; // Subnormal.
|
||||||
|
real = Math.Pow(2d, -1022) * ((double)frac64 * Math.Pow(2d, -52));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (exp64 == 0x7FFul)
|
||||||
|
{
|
||||||
|
if (frac64 == 0u)
|
||||||
|
{
|
||||||
|
type = FPType.Infinity;
|
||||||
|
real = Math.Pow(2d, 1000000);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
type = (~frac64 & 0x0008000000000000ul) == 0u ? FPType.QNaN : FPType.SNaN;
|
||||||
|
real = 0d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
type = FPType.Nonzero; // Normal.
|
||||||
|
real = Math.Pow(2d, (int)exp64 - 1023) * (1d + (double)frac64 * Math.Pow(2d, -52));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sign ? -real : real;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ushort FPConvertNaN(ulong valueBits)
|
||||||
|
{
|
||||||
|
return (ushort)((valueBits & 0x8000000000000000ul) >> 48 | 0x7E00u |
|
||||||
|
(valueBits & 0x0007FC0000000000ul) >> 42);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,9 +16,9 @@ namespace ARMeilleure.IntermediateRepresentation
|
|||||||
|
|
||||||
static class ComparisonExtensions
|
static class ComparisonExtensions
|
||||||
{
|
{
|
||||||
public static Comparison Invert(this Comparison comp)
|
extension(Comparison comparison)
|
||||||
{
|
{
|
||||||
return (Comparison)((int)comp ^ 1);
|
public Comparison Inverse => (Comparison)((int)comparison ^ 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace ARMeilleure.IntermediateRepresentation
|
namespace ARMeilleure.IntermediateRepresentation
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,48 +14,38 @@ namespace ARMeilleure.IntermediateRepresentation
|
|||||||
|
|
||||||
static class OperandTypeExtensions
|
static class OperandTypeExtensions
|
||||||
{
|
{
|
||||||
public static bool IsInteger(this OperandType type)
|
extension(OperandType type)
|
||||||
{
|
{
|
||||||
return type is OperandType.I32 or
|
public bool IsInteger => type is OperandType.I32 or OperandType.I64;
|
||||||
OperandType.I64;
|
|
||||||
}
|
public RegisterType Register => type switch
|
||||||
|
|
||||||
public static RegisterType ToRegisterType(this OperandType type)
|
|
||||||
{
|
|
||||||
return type switch
|
|
||||||
{
|
{
|
||||||
OperandType.FP32 => RegisterType.Vector,
|
OperandType.FP32 => RegisterType.Vector,
|
||||||
OperandType.FP64 => RegisterType.Vector,
|
OperandType.FP64 => RegisterType.Vector,
|
||||||
OperandType.I32 => RegisterType.Integer,
|
OperandType.I32 => RegisterType.Integer,
|
||||||
OperandType.I64 => RegisterType.Integer,
|
OperandType.I64 => RegisterType.Integer,
|
||||||
OperandType.V128 => RegisterType.Vector,
|
OperandType.V128 => RegisterType.Vector,
|
||||||
_ => throw new InvalidOperationException($"Invalid operand type \"{type}\"."),
|
_ => throw new InvalidOperationException($"Invalid operand type \"{type}\".")
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
public int ByteSize => type switch
|
||||||
public static int GetSizeInBytes(this OperandType type)
|
|
||||||
{
|
|
||||||
return type switch
|
|
||||||
{
|
{
|
||||||
OperandType.FP32 => 4,
|
OperandType.FP32 => 4,
|
||||||
OperandType.FP64 => 8,
|
OperandType.FP64 => 8,
|
||||||
OperandType.I32 => 4,
|
OperandType.I32 => 4,
|
||||||
OperandType.I64 => 8,
|
OperandType.I64 => 8,
|
||||||
OperandType.V128 => 16,
|
OperandType.V128 => 16,
|
||||||
_ => throw new InvalidOperationException($"Invalid operand type \"{type}\"."),
|
_ => throw new InvalidOperationException($"Invalid operand type \"{type}\".")
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
public int ByteSizeLog2 => type switch
|
||||||
public static int GetSizeInBytesLog2(this OperandType type)
|
|
||||||
{
|
|
||||||
return type switch
|
|
||||||
{
|
{
|
||||||
OperandType.FP32 => 2,
|
OperandType.FP32 => 2,
|
||||||
OperandType.FP64 => 3,
|
OperandType.FP64 => 3,
|
||||||
OperandType.I32 => 2,
|
OperandType.I32 => 2,
|
||||||
OperandType.I64 => 3,
|
OperandType.I64 => 3,
|
||||||
OperandType.V128 => 4,
|
OperandType.V128 => 4,
|
||||||
_ => throw new InvalidOperationException($"Invalid operand type \"{type}\"."),
|
_ => throw new InvalidOperationException($"Invalid operand type \"{type}\".")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,19 +45,12 @@ namespace ARMeilleure.Memory
|
|||||||
|
|
||||||
public static class MemoryManagerTypeExtensions
|
public static class MemoryManagerTypeExtensions
|
||||||
{
|
{
|
||||||
public static bool IsHostMapped(this MemoryManagerType type)
|
extension(MemoryManagerType type)
|
||||||
{
|
{
|
||||||
return type is MemoryManagerType.HostMapped or MemoryManagerType.HostMappedUnsafe;
|
public bool IsHostMapped => type is MemoryManagerType.HostMapped or MemoryManagerType.HostMappedUnsafe;
|
||||||
}
|
public bool IsHostTracked => type is MemoryManagerType.HostTracked or MemoryManagerType.HostTrackedUnsafe;
|
||||||
|
|
||||||
public static bool IsHostTracked(this MemoryManagerType type)
|
public bool IsHostMappedOrTracked => type.IsHostMapped || type.IsHostTracked;
|
||||||
{
|
|
||||||
return type is MemoryManagerType.HostTracked or MemoryManagerType.HostTrackedUnsafe;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsHostMappedOrTracked(this MemoryManagerType type)
|
|
||||||
{
|
|
||||||
return type.IsHostMapped() || type.IsHostTracked();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ namespace ARMeilleure
|
|||||||
public static bool AllowLcqInFunctionTable { get; set; } = true;
|
public static bool AllowLcqInFunctionTable { get; set; } = true;
|
||||||
public static bool UseUnmanagedDispatchLoop { get; set; } = true;
|
public static bool UseUnmanagedDispatchLoop { get; set; } = true;
|
||||||
public static bool EnableDebugging { get; set; } = false;
|
public static bool EnableDebugging { get; set; } = false;
|
||||||
|
public static bool EnableDeepCallRecursionProtection { get; set; } = true;
|
||||||
|
|
||||||
public static bool UseAdvSimdIfAvailable { get; set; } = true;
|
public static bool UseAdvSimdIfAvailable { get; set; } = true;
|
||||||
public static bool UseArm64AesIfAvailable { get; set; } = true;
|
public static bool UseArm64AesIfAvailable { get; set; } = true;
|
||||||
|
|||||||
@@ -134,6 +134,11 @@ namespace ARMeilleure.State
|
|||||||
public bool GetFPstateFlag(FPState flag) => _nativeContext.GetFPStateFlag(flag);
|
public bool GetFPstateFlag(FPState flag) => _nativeContext.GetFPStateFlag(flag);
|
||||||
public void SetFPstateFlag(FPState flag, bool value) => _nativeContext.SetFPStateFlag(flag, value);
|
public void SetFPstateFlag(FPState flag, bool value) => _nativeContext.SetFPStateFlag(flag, value);
|
||||||
|
|
||||||
|
internal void ResetCallDepth()
|
||||||
|
{
|
||||||
|
_nativeContext.ResetCallDepth();
|
||||||
|
}
|
||||||
|
|
||||||
internal void CheckInterrupt()
|
internal void CheckInterrupt()
|
||||||
{
|
{
|
||||||
if (Interrupted)
|
if (Interrupted)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ namespace ARMeilleure.State
|
|||||||
public ulong ExclusiveValueHigh;
|
public ulong ExclusiveValueHigh;
|
||||||
public int Running;
|
public int Running;
|
||||||
public long Tpidr2El0;
|
public long Tpidr2El0;
|
||||||
|
public int CallDepth;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Precise PC value used for debugging.
|
/// Precise PC value used for debugging.
|
||||||
@@ -199,6 +200,8 @@ namespace ARMeilleure.State
|
|||||||
public bool GetRunning() => GetStorage().Running != 0;
|
public bool GetRunning() => GetStorage().Running != 0;
|
||||||
public void SetRunning(bool value) => GetStorage().Running = value ? 1 : 0;
|
public void SetRunning(bool value) => GetStorage().Running = value ? 1 : 0;
|
||||||
|
|
||||||
|
public void ResetCallDepth() => GetStorage().CallDepth = 0;
|
||||||
|
|
||||||
public unsafe static int GetRegisterOffset(Register reg)
|
public unsafe static int GetRegisterOffset(Register reg)
|
||||||
{
|
{
|
||||||
if (reg.Type == RegisterType.Integer)
|
if (reg.Type == RegisterType.Integer)
|
||||||
@@ -284,6 +287,11 @@ namespace ARMeilleure.State
|
|||||||
return StorageOffset(ref _dummyStorage, ref _dummyStorage.DebugPrecisePc);
|
return StorageOffset(ref _dummyStorage, ref _dummyStorage.DebugPrecisePc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int GetCallDepthOffset()
|
||||||
|
{
|
||||||
|
return StorageOffset(ref _dummyStorage, ref _dummyStorage.CallDepth);
|
||||||
|
}
|
||||||
|
|
||||||
private static int StorageOffset<T>(ref NativeCtxStorage storage, ref T target)
|
private static int StorageOffset<T>(ref NativeCtxStorage storage, ref T target)
|
||||||
{
|
{
|
||||||
return (int)Unsafe.ByteOffset(ref Unsafe.As<NativeCtxStorage, T>(ref storage), ref target);
|
return (int)Unsafe.ByteOffset(ref Unsafe.As<NativeCtxStorage, T>(ref storage), ref target);
|
||||||
|
|||||||
@@ -361,10 +361,7 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
IntervalTreeNode<TK, TV> tmp = LeftOf(replacementNode) ?? RightOf(replacementNode);
|
IntervalTreeNode<TK, TV> tmp = LeftOf(replacementNode) ?? RightOf(replacementNode);
|
||||||
|
|
||||||
if (tmp != null)
|
tmp?.Parent = ParentOf(replacementNode);
|
||||||
{
|
|
||||||
tmp.Parent = ParentOf(replacementNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ParentOf(replacementNode) == null)
|
if (ParentOf(replacementNode) == null)
|
||||||
{
|
{
|
||||||
@@ -582,10 +579,7 @@ namespace ARMeilleure.Translation
|
|||||||
{
|
{
|
||||||
IntervalTreeNode<TK, TV> right = RightOf(node);
|
IntervalTreeNode<TK, TV> right = RightOf(node);
|
||||||
node.Right = LeftOf(right);
|
node.Right = LeftOf(right);
|
||||||
if (node.Right != null)
|
node.Right?.Parent = node;
|
||||||
{
|
|
||||||
node.Right.Parent = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
IntervalTreeNode<TK, TV> nodeParent = ParentOf(node);
|
IntervalTreeNode<TK, TV> nodeParent = ParentOf(node);
|
||||||
right.Parent = nodeParent;
|
right.Parent = nodeParent;
|
||||||
@@ -615,10 +609,7 @@ namespace ARMeilleure.Translation
|
|||||||
{
|
{
|
||||||
IntervalTreeNode<TK, TV> left = LeftOf(node);
|
IntervalTreeNode<TK, TV> left = LeftOf(node);
|
||||||
node.Left = RightOf(left);
|
node.Left = RightOf(left);
|
||||||
if (node.Left != null)
|
node.Left?.Parent = node;
|
||||||
{
|
|
||||||
node.Left.Parent = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
IntervalTreeNode<TK, TV> nodeParent = ParentOf(node);
|
IntervalTreeNode<TK, TV> nodeParent = ParentOf(node);
|
||||||
left.Parent = nodeParent;
|
left.Parent = nodeParent;
|
||||||
@@ -667,10 +658,7 @@ namespace ARMeilleure.Translation
|
|||||||
/// <param name="color">Color (Boolean)</param>
|
/// <param name="color">Color (Boolean)</param>
|
||||||
private static void SetColor(IntervalTreeNode<TK, TV> node, bool color)
|
private static void SetColor(IntervalTreeNode<TK, TV> node, bool color)
|
||||||
{
|
{
|
||||||
if (node != null)
|
node?.Color = color;
|
||||||
{
|
|
||||||
node.Color = color;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
||||||
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
||||||
|
|
||||||
private const uint InternalVersion = 7009; //! To be incremented manually for each change to the ARMeilleure project.
|
private const uint InternalVersion = 7010; //! To be incremented manually for each change to the ARMeilleure project.
|
||||||
|
|
||||||
private const string ActualDir = "0";
|
private const string ActualDir = "0";
|
||||||
private const string BackupDir = "1";
|
private const string BackupDir = "1";
|
||||||
|
|||||||
@@ -186,6 +186,7 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
Statistics.StartTimer();
|
Statistics.StartTimer();
|
||||||
|
|
||||||
|
context.ResetCallDepth();
|
||||||
ulong nextAddr = func.Execute(Stubs.ContextWrapper, context);
|
ulong nextAddr = func.Execute(Stubs.ContextWrapper, context);
|
||||||
|
|
||||||
Statistics.StopTimer(address);
|
Statistics.StopTimer(address);
|
||||||
@@ -260,6 +261,7 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
Logger.StartPass(PassName.Translation);
|
Logger.StartPass(PassName.Translation);
|
||||||
|
|
||||||
|
InstEmitFlowHelper.EmitCallDepthCheckAndIncrement(context, Const(address));
|
||||||
EmitSynchronization(context);
|
EmitSynchronization(context);
|
||||||
|
|
||||||
if (blocks[0].Address != address)
|
if (blocks[0].Address != address)
|
||||||
@@ -412,7 +414,7 @@ namespace ARMeilleure.Translation
|
|||||||
{
|
{
|
||||||
context.SyncQcFlag();
|
context.SyncQcFlag();
|
||||||
|
|
||||||
if (block.Branch != null && !block.Branch.Exit && block.Branch.Address <= block.Address)
|
if (block.Branch is { Exit: false } && block.Branch.Address <= block.Address)
|
||||||
{
|
{
|
||||||
EmitSynchronization(context);
|
EmitSynchronization(context);
|
||||||
}
|
}
|
||||||
@@ -429,14 +431,14 @@ namespace ARMeilleure.Translation
|
|||||||
{
|
{
|
||||||
lblPredicateSkip = Label();
|
lblPredicateSkip = Label();
|
||||||
|
|
||||||
InstEmitFlowHelper.EmitCondBranch(context, lblPredicateSkip, context.CurrentIfThenBlockCond.Invert());
|
InstEmitFlowHelper.EmitCondBranch(context, lblPredicateSkip, context.CurrentIfThenBlockCond.Inverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opCode is OpCode32 op && op.Cond < Condition.Al)
|
if (opCode is OpCode32 { Cond: < Condition.Al } op)
|
||||||
{
|
{
|
||||||
lblPredicateSkip = Label();
|
lblPredicateSkip = Label();
|
||||||
|
|
||||||
InstEmitFlowHelper.EmitCondBranch(context, lblPredicateSkip, op.Cond.Invert());
|
InstEmitFlowHelper.EmitCondBranch(context, lblPredicateSkip, op.Cond.Inverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opCode.Instruction.Emitter != null)
|
if (opCode.Instruction.Emitter != null)
|
||||||
|
|||||||
@@ -262,10 +262,18 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
Operand runningAddress = context.Add(nativeContext, Const((ulong)NativeContext.GetRunningOffset()));
|
Operand runningAddress = context.Add(nativeContext, Const((ulong)NativeContext.GetRunningOffset()));
|
||||||
Operand dispatchAddress = context.Add(nativeContext, Const((ulong)NativeContext.GetDispatchAddressOffset()));
|
Operand dispatchAddress = context.Add(nativeContext, Const((ulong)NativeContext.GetDispatchAddressOffset()));
|
||||||
|
Operand callDepthAddress = context.Add(nativeContext, Const((ulong)NativeContext.GetCallDepthOffset()));
|
||||||
|
|
||||||
EmitSyncFpContext(context, nativeContext, true);
|
EmitSyncFpContext(context, nativeContext, true);
|
||||||
|
|
||||||
context.MarkLabel(beginLbl);
|
context.MarkLabel(beginLbl);
|
||||||
|
|
||||||
|
if (Optimizations.EnableDeepCallRecursionProtection)
|
||||||
|
{
|
||||||
|
// Reset the call depth counter, since this is our first guest function call.
|
||||||
|
context.Store(callDepthAddress, Const(0));
|
||||||
|
}
|
||||||
|
|
||||||
context.Store(dispatchAddress, guestAddress);
|
context.Store(dispatchAddress, guestAddress);
|
||||||
context.Copy(guestAddress, context.Call(Const((ulong)DispatchStub), OperandType.I64, nativeContext));
|
context.Copy(guestAddress, context.Call(Const((ulong)DispatchStub), OperandType.I64, nativeContext));
|
||||||
context.BranchIfFalse(endLbl, guestAddress);
|
context.BranchIfFalse(endLbl, guestAddress);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Ryujinx.Audio\Ryujinx.Audio.csproj" />
|
<ProjectReference Include="..\Ryujinx.Audio\Ryujinx.Audio.csproj" />
|
||||||
<ProjectReference Include="..\Ryujinx.SDL2.Common\Ryujinx.SDL2.Common.csproj" />
|
<ProjectReference Include="..\Ryujinx.SDL3.Common\Ryujinx.SDL3.Common.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
namespace Ryujinx.Audio.Backends.SDL2
|
namespace Ryujinx.Audio.Backends.SDL3
|
||||||
{
|
{
|
||||||
class SDL2AudioBuffer
|
class SDL3AudioBuffer
|
||||||
{
|
{
|
||||||
public readonly ulong DriverIdentifier;
|
public readonly ulong DriverIdentifier;
|
||||||
public readonly ulong SampleCount;
|
public readonly ulong SampleCount;
|
||||||
public ulong SamplePlayed;
|
public ulong SamplePlayed;
|
||||||
|
|
||||||
public SDL2AudioBuffer(ulong driverIdentifier, ulong sampleCount)
|
public SDL3AudioBuffer(ulong driverIdentifier, ulong sampleCount)
|
||||||
{
|
{
|
||||||
DriverIdentifier = driverIdentifier;
|
DriverIdentifier = driverIdentifier;
|
||||||
SampleCount = sampleCount;
|
SampleCount = sampleCount;
|
||||||
@@ -2,42 +2,41 @@ using Ryujinx.Audio.Common;
|
|||||||
using Ryujinx.Audio.Integration;
|
using Ryujinx.Audio.Integration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using Ryujinx.SDL2.Common;
|
using Ryujinx.SDL3.Common;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using static Ryujinx.Audio.Integration.IHardwareDeviceDriver;
|
using static Ryujinx.Audio.Integration.IHardwareDeviceDriver;
|
||||||
using static SDL2.SDL;
|
using SDL;
|
||||||
|
using static SDL.SDL3;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Backends.SDL2
|
|
||||||
|
namespace Ryujinx.Audio.Backends.SDL3
|
||||||
{
|
{
|
||||||
public class SDL2HardwareDeviceDriver : IHardwareDeviceDriver
|
|
||||||
|
using unsafe SDL_AudioStreamCallbackPointer = delegate* unmanaged[Cdecl]<nint, SDL_AudioStream*, int, int, void>;
|
||||||
|
|
||||||
|
public class SDL3HardwareDeviceDriver : IHardwareDeviceDriver
|
||||||
{
|
{
|
||||||
private readonly ManualResetEvent _updateRequiredEvent;
|
private readonly ManualResetEvent _updateRequiredEvent;
|
||||||
private readonly ManualResetEvent _pauseEvent;
|
private readonly ManualResetEvent _pauseEvent;
|
||||||
private readonly ConcurrentDictionary<SDL2HardwareDeviceSession, byte> _sessions;
|
private readonly ConcurrentDictionary<SDL3HardwareDeviceSession, byte> _sessions;
|
||||||
|
|
||||||
private readonly bool _supportSurroundConfiguration;
|
private readonly bool _supportSurroundConfiguration;
|
||||||
|
|
||||||
public float Volume { get; set; }
|
public float Volume { get; set; }
|
||||||
|
|
||||||
// TODO: Add this to SDL2-CS
|
public unsafe SDL3HardwareDeviceDriver()
|
||||||
// NOTE: We use a DllImport here because of marshaling issue for spec.
|
|
||||||
[DllImport("SDL2")]
|
|
||||||
private static extern int SDL_GetDefaultAudioInfo(nint name, out SDL_AudioSpec spec, int isCapture);
|
|
||||||
|
|
||||||
public SDL2HardwareDeviceDriver()
|
|
||||||
{
|
{
|
||||||
_updateRequiredEvent = new ManualResetEvent(false);
|
_updateRequiredEvent = new ManualResetEvent(false);
|
||||||
_pauseEvent = new ManualResetEvent(true);
|
_pauseEvent = new ManualResetEvent(true);
|
||||||
_sessions = new ConcurrentDictionary<SDL2HardwareDeviceSession, byte>();
|
_sessions = new ConcurrentDictionary<SDL3HardwareDeviceSession, byte>();
|
||||||
|
|
||||||
SDL2Driver.Instance.Initialize();
|
SDL3Driver.Instance.Initialize();
|
||||||
|
|
||||||
int res = SDL_GetDefaultAudioInfo(nint.Zero, out SDL_AudioSpec spec, 0);
|
SDL_AudioSpec spec;
|
||||||
|
if (!SDL_GetAudioDeviceFormat(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, null))
|
||||||
if (res != 0)
|
|
||||||
{
|
{
|
||||||
Logger.Error?.Print(LogClass.Application,
|
Logger.Error?.Print(LogClass.Application,
|
||||||
$"SDL_GetDefaultAudioInfo failed with error \"{SDL_GetError()}\"");
|
$"SDL_GetDefaultAudioInfo failed with error \"{SDL_GetError()}\"");
|
||||||
@@ -54,16 +53,16 @@ namespace Ryujinx.Audio.Backends.SDL2
|
|||||||
|
|
||||||
public static bool IsSupported => IsSupportedInternal();
|
public static bool IsSupported => IsSupportedInternal();
|
||||||
|
|
||||||
private static bool IsSupportedInternal()
|
private unsafe static bool IsSupportedInternal()
|
||||||
{
|
{
|
||||||
uint device = OpenStream(SampleFormat.PcmInt16, Constants.TargetSampleRate, Constants.ChannelCountMax, Constants.TargetSampleCount, null);
|
SDL_AudioStream* device = OpenStream(SampleFormat.PcmInt16, Constants.TargetSampleRate, Constants.ChannelCountMax, Constants.TargetSampleCount, null);
|
||||||
|
|
||||||
if (device != 0)
|
if (device != null)
|
||||||
{
|
{
|
||||||
SDL_CloseAudioDevice(device);
|
SDL_DestroyAudioStream(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
return device != 0;
|
return device != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ManualResetEvent GetUpdateRequiredEvent()
|
public ManualResetEvent GetUpdateRequiredEvent()
|
||||||
@@ -90,67 +89,68 @@ namespace Ryujinx.Audio.Backends.SDL2
|
|||||||
|
|
||||||
if (direction != Direction.Output)
|
if (direction != Direction.Output)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException("Input direction is currently not implemented on SDL2 backend!");
|
throw new NotImplementedException("Input direction is currently not implemented on SDL3 backend!");
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL2HardwareDeviceSession session = new(this, memoryManager, sampleFormat, sampleRate, channelCount);
|
SDL3HardwareDeviceSession session = new(this, memoryManager, sampleFormat, sampleRate, channelCount);
|
||||||
|
|
||||||
_sessions.TryAdd(session, 0);
|
_sessions.TryAdd(session, 0);
|
||||||
|
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool Unregister(SDL2HardwareDeviceSession session)
|
internal bool Unregister(SDL3HardwareDeviceSession session)
|
||||||
{
|
{
|
||||||
return _sessions.TryRemove(session, out _);
|
return _sessions.TryRemove(session, out _);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SDL_AudioSpec GetSDL2Spec(SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount, uint sampleCount)
|
private static SDL_AudioSpec GetSDL3Spec(SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount)
|
||||||
{
|
{
|
||||||
return new SDL_AudioSpec
|
return new SDL_AudioSpec
|
||||||
{
|
{
|
||||||
channels = (byte)requestedChannelCount,
|
channels = (byte)requestedChannelCount,
|
||||||
format = GetSDL2Format(requestedSampleFormat),
|
format = GetSDL3Format(requestedSampleFormat),
|
||||||
freq = (int)requestedSampleRate,
|
freq = (int)requestedSampleRate,
|
||||||
samples = (ushort)sampleCount,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static ushort GetSDL2Format(SampleFormat format)
|
internal static SDL_AudioFormat GetSDL3Format(SampleFormat format)
|
||||||
{
|
{
|
||||||
return format switch
|
return format switch
|
||||||
{
|
{
|
||||||
SampleFormat.PcmInt8 => AUDIO_S8,
|
SampleFormat.PcmInt8 => SDL_AudioFormat.SDL_AUDIO_S8,
|
||||||
SampleFormat.PcmInt16 => AUDIO_S16,
|
SampleFormat.PcmInt16 => SDL_AudioFormat.SDL_AUDIO_S16LE,
|
||||||
SampleFormat.PcmInt32 => AUDIO_S32,
|
SampleFormat.PcmInt32 => SDL_AudioFormat.SDL_AUDIO_S32LE,
|
||||||
SampleFormat.PcmFloat => AUDIO_F32,
|
SampleFormat.PcmFloat => SDL_AudioFormat.SDL_AUDIO_F32LE,
|
||||||
_ => throw new ArgumentException($"Unsupported sample format {format}"),
|
_ => throw new ArgumentException($"Unsupported sample format {format}"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static uint OpenStream(SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount, uint sampleCount, SDL_AudioCallback callback)
|
internal unsafe static SDL_AudioStream* OpenStream(SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount, uint sampleCount, SDL3HardwareDeviceSession.SDL_AudioStreamCallback callback)
|
||||||
{
|
{
|
||||||
SDL_AudioSpec desired = GetSDL2Spec(requestedSampleFormat, requestedSampleRate, requestedChannelCount, sampleCount);
|
SDL_AudioSpec desired = GetSDL3Spec(requestedSampleFormat, requestedSampleRate, requestedChannelCount);
|
||||||
|
SDL_AudioSpec got = desired;
|
||||||
|
var pCallback = callback != null ? (SDL_AudioStreamCallbackPointer)Marshal.GetFunctionPointerForDelegate(callback) : null;
|
||||||
|
|
||||||
desired.callback = callback;
|
// From SDL 3 and on, SDL requires us to set this as a hint
|
||||||
|
SDL_SetHint(SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES, $"{sampleCount}");
|
||||||
|
SDL_AudioStream* device = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &got, pCallback, 0);
|
||||||
|
|
||||||
uint device = SDL_OpenAudioDevice(nint.Zero, 0, ref desired, out SDL_AudioSpec got, 0);
|
if (device == null)
|
||||||
|
|
||||||
if (device == 0)
|
|
||||||
{
|
{
|
||||||
Logger.Error?.Print(LogClass.Application, $"SDL2 open audio device initialization failed with error \"{SDL_GetError()}\"");
|
Logger.Error?.Print(LogClass.Application, $"SDL3 open audio device initialization failed with error \"{SDL_GetError()}\"");
|
||||||
|
|
||||||
return 0;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isValid = got.format == desired.format && got.freq == desired.freq && got.channels == desired.channels;
|
bool isValid = got.format == desired.format && got.freq == desired.freq && got.channels == desired.channels;
|
||||||
|
|
||||||
if (!isValid)
|
if (!isValid)
|
||||||
{
|
{
|
||||||
Logger.Error?.Print(LogClass.Application, "SDL2 open audio device is not valid");
|
Logger.Error?.Print(LogClass.Application, "SDL3 open audio device is not valid");
|
||||||
SDL_CloseAudioDevice(device);
|
SDL_DestroyAudioStream(device);
|
||||||
|
|
||||||
return 0;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return device;
|
return device;
|
||||||
@@ -166,12 +166,12 @@ namespace Ryujinx.Audio.Backends.SDL2
|
|||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
foreach (SDL2HardwareDeviceSession session in _sessions.Keys)
|
foreach (SDL3HardwareDeviceSession session in _sessions.Keys)
|
||||||
{
|
{
|
||||||
session.Dispose();
|
session.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL2Driver.Instance.Dispose();
|
SDL3Driver.Instance.Dispose();
|
||||||
|
|
||||||
_pauseEvent.Dispose();
|
_pauseEvent.Dispose();
|
||||||
}
|
}
|
||||||
@@ -6,36 +6,43 @@ using Ryujinx.Memory;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using SDL;
|
||||||
|
using static SDL.SDL3;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
using static SDL2.SDL;
|
namespace Ryujinx.Audio.Backends.SDL3
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Backends.SDL2
|
|
||||||
{
|
{
|
||||||
class SDL2HardwareDeviceSession : HardwareDeviceSessionOutputBase
|
|
||||||
|
|
||||||
|
|
||||||
|
unsafe class SDL3HardwareDeviceSession : HardwareDeviceSessionOutputBase
|
||||||
{
|
{
|
||||||
private readonly SDL2HardwareDeviceDriver _driver;
|
private readonly SDL3HardwareDeviceDriver _driver;
|
||||||
private readonly ConcurrentQueue<SDL2AudioBuffer> _queuedBuffers;
|
private readonly ConcurrentQueue<SDL3AudioBuffer> _queuedBuffers;
|
||||||
private readonly DynamicRingBuffer _ringBuffer;
|
private readonly DynamicRingBuffer _ringBuffer;
|
||||||
private ulong _playedSampleCount;
|
private ulong _playedSampleCount;
|
||||||
private readonly ManualResetEvent _updateRequiredEvent;
|
private readonly ManualResetEvent _updateRequiredEvent;
|
||||||
private uint _outputStream;
|
private SDL_AudioStream* _outputStream;
|
||||||
private bool _hasSetupError;
|
private bool _hasSetupError;
|
||||||
private readonly SDL_AudioCallback _callbackDelegate;
|
private readonly SDL_AudioStreamCallback _callbackDelegate;
|
||||||
private readonly int _bytesPerFrame;
|
private readonly int _bytesPerFrame;
|
||||||
private uint _sampleCount;
|
private uint _sampleCount;
|
||||||
private bool _started;
|
private bool _started;
|
||||||
private float _volume;
|
private float _volume;
|
||||||
private readonly ushort _nativeSampleFormat;
|
private readonly SDL_AudioFormat _nativeSampleFormat;
|
||||||
|
|
||||||
public SDL2HardwareDeviceSession(SDL2HardwareDeviceDriver driver, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount) : base(memoryManager, requestedSampleFormat, requestedSampleRate, requestedChannelCount)
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
internal delegate void SDL_AudioStreamCallback(nint session, SDL_AudioStream* stream, int stream_count, int device_count);
|
||||||
|
|
||||||
|
public SDL3HardwareDeviceSession(SDL3HardwareDeviceDriver driver, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount) : base(memoryManager, requestedSampleFormat, requestedSampleRate, requestedChannelCount)
|
||||||
{
|
{
|
||||||
_driver = driver;
|
_driver = driver;
|
||||||
_updateRequiredEvent = _driver.GetUpdateRequiredEvent();
|
_updateRequiredEvent = _driver.GetUpdateRequiredEvent();
|
||||||
_queuedBuffers = new ConcurrentQueue<SDL2AudioBuffer>();
|
_queuedBuffers = new ConcurrentQueue<SDL3AudioBuffer>();
|
||||||
_ringBuffer = new DynamicRingBuffer();
|
_ringBuffer = new DynamicRingBuffer();
|
||||||
_callbackDelegate = Update;
|
_callbackDelegate = Update;
|
||||||
_bytesPerFrame = BackendHelper.GetSampleSize(RequestedSampleFormat) * (int)RequestedChannelCount;
|
_bytesPerFrame = BackendHelper.GetSampleSize(RequestedSampleFormat) * (int)RequestedChannelCount;
|
||||||
_nativeSampleFormat = SDL2HardwareDeviceDriver.GetSDL2Format(RequestedSampleFormat);
|
_nativeSampleFormat = SDL3HardwareDeviceDriver.GetSDL3Format(RequestedSampleFormat);
|
||||||
_sampleCount = uint.MaxValue;
|
_sampleCount = uint.MaxValue;
|
||||||
_started = false;
|
_started = false;
|
||||||
_volume = 1f;
|
_volume = 1f;
|
||||||
@@ -44,45 +51,51 @@ namespace Ryujinx.Audio.Backends.SDL2
|
|||||||
private void EnsureAudioStreamSetup(AudioBuffer buffer)
|
private void EnsureAudioStreamSetup(AudioBuffer buffer)
|
||||||
{
|
{
|
||||||
uint bufferSampleCount = (uint)GetSampleCount(buffer);
|
uint bufferSampleCount = (uint)GetSampleCount(buffer);
|
||||||
bool needAudioSetup = (_outputStream == 0 && !_hasSetupError) ||
|
bool needAudioSetup = (_outputStream == null && !_hasSetupError) ||
|
||||||
(bufferSampleCount >= Constants.TargetSampleCount && bufferSampleCount < _sampleCount);
|
(bufferSampleCount >= Constants.TargetSampleCount && bufferSampleCount < _sampleCount);
|
||||||
|
|
||||||
if (needAudioSetup)
|
if (needAudioSetup)
|
||||||
{
|
{
|
||||||
_sampleCount = Math.Max(Constants.TargetSampleCount, bufferSampleCount);
|
_sampleCount = Math.Max(Constants.TargetSampleCount, bufferSampleCount);
|
||||||
|
|
||||||
uint newOutputStream = SDL2HardwareDeviceDriver.OpenStream(RequestedSampleFormat, RequestedSampleRate, RequestedChannelCount, _sampleCount, _callbackDelegate);
|
SDL_AudioStream* newOutputStream = SDL3HardwareDeviceDriver.OpenStream(RequestedSampleFormat, RequestedSampleRate, RequestedChannelCount, _sampleCount, _callbackDelegate);
|
||||||
|
|
||||||
_hasSetupError = newOutputStream == 0;
|
_hasSetupError = newOutputStream == null;
|
||||||
|
|
||||||
if (!_hasSetupError)
|
if (!_hasSetupError)
|
||||||
{
|
{
|
||||||
if (_outputStream != 0)
|
if (_outputStream != null)
|
||||||
{
|
{
|
||||||
SDL_CloseAudioDevice(_outputStream);
|
SDL_DestroyAudioStream(_outputStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
_outputStream = newOutputStream;
|
_outputStream = newOutputStream;
|
||||||
|
|
||||||
SDL_PauseAudioDevice(_outputStream, _started ? 0 : 1);
|
if (_started) {
|
||||||
|
SDL_ResumeAudioStreamDevice(_outputStream);
|
||||||
|
} else {
|
||||||
|
SDL_PauseAudioStreamDevice(_outputStream);
|
||||||
|
}
|
||||||
|
|
||||||
Logger.Info?.Print(LogClass.Audio, $"New audio stream setup with a target sample count of {_sampleCount}");
|
Logger.Info?.Print(LogClass.Audio, $"New audio stream setup with a target sample count of {_sampleCount}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void Update(nint userdata, nint stream, int streamLength)
|
private unsafe void Update(nint userdata, SDL_AudioStream* streamDevice, int additionalAmount, int totalAmmount)
|
||||||
{
|
{
|
||||||
Span<byte> streamSpan = new((void*)stream, streamLength);
|
using SpanOwner<byte> stream = SpanOwner<byte>.Rent(additionalAmount);
|
||||||
|
Span<byte> streamSpan = stream.Span;
|
||||||
|
|
||||||
int maxFrameCount = (int)GetSampleCount(streamLength);
|
|
||||||
|
int maxFrameCount = (int)GetSampleCount(additionalAmount);
|
||||||
int bufferedFrames = _ringBuffer.Length / _bytesPerFrame;
|
int bufferedFrames = _ringBuffer.Length / _bytesPerFrame;
|
||||||
|
|
||||||
int frameCount = Math.Min(bufferedFrames, maxFrameCount);
|
int frameCount = Math.Min(bufferedFrames, maxFrameCount);
|
||||||
|
|
||||||
if (frameCount == 0)
|
if (frameCount == 0)
|
||||||
{
|
{
|
||||||
// SDL2 left the responsibility to the user to clear the buffer.
|
// SDL3 left the responsibility to the user to clear the buffer.
|
||||||
streamSpan.Clear();
|
streamSpan.Clear();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -94,15 +107,17 @@ namespace Ryujinx.Audio.Backends.SDL2
|
|||||||
|
|
||||||
_ringBuffer.Read(samples, 0, samples.Length);
|
_ringBuffer.Read(samples, 0, samples.Length);
|
||||||
|
|
||||||
fixed (byte* p = samples)
|
// Zero the dest buffer
|
||||||
{
|
streamSpan.Clear();
|
||||||
nint pStreamSrc = (nint)p;
|
|
||||||
|
|
||||||
// Zero the dest buffer
|
fixed (byte* pStreamDst = streamSpan) {
|
||||||
streamSpan.Clear();
|
fixed (byte* pStreamSrc = samples)
|
||||||
|
{
|
||||||
|
|
||||||
// Apply volume to written data
|
// Apply volume to written data
|
||||||
SDL_MixAudioFormat(stream, pStreamSrc, _nativeSampleFormat, (uint)samples.Length, (int)(_driver.Volume * _volume * SDL_MIX_MAXVOLUME));
|
SDL_MixAudio(pStreamDst, pStreamSrc, _nativeSampleFormat, (uint)samples.Length, _driver.Volume * _volume);
|
||||||
|
SDL_PutAudioStreamData(streamDevice, (nint)pStreamDst, additionalAmount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong sampleCount = GetSampleCount(samples.Length);
|
ulong sampleCount = GetSampleCount(samples.Length);
|
||||||
@@ -111,7 +126,7 @@ namespace Ryujinx.Audio.Backends.SDL2
|
|||||||
|
|
||||||
bool needUpdate = false;
|
bool needUpdate = false;
|
||||||
|
|
||||||
while (availaibleSampleCount > 0 && _queuedBuffers.TryPeek(out SDL2AudioBuffer driverBuffer))
|
while (availaibleSampleCount > 0 && _queuedBuffers.TryPeek(out SDL3AudioBuffer driverBuffer))
|
||||||
{
|
{
|
||||||
ulong sampleStillNeeded = driverBuffer.SampleCount - Interlocked.Read(ref driverBuffer.SamplePlayed);
|
ulong sampleStillNeeded = driverBuffer.SampleCount - Interlocked.Read(ref driverBuffer.SamplePlayed);
|
||||||
ulong playedAudioBufferSampleCount = Math.Min(sampleStillNeeded, availaibleSampleCount);
|
ulong playedAudioBufferSampleCount = Math.Min(sampleStillNeeded, availaibleSampleCount);
|
||||||
@@ -152,9 +167,9 @@ namespace Ryujinx.Audio.Backends.SDL2
|
|||||||
{
|
{
|
||||||
EnsureAudioStreamSetup(buffer);
|
EnsureAudioStreamSetup(buffer);
|
||||||
|
|
||||||
if (_outputStream != 0)
|
if (_outputStream != null)
|
||||||
{
|
{
|
||||||
SDL2AudioBuffer driverBuffer = new(buffer.DataPointer, GetSampleCount(buffer));
|
SDL3AudioBuffer driverBuffer = new(buffer.DataPointer, GetSampleCount(buffer));
|
||||||
|
|
||||||
_ringBuffer.Write(buffer.Data, 0, buffer.Data.Length);
|
_ringBuffer.Write(buffer.Data, 0, buffer.Data.Length);
|
||||||
|
|
||||||
@@ -177,9 +192,9 @@ namespace Ryujinx.Audio.Backends.SDL2
|
|||||||
{
|
{
|
||||||
if (!_started)
|
if (!_started)
|
||||||
{
|
{
|
||||||
if (_outputStream != 0)
|
if (_outputStream != null)
|
||||||
{
|
{
|
||||||
SDL_PauseAudioDevice(_outputStream, 0);
|
SDL_ResumeAudioStreamDevice(_outputStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
_started = true;
|
_started = true;
|
||||||
@@ -190,9 +205,9 @@ namespace Ryujinx.Audio.Backends.SDL2
|
|||||||
{
|
{
|
||||||
if (_started)
|
if (_started)
|
||||||
{
|
{
|
||||||
if (_outputStream != 0)
|
if (_outputStream != null)
|
||||||
{
|
{
|
||||||
SDL_PauseAudioDevice(_outputStream, 1);
|
SDL_PauseAudioStreamDevice(_outputStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
_started = false;
|
_started = false;
|
||||||
@@ -203,7 +218,7 @@ namespace Ryujinx.Audio.Backends.SDL2
|
|||||||
|
|
||||||
public override bool WasBufferFullyConsumed(AudioBuffer buffer)
|
public override bool WasBufferFullyConsumed(AudioBuffer buffer)
|
||||||
{
|
{
|
||||||
if (!_queuedBuffers.TryPeek(out SDL2AudioBuffer driverBuffer))
|
if (!_queuedBuffers.TryPeek(out SDL3AudioBuffer driverBuffer))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -218,9 +233,9 @@ namespace Ryujinx.Audio.Backends.SDL2
|
|||||||
PrepareToClose();
|
PrepareToClose();
|
||||||
Stop();
|
Stop();
|
||||||
|
|
||||||
if (_outputStream != 0)
|
if (_outputStream != null)
|
||||||
{
|
{
|
||||||
SDL_CloseAudioDevice(_outputStream);
|
SDL_DestroyAudioStream(_outputStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,16 +58,16 @@ namespace Ryujinx.Audio.Backends.CompatLayer
|
|||||||
switch (realSampleFormat)
|
switch (realSampleFormat)
|
||||||
{
|
{
|
||||||
case SampleFormat.PcmInt8:
|
case SampleFormat.PcmInt8:
|
||||||
PcmHelper.ConvertSampleToPcm8(MemoryMarshal.Cast<byte, sbyte>(convertedSamples), samples);
|
PcmHelper.ConvertSampleToPcm8(MemoryMarshal.Cast<byte, sbyte>(new Span<byte>(convertedSamples)), samples);
|
||||||
break;
|
break;
|
||||||
case SampleFormat.PcmInt24:
|
case SampleFormat.PcmInt24:
|
||||||
PcmHelper.ConvertSampleToPcm24(convertedSamples, samples);
|
PcmHelper.ConvertSampleToPcm24(convertedSamples, samples);
|
||||||
break;
|
break;
|
||||||
case SampleFormat.PcmInt32:
|
case SampleFormat.PcmInt32:
|
||||||
PcmHelper.ConvertSampleToPcm32(MemoryMarshal.Cast<byte, int>(convertedSamples), samples);
|
PcmHelper.ConvertSampleToPcm32(MemoryMarshal.Cast<byte, int>(new Span<byte>(convertedSamples)), samples);
|
||||||
break;
|
break;
|
||||||
case SampleFormat.PcmFloat:
|
case SampleFormat.PcmFloat:
|
||||||
PcmHelper.ConvertSampleToPcmFloat(MemoryMarshal.Cast<byte, float>(convertedSamples), samples);
|
PcmHelper.ConvertSampleToPcmFloat(MemoryMarshal.Cast<byte, float>(new Span<byte>(convertedSamples)), samples);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new NotImplementedException($"Sample format conversion from {_userSampleFormat} to {realSampleFormat} not implemented.");
|
throw new NotImplementedException($"Sample format conversion from {_userSampleFormat} to {realSampleFormat} not implemented.");
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ namespace Ryujinx.Audio.Integration
|
|||||||
|
|
||||||
public void AppendBuffer(ReadOnlySpan<short> data, uint channelCount)
|
public void AppendBuffer(ReadOnlySpan<short> data, uint channelCount)
|
||||||
{
|
{
|
||||||
data.CopyTo(MemoryMarshal.Cast<byte, short>(_buffer));
|
data.CopyTo(MemoryMarshal.Cast<byte, short>(new Span<byte>(_buffer)));
|
||||||
|
|
||||||
_session.QueueBuffer(new AudioBuffer
|
_session.QueueBuffer(new AudioBuffer
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,27 +11,32 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; }
|
public int NodeId { get; private set; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.AdpcmDataSourceVersion1;
|
public CommandType CommandType => CommandType.AdpcmDataSourceVersion1;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public ushort OutputBufferIndex { get; }
|
public ushort OutputBufferIndex { get; private set; }
|
||||||
public uint SampleRate { get; }
|
public uint SampleRate { get; private set; }
|
||||||
|
|
||||||
public float Pitch { get; }
|
public float Pitch { get; private set; }
|
||||||
|
|
||||||
public WaveBuffer[] WaveBuffers { get; }
|
public WaveBuffer[] WaveBuffers { get; }
|
||||||
|
|
||||||
public Memory<VoiceState> State { get; }
|
public Memory<VoiceState> State { get; private set; }
|
||||||
|
|
||||||
public ulong AdpcmParameter { get; }
|
public ulong AdpcmParameter { get; private set; }
|
||||||
public ulong AdpcmParameterSize { get; }
|
public ulong AdpcmParameterSize { get; private set; }
|
||||||
|
|
||||||
public DecodingBehaviour DecodingBehaviour { get; }
|
public DecodingBehaviour DecodingBehaviour { get; private set; }
|
||||||
|
|
||||||
public AdpcmDataSourceCommandVersion1(ref VoiceInfo serverInfo, Memory<VoiceState> state, ushort outputBufferIndex, int nodeId)
|
public AdpcmDataSourceCommandVersion1()
|
||||||
|
{
|
||||||
|
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
|
||||||
|
}
|
||||||
|
|
||||||
|
public AdpcmDataSourceCommandVersion1 Initialize(ref VoiceInfo serverInfo, Memory<VoiceState> state, ushort outputBufferIndex, int nodeId)
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
@@ -42,8 +47,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
Span<Server.Voice.WaveBuffer> waveBufferSpan = serverInfo.WaveBuffers.AsSpan();
|
Span<Server.Voice.WaveBuffer> waveBufferSpan = serverInfo.WaveBuffers.AsSpan();
|
||||||
|
|
||||||
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
|
|
||||||
|
|
||||||
for (int i = 0; i < WaveBuffers.Length; i++)
|
for (int i = 0; i < WaveBuffers.Length; i++)
|
||||||
{
|
{
|
||||||
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref waveBufferSpan[i];
|
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref waveBufferSpan[i];
|
||||||
@@ -55,6 +58,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
AdpcmParameterSize = serverInfo.DataSourceStateAddressInfo.Size;
|
AdpcmParameterSize = serverInfo.DataSourceStateAddressInfo.Size;
|
||||||
State = state;
|
State = state;
|
||||||
DecodingBehaviour = serverInfo.DecodingBehaviour;
|
DecodingBehaviour = serverInfo.DecodingBehaviour;
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
|
|||||||
@@ -12,26 +12,31 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; }
|
public int NodeId { get; private set; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.AuxiliaryBuffer;
|
public CommandType CommandType => CommandType.AuxiliaryBuffer;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public uint InputBufferIndex { get; }
|
public uint InputBufferIndex { get; private set; }
|
||||||
public uint OutputBufferIndex { get; }
|
public uint OutputBufferIndex { get; private set; }
|
||||||
|
|
||||||
public AuxiliaryBufferAddresses BufferInfo { get; }
|
public AuxiliaryBufferAddresses BufferInfo { get; private set; }
|
||||||
|
|
||||||
public CpuAddress InputBuffer { get; }
|
public CpuAddress InputBuffer { get; private set; }
|
||||||
public CpuAddress OutputBuffer { get; }
|
public CpuAddress OutputBuffer { get; private set; }
|
||||||
public uint CountMax { get; }
|
public uint CountMax { get; private set; }
|
||||||
public uint UpdateCount { get; }
|
public uint UpdateCount { get; private set; }
|
||||||
public uint WriteOffset { get; }
|
public uint WriteOffset { get; private set; }
|
||||||
|
|
||||||
public bool IsEffectEnabled { get; }
|
public bool IsEffectEnabled { get; private set; }
|
||||||
|
|
||||||
public AuxiliaryBufferCommand(
|
public AuxiliaryBufferCommand()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuxiliaryBufferCommand Initialize(
|
||||||
uint bufferOffset,
|
uint bufferOffset,
|
||||||
byte inputBufferOffset,
|
byte inputBufferOffset,
|
||||||
byte outputBufferOffset,
|
byte outputBufferOffset,
|
||||||
@@ -55,6 +60,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
UpdateCount = updateCount;
|
UpdateCount = updateCount;
|
||||||
WriteOffset = writeOffset;
|
WriteOffset = writeOffset;
|
||||||
IsEffectEnabled = isEnabled;
|
IsEffectEnabled = isEnabled;
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
@@ -9,32 +9,37 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; }
|
public int NodeId { get; private set; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.BiquadFilterAndMix;
|
public CommandType CommandType => CommandType.BiquadFilterAndMix;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public ushort InputBufferIndex { get; }
|
public ushort InputBufferIndex { get; private set; }
|
||||||
public ushort OutputBufferIndex { get; }
|
public ushort OutputBufferIndex { get; private set; }
|
||||||
|
|
||||||
private BiquadFilterParameter2 _parameter;
|
private BiquadFilterParameter2 _parameter;
|
||||||
|
|
||||||
public Memory<BiquadFilterState> BiquadFilterState { get; }
|
public Memory<BiquadFilterState> BiquadFilterState { get; private set; }
|
||||||
public Memory<BiquadFilterState> PreviousBiquadFilterState { get; }
|
public Memory<BiquadFilterState> PreviousBiquadFilterState { get; private set; }
|
||||||
|
|
||||||
public Memory<VoiceState> State { get; }
|
public Memory<VoiceState> State { get; private set; }
|
||||||
|
|
||||||
public int LastSampleIndex { get; }
|
public int LastSampleIndex { get; private set; }
|
||||||
|
|
||||||
public float Volume0 { get; }
|
public float Volume0 { get; private set; }
|
||||||
public float Volume1 { get; }
|
public float Volume1 { get; private set; }
|
||||||
|
|
||||||
public bool NeedInitialization { get; }
|
public bool NeedInitialization { get; private set; }
|
||||||
public bool HasVolumeRamp { get; }
|
public bool HasVolumeRamp { get; private set; }
|
||||||
public bool IsFirstMixBuffer { get; }
|
public bool IsFirstMixBuffer { get; private set; }
|
||||||
|
|
||||||
public BiquadFilterAndMixCommand(
|
public BiquadFilterAndMixCommand()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public BiquadFilterAndMixCommand Initialize(
|
||||||
float volume0,
|
float volume0,
|
||||||
float volume1,
|
float volume1,
|
||||||
uint inputBufferIndex,
|
uint inputBufferIndex,
|
||||||
@@ -68,6 +73,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
NeedInitialization = needInitialization;
|
NeedInitialization = needInitialization;
|
||||||
HasVolumeRamp = hasVolumeRamp;
|
HasVolumeRamp = hasVolumeRamp;
|
||||||
IsFirstMixBuffer = isFirstMixBuffer;
|
IsFirstMixBuffer = isFirstMixBuffer;
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
|
|||||||
@@ -8,20 +8,25 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; }
|
public int NodeId { get; private set; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.BiquadFilter;
|
public CommandType CommandType => CommandType.BiquadFilter;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public Memory<BiquadFilterState> BiquadFilterState { get; }
|
public Memory<BiquadFilterState> BiquadFilterState { get; private set; }
|
||||||
public int InputBufferIndex { get; }
|
public int InputBufferIndex { get; private set; }
|
||||||
public int OutputBufferIndex { get; }
|
public int OutputBufferIndex { get; private set; }
|
||||||
public bool NeedInitialization { get; }
|
public bool NeedInitialization { get; private set; }
|
||||||
|
|
||||||
private BiquadFilterParameter2 _parameter;
|
private BiquadFilterParameter2 _parameter;
|
||||||
|
|
||||||
public BiquadFilterCommand(
|
public BiquadFilterCommand()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public BiquadFilterCommand Initialize(
|
||||||
int baseIndex,
|
int baseIndex,
|
||||||
ref BiquadFilterParameter2 filter,
|
ref BiquadFilterParameter2 filter,
|
||||||
Memory<BiquadFilterState> biquadFilterStateMemory,
|
Memory<BiquadFilterState> biquadFilterStateMemory,
|
||||||
@@ -38,6 +43,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
|
|||||||
@@ -12,25 +12,30 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; }
|
public int NodeId { get; private set; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.CaptureBuffer;
|
public CommandType CommandType => CommandType.CaptureBuffer;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public uint InputBufferIndex { get; }
|
public uint InputBufferIndex { get; private set; }
|
||||||
|
|
||||||
public ulong CpuBufferInfoAddress { get; }
|
public ulong CpuBufferInfoAddress { get; private set; }
|
||||||
public ulong DspBufferInfoAddress { get; }
|
public ulong DspBufferInfoAddress { get; private set; }
|
||||||
|
|
||||||
public CpuAddress OutputBuffer { get; }
|
public CpuAddress OutputBuffer { get; private set; }
|
||||||
public uint CountMax { get; }
|
public uint CountMax { get; private set; }
|
||||||
public uint UpdateCount { get; }
|
public uint UpdateCount { get; private set; }
|
||||||
public uint WriteOffset { get; }
|
public uint WriteOffset { get; private set; }
|
||||||
|
|
||||||
public bool IsEffectEnabled { get; }
|
public bool IsEffectEnabled { get; private set; }
|
||||||
|
|
||||||
public CaptureBufferCommand(uint bufferOffset, byte inputBufferOffset, ulong sendBufferInfo, bool isEnabled,
|
public CaptureBufferCommand()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public CaptureBufferCommand Initialize(uint bufferOffset, byte inputBufferOffset, ulong sendBufferInfo, bool isEnabled,
|
||||||
uint countMax, CpuAddress outputBuffer, uint updateCount, uint writeOffset, int nodeId)
|
uint countMax, CpuAddress outputBuffer, uint updateCount, uint writeOffset, int nodeId)
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
@@ -43,6 +48,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
UpdateCount = updateCount;
|
UpdateCount = updateCount;
|
||||||
WriteOffset = writeOffset;
|
WriteOffset = writeOffset;
|
||||||
IsEffectEnabled = isEnabled;
|
IsEffectEnabled = isEnabled;
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
@@ -9,25 +9,29 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; }
|
public int NodeId { get; private set; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.CircularBufferSink;
|
public CommandType CommandType => CommandType.CircularBufferSink;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public ushort[] Input { get; }
|
public ushort[] Input { get; }
|
||||||
public uint InputCount { get; }
|
public uint InputCount { get; private set; }
|
||||||
|
|
||||||
public ulong CircularBuffer { get; }
|
public ulong CircularBuffer { get; private set; }
|
||||||
public ulong CircularBufferSize { get; }
|
public ulong CircularBufferSize { get; private set; }
|
||||||
public ulong CurrentOffset { get; }
|
public ulong CurrentOffset { get; private set; }
|
||||||
|
|
||||||
public CircularBufferSinkCommand(uint bufferOffset, ref CircularBufferParameter parameter, ref AddressInfo circularBufferAddressInfo, uint currentOffset, int nodeId)
|
public CircularBufferSinkCommand()
|
||||||
|
{
|
||||||
|
Input = new ushort[Constants.ChannelCountMax];
|
||||||
|
}
|
||||||
|
|
||||||
|
public CircularBufferSinkCommand Initialize(uint bufferOffset, ref CircularBufferParameter parameter, ref AddressInfo circularBufferAddressInfo, uint currentOffset, int nodeId)
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
|
|
||||||
Input = new ushort[Constants.ChannelCountMax];
|
|
||||||
InputCount = parameter.InputCount;
|
InputCount = parameter.InputCount;
|
||||||
|
|
||||||
Span<byte> inputSpan = parameter.Input.AsSpan();
|
Span<byte> inputSpan = parameter.Input.AsSpan();
|
||||||
@@ -42,6 +46,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
CurrentOffset = currentOffset;
|
CurrentOffset = currentOffset;
|
||||||
|
|
||||||
Debug.Assert(CircularBuffer != 0);
|
Debug.Assert(CircularBuffer != 0);
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
|
|||||||
@@ -4,16 +4,23 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; }
|
public int NodeId { get; private set; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.ClearMixBuffer;
|
public CommandType CommandType => CommandType.ClearMixBuffer;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public ClearMixBufferCommand(int nodeId)
|
public ClearMixBufferCommand()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClearMixBufferCommand Initialize(int nodeId)
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
public Memory<float> Buffers { get; }
|
public Memory<float> Buffers { get; }
|
||||||
public uint BufferCount { get; }
|
public uint BufferCount { get; }
|
||||||
|
|
||||||
|
private readonly static ObjectPool<List<ICommand>> CommandsListPool = new(() => new List<ICommand>(256));
|
||||||
public List<ICommand> Commands { get; }
|
public List<ICommand> Commands { get; }
|
||||||
|
|
||||||
public IVirtualMemoryManager MemoryManager { get; }
|
public IVirtualMemoryManager MemoryManager { get; }
|
||||||
@@ -46,7 +47,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
SampleRate = sampleRate;
|
SampleRate = sampleRate;
|
||||||
BufferCount = mixBufferCount + voiceChannelCountMax;
|
BufferCount = mixBufferCount + voiceChannelCountMax;
|
||||||
Buffers = mixBuffer;
|
Buffers = mixBuffer;
|
||||||
Commands = [];
|
Commands = CommandsListPool.Allocate();
|
||||||
MemoryManager = memoryManager;
|
MemoryManager = memoryManager;
|
||||||
|
|
||||||
_buffersEntryCount = Buffers.Length;
|
_buffersEntryCount = Buffers.Length;
|
||||||
@@ -142,6 +143,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CommandBuffer.ReleaseCommand(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
EndTime = (ulong)PerformanceCounter.ElapsedNanoseconds;
|
EndTime = (ulong)PerformanceCounter.ElapsedNanoseconds;
|
||||||
@@ -149,6 +152,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
Commands.Clear();
|
||||||
|
CommandsListPool.Release(Commands);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
_buffersMemoryHandle.Dispose();
|
_buffersMemoryHandle.Dispose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,22 +15,28 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; }
|
public int NodeId { get; private set; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.Compressor;
|
public CommandType CommandType => CommandType.Compressor;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public CompressorParameter Parameter => _parameter;
|
public CompressorParameter Parameter => _parameter;
|
||||||
public Memory<CompressorState> State { get; }
|
public Memory<CompressorState> State { get; private set; }
|
||||||
public Memory<EffectResultState> ResultState { get; }
|
public Memory<EffectResultState> ResultState { get; private set; }
|
||||||
public ushort[] OutputBufferIndices { get; }
|
public ushort[] OutputBufferIndices { get; }
|
||||||
public ushort[] InputBufferIndices { get; }
|
public ushort[] InputBufferIndices { get; }
|
||||||
public bool IsEffectEnabled { get; }
|
public bool IsEffectEnabled { get; private set; }
|
||||||
|
|
||||||
private CompressorParameter _parameter;
|
private CompressorParameter _parameter;
|
||||||
|
|
||||||
public CompressorCommand(uint bufferOffset, CompressorParameter parameter, Memory<CompressorState> state, Memory<EffectResultState> resultState, bool isEnabled, int nodeId)
|
public CompressorCommand()
|
||||||
|
{
|
||||||
|
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
||||||
|
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompressorCommand Initialize(uint bufferOffset, CompressorParameter parameter, Memory<CompressorState> state, Memory<EffectResultState> resultState, bool isEnabled, int nodeId)
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
@@ -39,9 +45,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
ResultState = resultState;
|
ResultState = resultState;
|
||||||
|
|
||||||
IsEffectEnabled = isEnabled;
|
IsEffectEnabled = isEnabled;
|
||||||
|
|
||||||
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
|
||||||
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
|
||||||
|
|
||||||
Span<byte> inputSpan = _parameter.Input.AsSpan();
|
Span<byte> inputSpan = _parameter.Input.AsSpan();
|
||||||
Span<byte> outputSpan = _parameter.Output.AsSpan();
|
Span<byte> outputSpan = _parameter.Output.AsSpan();
|
||||||
@@ -51,6 +54,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
|
InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
|
||||||
OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]);
|
OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
|
|||||||
@@ -4,22 +4,29 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; }
|
public int NodeId { get; private set; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.CopyMixBuffer;
|
public CommandType CommandType => CommandType.CopyMixBuffer;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public ushort InputBufferIndex { get; }
|
public ushort InputBufferIndex { get; private set; }
|
||||||
public ushort OutputBufferIndex { get; }
|
public ushort OutputBufferIndex { get; private set; }
|
||||||
|
|
||||||
public CopyMixBufferCommand(uint inputBufferIndex, uint outputBufferIndex, int nodeId)
|
public CopyMixBufferCommand()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public CopyMixBufferCommand Initialize(uint inputBufferIndex, uint outputBufferIndex, int nodeId)
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
|
|
||||||
InputBufferIndex = (ushort)inputBufferIndex;
|
InputBufferIndex = (ushort)inputBufferIndex;
|
||||||
OutputBufferIndex = (ushort)outputBufferIndex;
|
OutputBufferIndex = (ushort)outputBufferIndex;
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
|
|||||||
@@ -11,35 +11,40 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; }
|
public int NodeId { get; private set; }
|
||||||
|
|
||||||
public CommandType CommandType { get; }
|
public CommandType CommandType { get; private set; }
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public ushort OutputBufferIndex { get; }
|
public ushort OutputBufferIndex { get; private set; }
|
||||||
public uint SampleRate { get; }
|
public uint SampleRate { get; private set; }
|
||||||
|
|
||||||
public float Pitch { get; }
|
public float Pitch { get; private set; }
|
||||||
|
|
||||||
public WaveBuffer[] WaveBuffers { get; }
|
public WaveBuffer[] WaveBuffers { get; }
|
||||||
|
|
||||||
public Memory<VoiceState> State { get; }
|
public Memory<VoiceState> State { get; private set; }
|
||||||
|
|
||||||
public ulong ExtraParameter { get; }
|
public ulong ExtraParameter { get; private set; }
|
||||||
public ulong ExtraParameterSize { get; }
|
public ulong ExtraParameterSize { get; private set; }
|
||||||
|
|
||||||
public uint ChannelIndex { get; }
|
public uint ChannelIndex { get; private set; }
|
||||||
|
|
||||||
public uint ChannelCount { get; }
|
public uint ChannelCount { get; private set; }
|
||||||
|
|
||||||
public DecodingBehaviour DecodingBehaviour { get; }
|
public DecodingBehaviour DecodingBehaviour { get; private set; }
|
||||||
|
|
||||||
public SampleFormat SampleFormat { get; }
|
public SampleFormat SampleFormat { get; private set; }
|
||||||
|
|
||||||
public SampleRateConversionQuality SrcQuality { get; }
|
public SampleRateConversionQuality SrcQuality { get; private set; }
|
||||||
|
|
||||||
public DataSourceVersion2Command(ref VoiceInfo serverInfo, Memory<VoiceState> state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
|
public DataSourceVersion2Command()
|
||||||
|
{
|
||||||
|
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataSourceVersion2Command Initialize(ref VoiceInfo serverInfo, Memory<VoiceState> state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
@@ -55,8 +60,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
Span<Server.Voice.WaveBuffer> waveBufferSpan = serverInfo.WaveBuffers.AsSpan();
|
Span<Server.Voice.WaveBuffer> waveBufferSpan = serverInfo.WaveBuffers.AsSpan();
|
||||||
|
|
||||||
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
|
|
||||||
|
|
||||||
for (int i = 0; i < WaveBuffers.Length; i++)
|
for (int i = 0; i < WaveBuffers.Length; i++)
|
||||||
{
|
{
|
||||||
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref waveBufferSpan[i];
|
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref waveBufferSpan[i];
|
||||||
@@ -72,6 +75,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
State = state;
|
State = state;
|
||||||
DecodingBehaviour = serverInfo.DecodingBehaviour;
|
DecodingBehaviour = serverInfo.DecodingBehaviour;
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CommandType GetCommandTypeBySampleFormat(SampleFormat sampleFormat)
|
private static CommandType GetCommandTypeBySampleFormat(SampleFormat sampleFormat)
|
||||||
|
|||||||
@@ -13,24 +13,30 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public int NodeId { get; }
|
public int NodeId { get; private set; }
|
||||||
|
|
||||||
public CommandType CommandType => CommandType.Delay;
|
public CommandType CommandType => CommandType.Delay;
|
||||||
|
|
||||||
public uint EstimatedProcessingTime { get; set; }
|
public uint EstimatedProcessingTime { get; set; }
|
||||||
|
|
||||||
public DelayParameter Parameter => _parameter;
|
public DelayParameter Parameter => _parameter;
|
||||||
public Memory<DelayState> State { get; }
|
public Memory<DelayState> State { get; private set; }
|
||||||
public ulong WorkBuffer { get; }
|
public ulong WorkBuffer { get; private set; }
|
||||||
public ushort[] OutputBufferIndices { get; }
|
public ushort[] OutputBufferIndices { get; }
|
||||||
public ushort[] InputBufferIndices { get; }
|
public ushort[] InputBufferIndices { get; }
|
||||||
public bool IsEffectEnabled { get; }
|
public bool IsEffectEnabled { get; private set; }
|
||||||
|
|
||||||
private DelayParameter _parameter;
|
private DelayParameter _parameter;
|
||||||
|
|
||||||
private const int FixedPointPrecision = 14;
|
private const int FixedPointPrecision = 14;
|
||||||
|
|
||||||
public DelayCommand(uint bufferOffset, DelayParameter parameter, Memory<DelayState> state, bool isEnabled, ulong workBuffer, int nodeId, bool newEffectChannelMappingSupported)
|
public DelayCommand()
|
||||||
|
{
|
||||||
|
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
||||||
|
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
||||||
|
}
|
||||||
|
|
||||||
|
public DelayCommand Initialize(uint bufferOffset, DelayParameter parameter, Memory<DelayState> state, bool isEnabled, ulong workBuffer, int nodeId, bool newEffectChannelMappingSupported)
|
||||||
{
|
{
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
@@ -39,9 +45,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
WorkBuffer = workBuffer;
|
WorkBuffer = workBuffer;
|
||||||
|
|
||||||
IsEffectEnabled = isEnabled;
|
IsEffectEnabled = isEnabled;
|
||||||
|
|
||||||
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
|
||||||
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
|
|
||||||
|
|
||||||
Span<byte> inputSpan = Parameter.Input.AsSpan();
|
Span<byte> inputSpan = Parameter.Input.AsSpan();
|
||||||
Span<byte> outputSpan = Parameter.Output.AsSpan();
|
Span<byte> outputSpan = Parameter.Output.AsSpan();
|
||||||
@@ -54,6 +57,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
DataSourceHelper.RemapLegacyChannelEffectMappingToChannelResourceMapping(newEffectChannelMappingSupported, InputBufferIndices, Parameter.ChannelCount);
|
DataSourceHelper.RemapLegacyChannelEffectMappingToChannelResourceMapping(newEffectChannelMappingSupported, InputBufferIndices, Parameter.ChannelCount);
|
||||||
DataSourceHelper.RemapLegacyChannelEffectMappingToChannelResourceMapping(newEffectChannelMappingSupported, OutputBufferIndices, Parameter.ChannelCount);
|
DataSourceHelper.RemapLegacyChannelEffectMappingToChannelResourceMapping(newEffectChannelMappingSupported, OutputBufferIndices, Parameter.ChannelCount);
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user