Author SHA1 Message Date
KeatonTheBot c3bfce3378 Update Kenji-NX to 2.0.5 2025-10-06 08:57:12 -05:00
KeatonTheBot 88e8d1309c UI: RPC: Asset images
* Final Fantasy Tactics: The Ivalice Chronicles

* Hades II

* Sonic Racing: CrossWorlds

* Super Mario Galaxy 1 & 2
2025-10-03 10:06:02 -05:00
KeatonTheBot ebeb532099 Fix build error: Replace StartsWithIgnoreCase with standard .NET equivalent 2025-10-02 15:18:35 -05:00
KeatonTheBot c501fe264b Fix push descriptors bugfix logic for Intel Arc on Linux 2025-10-01 15:30:02 -05:00
GreemDev 61d0430006 vulkan: Intel Arc on Linux also has the push descriptors bug. 2025-10-01 14:20:02 -05:00
KeatonTheBot cd477cf744 Ryujinx.csproj: Move PublishTrimmed setting for win-arm64 into existing PropertyGroup 2025-10-01 08:49:24 -05:00
KeatonTheBot 0487b781dc Revert NullReferenceException change in IntervalTree.cs
* Not technically needed because newNode.Parent is the same value as parent
2025-09-30 17:53:09 -05:00
KeatonTheBot 51b32981b6 misc: chore: Fix possible NullReferenceExceptions, InvalidOperationExceptions 2025-09-30 15:05:14 -05:00
KeatonTheBot fa682d406e misc: chore: Merge into pattern 2025-09-24 13:51:15 -05:00
KeatonTheBot 503dea74c2 misc: chore: Remove unnecessary usings 2025-09-24 13:48:36 -05:00
KeatonTheBot 1f979e5c6f misc: chore: Fix object creation 2025-09-24 13:44:00 -05:00
KeatonTheBot 378dc33cca misc: chore: Discard unused parameters 2025-09-24 13:26:50 -05:00
KeatonTheBot 9c37a557dd misc: chore: Merge duplicated 'if' branches 2025-09-24 13:26:50 -05:00
Mcost45 6e5bd0c9f2 Include SL/SR default bindings for single joycons
Single L/R Joycons default to unbound for the SL/SR inputs - so by default you can't progress past 'press L + R to continue' type screens.
But

* ConfigGamepadInputId.SingleLeftTrigger0(L)

* ConfigGamepadInputId.SingleRightTrigger0(L)

* ConfigGamepadInputId.SingleLeftTrigger1(R)

* ConfigGamepadInputId.SingleRightTrigger1(R)

already exist (and I verified these are the inputs triggered by the SL/SR buttons), so my change would default to these instead.
2025-09-23 09:27:59 -05:00
Alula 0f2b11d4d5 feat: resolve real module names in HLE debugger 2025-09-20 11:32:15 -05:00
KeatonTheBot 1abf5b82c5 Fix: Configuration migration for Turbo Mode 2025-09-19 16:28:59 -05:00
KeatonTheBot d751cfa81a UI: Update Svg.Controls.Avalonia group to 11.3.6.2 2025-09-19 08:20:24 -05:00
KeatonTheBot af14fadb2f UI: Update Avalonia to 11.3.6 2025-09-17 09:15:01 -05:00
KeatonTheBot 4fd4e3a4ff Increase # of maximum log files from 4 to 5 2025-09-15 16:21:11 -05:00
KeatonTheBot a1834900be Revert stream loader changes
"add stream based loaders" - Commit c16559f2

"Fix some DLCs crashing due to stream loader change" - Commit a62deb8c
2025-09-14 14:51:46 -05:00
KeatonTheBot fe7a30c747 Revert Android changes
* "Android: NCE support" - Commit cd3221ab

* "Android: Numerous fixes" - Commit 19dd23c2

* "Android: Memory specific switches" - Commit 98b4ff33

* "Android: Remove unmanaged code" - Commit 846b5b6e
2025-09-14 14:51:44 -05:00
KeatonTheBot 3a387309b4 Memory changes part 2 crash fix
* This was an oversight: Two lines were left out when initially cherry-picking from Ryubing
2025-09-12 17:58:00 -05:00
KeatonTheBot 867a92a8bc nuget: bump System group to 9.0.9 2025-09-10 15:41:20 -05:00
Coxxs 45bf443c01 Fix headless mode
Fix the error

`Error setting value to option 'gdb-stub-port': Check if Option or Value attribute values are set properly for the given type.`

https://github.com/commandlineparser/commandline/issues/612
2025-09-10 13:14:07 -05:00
LotP a09568d1b7 Memory changes 2.2.1
Cleans up some leftover comments i forgot to remove.

Potentially fixes 1 more crash.
2025-09-07 13:11:57 -05:00
LotP dae7ae7eaf Memory changes 2.2
A few more internal changes to the RangeList systems.

* No longer using a QuickAccess dictionary.

  * The performance of the dictionary wasn't much faster than just doing binary searches.

  * Using just binary searches allows us to take advantage of span and array returns as they're are faster than linked lists when iterating or copying the overlaps.

Small code optimizations.

Fixes a few leftover crashes.
2025-09-06 12:26:08 -05:00
KeatonTheBot c2f54d0a5c UI: RPC: Hollow Knight Silksong asset image 2025-09-05 08:59:38 -05:00
LotP f4dfdd35b2 hle: Basic event handle implementation for IApplicationFunctions 210
Lets Hollow Knight: Silksong boot.

* remove stub

* Add version comment
2025-09-05 08:59:26 -05:00
GreemDevandKeatonTheBot c56d04a9a9 feature: Turbo Mode
Adds an elapsed tick multiplier feature which speeds up games which are built upon delta time.

More information: https://web.archive.org/web/20240713135029/https://github.com/Ryujinx/Ryujinx/pull/6456

Co-authored-by: KeatonTheBot <keaton@ryujinx.app>
2025-09-04 23:49:32 -05:00
KeatonTheBot 5c6175cebf UI: Fix Match System Time setting not appropriately disabling/enabling System Time options 2025-09-04 23:49:26 -05:00
KeatonTheBot 9addccb50f misc: chore: Replace Gommon functions with standard .NET equivalents (part 3) 2025-09-04 14:28:54 -05:00
KeatonTheBot 17946c78e6 UI: Update Avalonia to 11.3.5 2025-09-04 12:31:51 -05:00
KeatonTheBot 29647b6351 Update SDL to 2.32.10 2025-09-02 10:33:51 -05:00
KeatonTheBot 6e6983799e Update FFmpeg runtimes to 6.1.3 for Windows/Linux 2025-09-01 12:44:24 -05:00
LotP 61da23cb9e Memory changes 2.1
* Fixes a few crashes

* Simplifies a few functions

* Changes a few calls to use faster methods
2025-08-31 20:42:31 -05:00
KeatonTheBot a62deb8cfd Fix some DLCs crashing due to stream loader change 2025-08-31 20:42:28 -05:00
KeatonTheBot 8ea79ae5d5 UI: Update Svg.Controls.Avalonia group to 11.3.0.4 2025-08-28 16:26:13 -05:00
GreemDev 09f3bf4b55 [ci skip] chore: Change LDN server URL (it's the same server, just a more official URL) 2025-08-28 09:50:29 -05:00
LotP 171624e7f0 Memory Changes part 2
* Slightly refactors RangeLists from the last Memory Changes MR, which fixes issue 61.

* Convert as many const size array iterators to span iterators as possible. When iterating over a const size array, every iteration created a Span, now only the first iteration does in most places.

* Now using object pooling for a few object types that were rapidly deleted and recreated.

* Converted a few flag checks to binary operations to save memory allocations.
2025-08-26 15:30:12 -05:00
LotP 01cb33f658 Memory Changes
* Refactors the RangeList and derivative classes used for handling lists of regions

* The Binary searches are now more performant, relying on edge searches instead of just returning the first matching hit and manually iterating until the edge is found

* Most look-ups now return a RangeItem, which acts as a linked list node now, instead where possible, moving away from Array copies. This should help with some specific lag spikes.

* Made IntrusiveRedBlackTreeNodes act like linked list nodes too to improve the lookup time of minimums, maximums and successors.

* Changed a few cases of HasFlag() into binary operations to save on memory allocations.

In general, [these changes] should increase frame time stability and lag spikes, but at the cost of some overhead to memory look-ups, the result being a very slightly better average fps from my testing (~1-2%).
2025-08-26 15:28:43 -05:00
KeatonTheBot 121bb5dc76 UI: Update Avalonia to 11.3.4
* Fix text and ComboBox alignment in Save Manager
2025-08-21 11:36:23 -05:00
KeatonTheBot d73ef0e3fb nuget: bump packages
* Microsoft.CodeAnalysis.CSharp to 4.12.0

* Microsoft.IdentityModel.JsonWebTokens to 8.14.0

* UnicornEngine.Unicorn to 2.1.3
2025-08-20 16:51:15 -05:00
MaxLastBreathandGreemDev 46b2da2435 Fix Avalonia Native MouseWheel-Support
* Rename timer interval constant

* Also cut the delay after which scrolling is considered ended in half

Co-authored-by: GreemDev <greemdev@ryujinx.app>
2025-08-20 11:51:46 -05:00
gdkchan aca897c70c Protect against stack overflow caused by deep recursive calls
* PPTC version bump

* Also reset call depth when not using the unmanaged dispatch loop

* Increment call depth on function start rather than before call
2025-08-20 11:50:15 -05:00
gdkchan e7d423cd07 Avoid lookup of invalid textures if pool did not change 2025-08-17 00:41:30 -05:00
KeatonTheBot 48c809a80d Revert "Memory Changes"
This reverts commit d5c9bc662c.

Solves crash in Kirby Star Allies after a few mins of gameplay, possibly other titles.
2025-08-17 00:19:01 -05:00
Coxxs 7fd01214cf gdb: Improve stepping 2025-08-11 15:06:46 -05:00
Coxxs ef72e9b790 Add GDB Stub 2025-08-11 15:06:41 -05:00
LotP d5c9bc662c Memory Changes 2025-08-07 11:59:44 -05:00
KeatonTheBot 3cf90e808d nuget: bump System group to 9.0.8 2025-08-06 08:49:45 -05:00
KeatonTheBot 326f744093 nuget: bump DiscordRichPresence to 1.6.1.70 2025-08-05 14:04:33 -05:00
KeatonTheBot 6cecbaa625 UI: Update FluentAvalonia.NoAnim to 2.4.0-build2, revert ColorPicker changes 2025-07-30 21:19:15 -05:00
KeatonTheBot 1443e1a2ff UI: Update Avalonia to 11.3.2, FluentAvalonia to 2.4.0
* FluentAvalonia: Disabled NavigationView selection indicator animations due to bugged implementation in 2.1.0+, restoring previous behavior

* Avalonia: Fixed text on certain buttons being larger than normal

* Avalonia: Fixed ComboBox code inserting extra space to the left of selected items
2025-07-29 18:01:11 -05:00
KeatonTheBot 12d7f95468 nuget: bump DiscordRichPresence to 1.4.1.37, Microsoft.IdentityModel.JsonWebTokens to 8.13.0 2025-07-29 17:48:55 -05:00
KeatonTheBot b59a833467 UI: RPC: Pokémon Friends asset image 2025-07-28 20:10:33 -05:00
GreemDev 50a2caf799 Update Ryujinx.LibHac
This should fix crashes with mods that worked on Ryubing 1.3.1.

Thanks @cyphix!

https://git.ryujinx.app/ryubing/libhac/-/commit/e39169ab5053ff179b7fef38f624dfc608d2596c
2025-07-21 22:43:51 -05:00
KeatonTheBot 7d1fd99d3d nuget: bump System group to 9.0.7 2025-07-12 16:22:42 -05:00
Emmanuel Hansen c16559f20e add stream based loaders
* extend stream loading support

* fix content manager rebase

* fix update searching
2025-06-28 13:41:52 -05:00
Coxxs 6ecd6111d5 fix: UI deadlock when launching a game with "Trace Logs" enabled
This fixes https://github.com/Ryubing/Issues/issues/30

* Switch to "Release" build config (PerformanceCheck(); will only be called in Release build config)

* Enable "Trace Logs" in Ryujinx settings

* Double-click a game to launch

* Ryujinx will attempt to open a confirmation dialog box that never opens, causing UI deadlock
2025-06-20 10:40:29 -05:00
KeatonTheBot 0ee71fa064 misc: chore: Replace Gommon functions with standard .NET equivalents (part 2) 2025-06-20 10:36:56 -05:00
KeatonTheBot 6e8f7e7fcb misc: chore: Replace additional instances of Gommon ForEach with 'foreach' statements 2025-06-18 16:19:17 -05:00
KeatonTheBot f9780b33bb misc: chore: Use 'foreach' statement in place of Gommon ForEach in "delete all" mod manager crash fix
* Simplify statement for valid mod folder checking
2025-06-18 02:41:02 -05:00
KeatonTheBot d2a532f971 misc: chore: Fix numerous NullReferenceExceptions, InvalidOperationExceptions 2025-06-18 02:25:06 -05:00
Coxxs a90db3464d fix: socket blocking flag is inverted when setting it 2025-06-13 17:00:28 -05:00
KeatonTheBot c61d171e52 nuget: bump packages
* DynamicData to 9.4.1

* Microsoft.IdentityModel.JsonWebTokens to 8.12.0
2025-06-12 19:16:04 -05:00
KeatonTheBot 8927a78c4d nuget: bump DiscordRichPresence to 1.3.0.28 2025-06-12 17:05:53 -05:00
KeatonTheBot aa836dd924 nuget: bump System group to 9.0.6 2025-06-11 14:07:59 -05:00
mqudsi 878ea70aa9 Work around Escape hotkey race with exit confirmation dialog 2025-06-11 10:47:53 -05:00
rockingdice 9f0a35ee9b fix: crash caused by cursor overflow
* This fixes a crash that occurred when opening the soft keyboard for the second time
2025-06-10 18:17:48 -05:00
rockingdice ed0ebdec5b fix: use the correct font family for CJK characters 2025-06-10 18:16:56 -05:00
KeatonTheBot b5a1272141 Update SDL2 to 2.32.8 2025-06-09 03:08:12 -05:00
GreemDev 6768e1fa71 infra: Update to Ryujinx.LibHac 0.20.0
This is identical to the previous version, it's just on NuGet.org so we can comment out the LibHacAlpha source in nuget.config.
2025-06-08 23:20:47 -05:00
GreemDev 5c2d710fbb misc: Update LibHac
* _lastFileOffset now correctly stores the offset for the last file in the chain

  * Fixes an issue where a RomFS mod with both overridden and new files in the same folder would load incorrectly

* Renamed a variable with the wrong name

* Now behaves correctly when the same file is added twice in a row compared to V1 MR
2025-06-06 17:06:35 -05:00
LotP d3f3eacc41 fix: use accurate length for enumerating
See merge request ryubing/ryujinx!49
2025-06-04 11:42:21 -05:00
LotP 5983cb9e5f Update LibHac
* Fixes Avalonia timeout

* Cuts RomFS rebuilding times by up to a factor of 1000 in games with big RomFS like TotK
2025-06-01 02:26:43 -05:00
KeatonTheBot e09f16838e Suppress CA1416 warnings, correct argument kind in IFileSystem 2025-06-01 02:26:15 -05:00
KeatonTheBot 18f302c0b0 Update OpenTK to 4.9.4, OpenAL to 1.24.3 2025-06-01 02:26:01 -05:00
KeatonTheBot 8f77076117 Change stick visualizer color to system accent color 2025-06-01 02:25:39 -05:00
KeatonTheBot 39544e323c Update Kenji-NX to 2.0.4 2025-05-29 22:01:40 -05:00
KeatonTheBot 24932b7e1b infra: Remove Ryujinx.Common references from project files that indirectly reference the same file 2025-05-29 11:10:57 -05:00
KeatonTheBot 2aaf34937d infra: Fix missing libarmeilleure-jitsupport.dylib on macOS (arm64) builds 2025-05-29 10:28:00 -05:00
KeatonTheBot bce3426d26 Linux: Fix games not launching (from Bionic code) 2025-05-28 03:37:23 -05:00
MrKev 51ca73cb10 Fix JWT Claims and Socket Flag Handling to Improve Just Dance® Server Connection 2025-05-27 18:28:15 -05:00
KeatonTheBot cd3221abdc Android: NCE support 2025-05-26 16:02:20 -05:00
KeatonTheBot 19dd23c288 Android: Numerous fixes
* GetSerialNumber in ISystemSettingsServer

* Bionic qualifiers

* Revert application pool size to 3285 MB for 4 GB DRAM

* Fix PPTC recompilation if mod or patch is applied
2025-05-26 16:01:23 -05:00
GreemDev 20f1cef9b2 fix: Super Mario Party Jamboree audio renderer crashing 2025-05-26 10:22:13 -05:00
KeatonTheBot 2f400491d5 ffmpeg: Fix green screen issues on Linux 2025-05-25 22:34:06 -05:00
ChromJ f6351e3fff Add Ctrl+Comma shortcut for settings
See merge request kenji-nx/ryujinx!2
2025-05-24 23:47:13 -05:00
KeatonTheBot f15ddcf9c4 UI: Fix GitLab logos not showing on git server in Ryujinx.UI.Common\Resources folder due to capitalization error 2025-05-24 22:23:44 -05:00
Evan Husted 88d904acde Headless in Avalonia v2
Launch the Ryujinx.exe, first argument --no-gui or nogui, and the rest of the arguments should be your normal headless script. You can include the new option --use-main-config which will provide any arguments that you don't, filled in from your main config made by the UI.
2025-05-24 19:32:45 -05:00
KeatonTheBot fbcf57bef5 UI: RPC: Add LUNAR Remastered Collection 2025-05-22 15:29:39 -05:00
KeatonTheBot 8bfb670e65 infra: Update SDL2 to 2.32.6 2025-05-21 15:50:27 -05:00
KeatonTheBot e00bece65a nuget: Remove GtkSharp packages 2025-05-20 02:26:44 -05:00
GreemDev 2a03f7b1d4 infra: Update to Ryujinx.LibHac 0.20.0.
This time it's pulled in via GitLab package registry.
2025-05-20 00:28:49 -05:00
KeatonTheBot 6c7b7d6fc4 UI: Change the GitHub button in the About window to GitLab 2025-05-19 23:03:37 -05:00
KeatonTheBot c43db7d5f6 Update README.md and other documents 2025-05-17 13:35:37 -05:00
KeatonTheBot cc92af12a4 infra: Fix clean installation crash 2025-05-16 17:23:10 -05:00
1166 changed files with 12954 additions and 45869 deletions
-3
View File
@@ -173,6 +173,3 @@ PublishProfiles/
# Glade backup files # Glade backup files
*.glade~ *.glade~
# Log files
/logs/
-9
View File
@@ -1,9 +0,0 @@
[submodule "src/KenjinxAndroid/app/src/main/cpp/libraries/adrenotools"]
path = src/KenjinxAndroid/app/src/main/cpp/libraries/adrenotools
url = https://git.ryujinx.app/kenji-nx/libadrenotools.git
[submodule "src/KenjinxAndroid/app/src/main/cpp/libraries/openal"]
path = src/KenjinxAndroid/app/src/main/cpp/libraries/openal
url = https://git.ryujinx.app/kenji-nx/openal-soft.git
[submodule "src/KenjinxAndroid/app/src/main/cpp/libraries/adrenotools/lib/linkernsbypass"]
path = src/KenjinxAndroid/app/src/main/cpp/libraries/adrenotools/lib/linkernsbypass
url = https://git.ryujinx.app/kenji-nx/liblinkernsbypass.git
+25 -27
View File
@@ -3,54 +3,52 @@
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageVersion Include="Avalonia" Version="11.3.13" /> <PackageVersion Include="Avalonia" Version="11.3.6" />
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.3.13" /> <PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.3.6" />
<PackageVersion Include="Avalonia.Desktop" Version="11.3.13" /> <PackageVersion Include="Avalonia.Desktop" Version="11.3.6" />
<PackageVersion Include="Avalonia.Diagnostics" Version="11.3.13" /> <PackageVersion Include="Avalonia.Diagnostics" Version="11.3.6" />
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.3.13" /> <PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.3.6" />
<PackageVersion Include="Svg.Controls.Avalonia" Version="11.3.9.5" /> <PackageVersion Include="Svg.Controls.Avalonia" Version="11.3.6.2" />
<PackageVersion Include="Svg.Controls.Skia.Avalonia" Version="11.3.9.5" /> <PackageVersion Include="Svg.Controls.Skia.Avalonia" Version="11.3.6.2" />
<PackageVersion Include="CommandLineParser" Version="2.9.1" /> <PackageVersion Include="CommandLineParser" Version="2.9.1" />
<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.31" /> <PackageVersion Include="DynamicData" Version="9.4.1" />
<PackageVersion Include="FluentAvaloniaUI" Version="2.4.1" /> <PackageVersion Include="FluentAvaloniaUI.NoAnim" Version="2.4.0-build2" />
<PackageVersion Include="Gommon" Version="2.8.1.1" /> <PackageVersion Include="Gommon" Version="2.7.1.1" />
<PackageVersion Include="Humanizer" Version="3.0.10" /> <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.12.0" /> <PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.12.0" />
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.17.0" /> <PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.14.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.3.0" /> <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" /> <PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" /> <PackageVersion Include="MsgPack.Cli" Version="1.0.1" />
<PackageVersion Include="NetCoreServer" Version="8.0.7" /> <PackageVersion Include="NetCoreServer" Version="8.0.7" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" /> <PackageVersion Include="NUnit" Version="3.13.3" />
<PackageVersion Include="NUnit" Version="4.5.1" /> <PackageVersion Include="NUnit3TestAdapter" Version="4.1.0" />
<PackageVersion Include="NUnit3TestAdapter" Version="6.2.0" />
<PackageVersion Include="OpenTK.Core" Version="4.9.4" /> <PackageVersion Include="OpenTK.Core" Version="4.9.4" />
<PackageVersion Include="OpenTK.Graphics" Version="4.9.4" /> <PackageVersion Include="OpenTK.Graphics" Version="4.9.4" />
<PackageVersion Include="OpenTK.Audio.OpenAL" Version="4.9.4" /> <PackageVersion Include="OpenTK.Audio.OpenAL" Version="4.9.4" />
<PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.9.4" /> <PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.9.4" />
<PackageVersion Include="Open.NAT.Core" Version="2.1.0.5" /> <PackageVersion Include="Open.NAT.Core" Version="2.1.0.5" />
<PackageVersion Include="Ryujinx.Audio.OpenAL" Version="1.25.2" /> <PackageVersion Include="Ryujinx.Audio.OpenAL" Version="1.24.3" />
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.Linux" Version="6.1.3-build5" /> <PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.Linux" Version="6.1.3-build5" />
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.macOS" Version="5.0.3-build14" /> <PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.macOS" Version="5.0.3-build14" />
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.Windows" Version="6.1.3-build5" /> <PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.Windows" Version="6.1.3-build5" />
<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.128" /> <PackageVersion Include="Ryujinx.LibHac" Version="0.21.0-alpha.116" />
<PackageVersion Include="Ryujinx.SDL3-CS" Version="2026.707.0" /> <PackageVersion Include="Ryujinx.SDL2-CS-Redux" Version="2.32.10" />
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" /> <PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
<PackageVersion Include="shaderc.net" Version="0.1.0" />
<PackageVersion Include="SharpZipLib" Version="1.4.2" /> <PackageVersion Include="SharpZipLib" Version="1.4.2" />
<PackageVersion Include="Silk.NET.Shaderc" Version="2.23.0" /> <PackageVersion Include="Silk.NET.Vulkan" Version="2.22.0" />
<PackageVersion Include="Silk.NET.Vulkan" Version="2.23.0" /> <PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.22.0" />
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.23.0" /> <PackageVersion Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.22.0" />
<PackageVersion Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.23.0" />
<PackageVersion Include="SkiaSharp" Version="2.88.9" /> <PackageVersion Include="SkiaSharp" Version="2.88.9" />
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.9" /> <PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.9" />
<PackageVersion Include="SPB" Version="0.0.4-build32" /> <PackageVersion Include="SPB" Version="0.0.4-build32" />
<PackageVersion Include="System.IO.Hashing" Version="9.0.12" /> <PackageVersion Include="System.IO.Hashing" Version="9.0.9" />
<PackageVersion Include="System.Management" Version="9.0.12" /> <PackageVersion Include="System.Management" Version="9.0.9" />
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.1.0" /> <PackageVersion Include="UnicornEngine.Unicorn" Version="2.1.3" />
<PackageVersion Include="Rxmxnx.PInvoke.Extensions" Version="2.9.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>
+23 -18
View File
@@ -1,26 +1,31 @@
<h1 align="center"> <h1 align="center">
<br> <br>
<img src="https://git.ryujinx.app/projects/Kenji-NX/raw/branch/master/distribution/misc/Logo.png" alt="Kenji-NX"> <img src="https://git.ryujinx.app/kenji-nx/ryujinx/-/raw/master/distribution/misc/Logo.png" alt="Kenji-NX">
<br> <br>
<b>Kenji-NX</b> <b>Kenji-NX</b>
<br> <br>
<a href="https://github.com/Kenji-NX/Releases/releases/latest">
[![Latest Desktop Release](https://git.ryujinx.app/projects/Kenji-NX/badges/release.svg?label=desktop)](https://git.ryujinx.app/projects/Kenji-NX/releases/latest) <img src="https://img.shields.io/github/v/release/Kenji-NX/Releases"
[![Latest Android Release](https://git.ryujinx.app/Kenji-NX/android/badges/release.svg?label=android)](https://git.ryujinx.app/Kenji-NX/android/releases/latest) alt="Latest Release">
<br> </a>
[![Discord](https://img.shields.io/discord/1294443224030511104?color=5865F2&label=Kenji-NX&logo=discord&logoColor=white)](https://discord.gg/zBSAuZfKqe)
</h1> </h1>
Kenji-NX is an open-source Nintendo Switch emulator, originally created by gdkchan, written in C#. <p>
This emulator aims at providing excellent accuracy and performance, a user-friendly interface and consistent builds. Kenji-NX is an open-source Nintendo Switch emulator, originally created by gdkchan, written in C#.
It was written from scratch and development on the project began in September 2017. This emulator aims at providing excellent accuracy and performance, a user-friendly interface and consistent builds.
Kenji-NX is available on GitHub under the [MIT license](LICENSE.txt). It was written from scratch and development on the project began in September 2017.
Kenji-NX is available on GitHub under the <a href="https://git.ryujinx.app/kenji-nx/ryujinx/-/raw/master/LICENSE.txt" target="_blank">MIT license</a>.
<br><br>
On October 1st 2024, Ryujinx was discontinued as the creator was forced to abandon the project.
<br><br>
This fork is not a Ryujinx revival project; it aims to be a middle ground between GreemDev's <a href="https://git.ryujinx.app/ryubing/ryujinx">Ryujinx</a> fork and the more preservative <a href="https://git.ryujinx.app/archive/ryujinx-mirror">ryujinx-mirror</a> fork.
It brings over many of the front-facing features from the aforementioned forks with <i>additional</i> contributions from KeatonTheBot and others.
<br>
</p>
On October 1st 2024, Ryujinx was discontinued as the creator was forced to abandon the project. <p>
<img src="docs/shell.png">
This fork is not a Ryujinx revival project; it aims to be a middle ground between GreemDev's [Ryujinx](https://git.ryujinx.app/projects/Ryubing) fork and the more preservative [ryujinx-mirror](https://git.ryujinx.app/archive/ryujinx-mirror) fork. </p>
It brings over many of the front-facing features from the aforementioned forks with *additional* contributions from KeatonTheBot and others.
## Compatibility ## Compatibility
@@ -53,12 +58,12 @@ If you wish to build the emulator yourself, follow these steps:
### Step 1 ### Step 1
Install the [.NET 10.0 (or higher) SDK](https://dotnet.microsoft.com/download/dotnet/10.0). Install the [.NET 9.0 (or higher) SDK](https://dotnet.microsoft.com/download/dotnet/9.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://git.ryujinx.app/projects/Kenji-NX` 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/kenji-nx/ryujinx` on the command line to clone the repository or use Code --> Download zip button to get the files.
### Step 3 ### Step 3
@@ -120,7 +125,7 @@ See [LICENSE.txt](LICENSE.txt) and [THIRDPARTY.md](distribution/legal/THIRDPARTY
## Credits ## Credits
- [LibHac](https://git.ryujinx.app/projects/LibHac) is used for our file-system. - [LibHac](https://github.com/Thealexbarney/LibHac) is used for our file-system.
- [AmiiboAPI](https://www.amiiboapi.com) is used in our Amiibo emulation. - [AmiiboAPI](https://www.amiiboapi.com) is used in our Amiibo emulation.
- [ldn_mitm](https://github.com/spacemeowx2/ldn_mitm) is used for one of our available multiplayer modes. - [ldn_mitm](https://github.com/spacemeowx2/ldn_mitm) is used for one of our available multiplayer modes.
- [ShellLink](https://github.com/securifybv/ShellLink) is used for Windows shortcut generation. - [ShellLink](https://github.com/securifybv/ShellLink) is used for Windows shortcut generation.
-8
View File
@@ -5,8 +5,6 @@ VisualStudioVersion = 17.1.32228.430
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Tests", "src\Ryujinx.Tests\Ryujinx.Tests.csproj", "{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Tests", "src\Ryujinx.Tests\Ryujinx.Tests.csproj", "{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibKenjinx", "src\LibKenjinx\LibKenjinx.csproj", "{AF58C1D5-DE16-429B-B155-7CE83B4E8FA6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Tests.Unicorn", "src\Ryujinx.Tests.Unicorn\Ryujinx.Tests.Unicorn.csproj", "{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Tests.Unicorn", "src\Ryujinx.Tests.Unicorn\Ryujinx.Tests.Unicorn.csproj", "{D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.HLE", "src\Ryujinx.HLE\Ryujinx.HLE.csproj", "{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.HLE", "src\Ryujinx.HLE\Ryujinx.HLE.csproj", "{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}"
@@ -34,9 +32,7 @@ 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
Directory.Build.props = Directory.Build.props
Directory.Packages.props = Directory.Packages.props Directory.Packages.props = Directory.Packages.props
nuget.config = nuget.config
EndProjectSection EndProjectSection
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Memory", "src\Ryujinx.Memory\Ryujinx.Memory.csproj", "{A5E6C691-9E22-4263-8F40-42F002CE66BE}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Memory", "src\Ryujinx.Memory\Ryujinx.Memory.csproj", "{A5E6C691-9E22-4263-8F40-42F002CE66BE}"
@@ -99,10 +95,6 @@ Global
{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}.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
{AF58C1D5-DE16-429B-B155-7CE83B4E8FA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AF58C1D5-DE16-429B-B155-7CE83B4E8FA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AF58C1D5-DE16-429B-B155-7CE83B4E8FA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AF58C1D5-DE16-429B-B155-7CE83B4E8FA6}.Release|Any CPU.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}.Release|Any CPU.ActiveCfg = Release|Any CPU {D8F72938-78EF-4E8C-BAFE-531C9C3C8F15}.Release|Any CPU.ActiveCfg = Release|Any CPU
-47
View File
@@ -1,47 +0,0 @@
<Solution>
<Folder Name="/Solution Items/">
<File Path=".editorconfig" />
<File Path="Directory.Build.props" />
<File Path="Directory.Packages.props" />
<File Path="nuget.config" />
</Folder>
<Project Path="src/ARMeilleure/ARMeilleure.csproj" />
<Project Path="src/LibKenjinx/LibKenjinx.csproj" />
<Project Path="src/Ryujinx.Audio.Backends.OpenAL/Ryujinx.Audio.Backends.OpenAL.csproj" />
<Project Path="src/Ryujinx.Audio.Backends.SDL3/Ryujinx.Audio.Backends.SDL3.csproj" />
<Project Path="src/Ryujinx.Audio.Backends.SoundIo/Ryujinx.Audio.Backends.SoundIo.csproj" />
<Project Path="src/Ryujinx.Audio/Ryujinx.Audio.csproj" />
<Project Path="src/Ryujinx.Common/Ryujinx.Common.csproj" />
<Project Path="src/Ryujinx.Cpu/Ryujinx.Cpu.csproj" />
<Project Path="src/Ryujinx.Graphics.Device/Ryujinx.Graphics.Device.csproj" />
<Project Path="src/Ryujinx.Graphics.GAL/Ryujinx.Graphics.GAL.csproj" />
<Project Path="src/Ryujinx.Graphics.Gpu/Ryujinx.Graphics.Gpu.csproj" />
<Project Path="src/Ryujinx.Graphics.Host1x/Ryujinx.Graphics.Host1x.csproj" />
<Project Path="src/Ryujinx.Graphics.Nvdec.FFmpeg/Ryujinx.Graphics.Nvdec.FFmpeg.csproj" />
<Project Path="src/Ryujinx.Graphics.Nvdec.Vp9/Ryujinx.Graphics.Nvdec.Vp9.csproj" />
<Project Path="src/Ryujinx.Graphics.Nvdec/Ryujinx.Graphics.Nvdec.csproj" />
<Project Path="src/Ryujinx.Graphics.OpenGL/Ryujinx.Graphics.OpenGL.csproj" />
<Project Path="src/Ryujinx.Graphics.Shader/Ryujinx.Graphics.Shader.csproj" />
<Project Path="src/Ryujinx.Graphics.Texture/Ryujinx.Graphics.Texture.csproj" />
<Project Path="src/Ryujinx.Graphics.Vic/Ryujinx.Graphics.Vic.csproj" />
<Project Path="src/Ryujinx.Graphics.Video/Ryujinx.Graphics.Video.csproj" />
<Project Path="src/Ryujinx.Graphics.Vulkan/Ryujinx.Graphics.Vulkan.csproj" />
<Project Path="src/Ryujinx.HLE.Generators/Ryujinx.HLE.Generators.csproj" />
<Project Path="src/Ryujinx.HLE/Ryujinx.HLE.csproj" />
<Project Path="src/Ryujinx.Horizon.Common/Ryujinx.Horizon.Common.csproj" />
<Project Path="src/Ryujinx.Horizon.Generators/Ryujinx.Horizon.Generators.csproj" />
<Project Path="src/Ryujinx.Horizon.Kernel.Generators/Ryujinx.Horizon.Kernel.Generators.csproj" />
<Project Path="src/Ryujinx.Horizon/Ryujinx.Horizon.csproj" />
<Project Path="src/Ryujinx.Input.SDL3/Ryujinx.Input.SDL3.csproj" />
<Project Path="src/Ryujinx.Input/Ryujinx.Input.csproj" />
<Project Path="src/Ryujinx.Memory/Ryujinx.Memory.csproj" />
<Project Path="src/Ryujinx.SDL3.Common/Ryujinx.SDL3.Common.csproj" />
<Project Path="src/Ryujinx.ShaderTools/Ryujinx.ShaderTools.csproj" />
<Project Path="src/Ryujinx.Tests.Memory/Ryujinx.Tests.Memory.csproj" />
<Project Path="src/Ryujinx.Tests.Unicorn/Ryujinx.Tests.Unicorn.csproj" />
<Project Path="src/Ryujinx.Tests/Ryujinx.Tests.csproj" />
<Project Path="src/Ryujinx.UI.Common/Ryujinx.UI.Common.csproj" />
<Project Path="src/Ryujinx.UI.LocaleGenerator/Ryujinx.UI.LocaleGenerator.csproj" />
<Project Path="src/Ryujinx/Ryujinx.csproj" />
<Project Path="src/Spv.Generator/Spv.Generator.csproj" />
</Solution>
+1 -1
View File
@@ -8,7 +8,7 @@ Intro to Kenji-NX
Kenji-NX is an open-source Nintendo Switch emulator written in C#. It is based on Ryujinx, which was originally created by gdkchan. Kenji-NX is an open-source Nintendo Switch emulator written in C#. It is based on Ryujinx, which was originally created by gdkchan.
* 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 SDL3, with OpenAL & libsoundio as fallbacks. * Audio output is entirely supported via C# wrappers for SDL2, with OpenAL & libsoundio as fallbacks.
Getting Started Getting Started
=============== ===============
+1 -5
View File
@@ -4,8 +4,7 @@
<clear /> <clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" /> <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<!-- Only needed when using pre-release versions of Ryujinx.LibHac. --> <!-- Only needed when using pre-release versions of Ryujinx.LibHac. -->
<add key="LibHacAlpha" value="https://git.ryujinx.app/api/packages/projects/nuget/index.json" /> <add key="LibHacAlpha" value="https://git.ryujinx.app/api/v4/projects/17/packages/nuget/index.json" />
<!--<add key="Silk.NET" value="https://gitlab.com/api/v4/projects/51457475/packages/nuget/index.json" />-->
</packageSources> </packageSources>
<packageSourceMapping> <packageSourceMapping>
<!-- key value for <packageSource> should match key values from <packageSources> element --> <!-- key value for <packageSource> should match key values from <packageSources> element -->
@@ -16,8 +15,5 @@
<packageSource key="LibHacAlpha"> <packageSource key="LibHacAlpha">
<package pattern="Ryujinx.LibHac" /> <package pattern="Ryujinx.LibHac" />
</packageSource> </packageSource>
<!--<packageSource key="Silk.NET">
<package pattern="Silk.*" />
</packageSource>-->
</packageSourceMapping> </packageSourceMapping>
</configuration> </configuration>
@@ -13,13 +13,13 @@ namespace ARMeilleure.CodeGen.Arm64
public static void RunPass(ControlFlowGraph cfg) public static void RunPass(ControlFlowGraph cfg)
{ {
Dictionary<ulong, Operand> constants = new(); var constants = new Dictionary<ulong, Operand>();
Operand GetConstantCopy(BasicBlock block, Operation operation, Operand source) Operand GetConstantCopy(BasicBlock block, Operation operation, Operand source)
{ {
// If the constant has many uses, we also force a new constant mov to be added, in order // If the constant has many uses, we also force a new constant mov to be added, in order
// to avoid overflow of the counts field (that is limited to 16 bits). // to avoid overflow of the counts field (that is limited to 16 bits).
if (!constants.TryGetValue(source.Value, out Operand constant) || constant.UsesCount > MaxConstantUses) if (!constants.TryGetValue(source.Value, out var constant) || constant.UsesCount > MaxConstantUses)
{ {
constant = Local(source.Type); constant = Local(source.Type);
+1 -1
View File
@@ -123,7 +123,7 @@ namespace ARMeilleure.CodeGen.Arm64
public void Cset(Operand rd, ArmCondition condition) public void Cset(Operand rd, ArmCondition condition)
{ {
Operand zr = Factory.Register(ZrRegister, RegisterType.Integer, rd.Type); var zr = Factory.Register(ZrRegister, RegisterType.Integer, rd.Type);
Csinc(rd, zr, zr, (ArmCondition)((int)condition ^ 1)); Csinc(rd, zr, zr, (ArmCondition)((int)condition ^ 1));
} }
@@ -91,7 +91,7 @@ namespace ARMeilleure.CodeGen.Arm64
long target = _stream.Position; long target = _stream.Position;
if (_pendingBranches.TryGetValue(block, out List<(ArmCondition Condition, long BranchPos)> list)) if (_pendingBranches.TryGetValue(block, out var list))
{ {
foreach ((ArmCondition condition, long branchPos) in list) foreach ((ArmCondition condition, long branchPos) in list)
{ {
@@ -119,7 +119,7 @@ namespace ARMeilleure.CodeGen.Arm64
} }
else else
{ {
if (!_pendingBranches.TryGetValue(target, out List<(ArmCondition Condition, long BranchPos)> list)) if (!_pendingBranches.TryGetValue(target, out var list))
{ {
list = new List<(ArmCondition, long)>(); list = new List<(ArmCondition, long)>();
_pendingBranches.Add(target, list); _pendingBranches.Add(target, list);
@@ -321,7 +321,7 @@ namespace ARMeilleure.CodeGen.Arm64
Debug.Assert(comp.Kind == OperandKind.Constant); Debug.Assert(comp.Kind == OperandKind.Constant);
ArmCondition cond = ((Comparison)comp.AsInt32()).ToArmCondition(); var cond = ((Comparison)comp.AsInt32()).ToArmCondition();
GenerateCompareCommon(context, operation); GenerateCompareCommon(context, operation);
@@ -353,7 +353,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(); var cond = ((Comparison)comp.AsInt32()).ToArmCondition();
GenerateCompareCommon(context, operation); GenerateCompareCommon(context, operation);
@@ -127,13 +127,13 @@ namespace ARMeilleure.CodeGen.Arm64
#region macOS #region macOS
[LibraryImport("libSystem.dylib", SetLastError = true)] [LibraryImport("libSystem.dylib", SetLastError = true)]
private static unsafe partial int sysctlbyname([MarshalAs(UnmanagedType.LPStr)] string name, out int oldValue, ref ulong oldSize, nint newValue, ulong newValueSize); private static unsafe partial int sysctlbyname([MarshalAs(UnmanagedType.LPStr)] string name, out int oldValue, ref ulong oldSize, IntPtr newValue, ulong newValueSize);
[SupportedOSPlatform("macos")] [SupportedOSPlatform("macos")]
private static bool CheckSysctlName(string name) private static bool CheckSysctlName(string name)
{ {
ulong size = sizeof(int); ulong size = sizeof(int);
if (sysctlbyname(name, out int val, ref size, nint.Zero, 0) == 0 && size == sizeof(int)) if (sysctlbyname(name, out int val, ref size, IntPtr.Zero, 0) == 0 && size == sizeof(int))
{ {
return val != 0; return val != 0;
} }
@@ -847,7 +847,7 @@ namespace ARMeilleure.CodeGen.Arm64
Debug.Assert(comp.Kind == OperandKind.Constant); Debug.Assert(comp.Kind == OperandKind.Constant);
Comparison compType = (Comparison)comp.AsInt32(); var compType = (Comparison)comp.AsInt32();
return compType is Comparison.Equal or Comparison.NotEqual; return compType is Comparison.Equal or Comparison.NotEqual;
} }
+2 -1
View File
@@ -1,6 +1,7 @@
using ARMeilleure.CodeGen.Linking; using ARMeilleure.CodeGen.Linking;
using ARMeilleure.CodeGen.Unwinding; using ARMeilleure.CodeGen.Unwinding;
using ARMeilleure.Translation.Cache; using ARMeilleure.Translation.Cache;
using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace ARMeilleure.CodeGen namespace ARMeilleure.CodeGen
@@ -57,7 +58,7 @@ namespace ARMeilleure.CodeGen
/// <typeparam name="T">Type of delegate</typeparam> /// <typeparam name="T">Type of delegate</typeparam>
/// <param name="codePointer">Pointer to the function code in memory</param> /// <param name="codePointer">Pointer to the function code in memory</param>
/// <returns>A delegate of type <typeparamref name="T"/> pointing to the mapped function</returns> /// <returns>A delegate of type <typeparamref name="T"/> pointing to the mapped function</returns>
public T MapWithPointer<T>(out nint codePointer) public T MapWithPointer<T>(out IntPtr codePointer)
{ {
codePointer = JitCache.Map(this); codePointer = JitCache.Map(this);
@@ -115,7 +115,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{ {
NumberLocals(cfg, regMasks.RegistersCount); NumberLocals(cfg, regMasks.RegistersCount);
AllocationContext context = new(stackAlloc, regMasks, _intervals.Count); var context = new AllocationContext(stackAlloc, regMasks, _intervals.Count);
BuildIntervals(cfg, context); BuildIntervals(cfg, context);
@@ -387,7 +387,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
public override int GetHashCode() public override int GetHashCode()
{ {
return HashCode.Combine((nint)_data); return HashCode.Combine((IntPtr)_data);
} }
public override string ToString() public override string ToString()
@@ -15,12 +15,12 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{ {
if (_count + 1 > _capacity) if (_count + 1 > _capacity)
{ {
Span<LiveInterval> oldSpan = Span; var oldSpan = Span;
_capacity = Math.Max(4, _capacity * 2); _capacity = Math.Max(4, _capacity * 2);
_items = Allocators.References.Allocate<LiveInterval>((uint)_capacity); _items = Allocators.References.Allocate<LiveInterval>((uint)_capacity);
Span<LiveInterval> newSpan = Span; var newSpan = Span;
oldSpan.CopyTo(newSpan); oldSpan.CopyTo(newSpan);
} }
@@ -63,7 +63,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
public override int GetHashCode() public override int GetHashCode()
{ {
return HashCode.Combine((nint)_data); return HashCode.Combine((IntPtr)_data);
} }
public override string ToString() public override string ToString()
@@ -16,12 +16,12 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{ {
if (Count + 1 > _capacity) if (Count + 1 > _capacity)
{ {
Span<int> oldSpan = Span; var oldSpan = Span;
_capacity = Math.Max(4, _capacity * 2); _capacity = Math.Max(4, _capacity * 2);
_items = Allocators.Default.Allocate<int>((uint)_capacity); _items = Allocators.Default.Allocate<int>((uint)_capacity);
Span<int> newSpan = Span; var newSpan = Span;
oldSpan.CopyTo(newSpan); oldSpan.CopyTo(newSpan);
} }
+10 -11
View File
@@ -1,6 +1,5 @@
using ARMeilleure.CodeGen.Linking; using ARMeilleure.CodeGen.Linking;
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using Microsoft.IO;
using Ryujinx.Common.Memory; using Ryujinx.Common.Memory;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -1107,17 +1106,17 @@ namespace ARMeilleure.CodeGen.X86
} }
else else
{ {
if ((flags & InstructionFlags.Prefix66) != 0) if (flags.HasFlag(InstructionFlags.Prefix66))
{ {
WriteByte(0x66); WriteByte(0x66);
} }
if ((flags & InstructionFlags.PrefixF2) != 0f) if (flags.HasFlag(InstructionFlags.PrefixF2))
{ {
WriteByte(0xf2); WriteByte(0xf2);
} }
if ((flags & InstructionFlags.PrefixF3) != 0f) if (flags.HasFlag(InstructionFlags.PrefixF3))
{ {
WriteByte(0xf3); WriteByte(0xf3);
} }
@@ -1325,8 +1324,8 @@ namespace ARMeilleure.CodeGen.X86
public (byte[], RelocInfo) GetCode() public (byte[], RelocInfo) GetCode()
{ {
Span<Jump> jumps = CollectionsMarshal.AsSpan(_jumps); var jumps = CollectionsMarshal.AsSpan(_jumps);
Span<Reloc> relocs = CollectionsMarshal.AsSpan(_relocs); var relocs = CollectionsMarshal.AsSpan(_relocs);
// Write jump relative offsets. // Write jump relative offsets.
bool modified; bool modified;
@@ -1411,13 +1410,13 @@ namespace ARMeilleure.CodeGen.X86
// Write the code, ignoring the dummy bytes after jumps, into a new stream. // Write the code, ignoring the dummy bytes after jumps, into a new stream.
_stream.Seek(0, SeekOrigin.Begin); _stream.Seek(0, SeekOrigin.Begin);
using RecyclableMemoryStream codeStream = MemoryStreamManager.Shared.GetStream(); using var codeStream = MemoryStreamManager.Shared.GetStream();
Assembler assembler = new(codeStream, HasRelocs); var assembler = new Assembler(codeStream, HasRelocs);
bool hasRelocs = HasRelocs; bool hasRelocs = HasRelocs;
int relocIndex = 0; int relocIndex = 0;
int relocOffset = 0; int relocOffset = 0;
RelocEntry[] relocEntries = hasRelocs var relocEntries = hasRelocs
? new RelocEntry[relocs.Length] ? new RelocEntry[relocs.Length]
: Array.Empty<RelocEntry>(); : Array.Empty<RelocEntry>();
@@ -1470,8 +1469,8 @@ namespace ARMeilleure.CodeGen.X86
_stream.CopyTo(codeStream); _stream.CopyTo(codeStream);
byte[] code = codeStream.ToArray(); var code = codeStream.ToArray();
RelocInfo relocInfo = new(relocEntries); var relocInfo = new RelocInfo(relocEntries);
return (code, relocInfo); return (code, relocInfo);
} }
+2 -2
View File
@@ -622,7 +622,7 @@ namespace ARMeilleure.CodeGen.X86
Debug.Assert(comp.Kind == OperandKind.Constant); Debug.Assert(comp.Kind == OperandKind.Constant);
X86Condition cond = ((Comparison)comp.AsInt32()).ToX86Condition(); var cond = ((Comparison)comp.AsInt32()).ToX86Condition();
GenerateCompareCommon(context, operation); GenerateCompareCommon(context, operation);
@@ -660,7 +660,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(); var cond = ((Comparison)comp.AsInt32()).ToX86Condition();
GenerateCompareCommon(context, operation); GenerateCompareCommon(context, operation);
@@ -53,7 +53,7 @@ namespace ARMeilleure.CodeGen.X86
memGetXcr0.Reprotect(0, (ulong)asmGetXcr0.Length, MemoryPermission.ReadAndExecute); memGetXcr0.Reprotect(0, (ulong)asmGetXcr0.Length, MemoryPermission.ReadAndExecute);
GetXcr0 fGetXcr0 = Marshal.GetDelegateForFunctionPointer<GetXcr0>(memGetXcr0.Pointer); var fGetXcr0 = Marshal.GetDelegateForFunctionPointer<GetXcr0>(memGetXcr0.Pointer);
return fGetXcr0(); return fGetXcr0();
} }
+1 -1
View File
@@ -759,7 +759,7 @@ namespace ARMeilleure.CodeGen.X86
Debug.Assert(comp.Kind == OperandKind.Constant); Debug.Assert(comp.Kind == OperandKind.Constant);
Comparison compType = (Comparison)comp.AsInt32(); var compType = (Comparison)comp.AsInt32();
return compType is Comparison.Equal or Comparison.NotEqual; return compType is Comparison.Equal or Comparison.NotEqual;
} }
+2 -2
View File
@@ -13,13 +13,13 @@ namespace ARMeilleure.CodeGen.X86
public static void RunPass(ControlFlowGraph cfg) public static void RunPass(ControlFlowGraph cfg)
{ {
Dictionary<ulong, Operand> constants = new(); var constants = new Dictionary<ulong, Operand>();
Operand GetConstantCopy(BasicBlock block, Operation operation, Operand source) Operand GetConstantCopy(BasicBlock block, Operation operation, Operand source)
{ {
// If the constant has many uses, we also force a new constant mov to be added, in order // If the constant has many uses, we also force a new constant mov to be added, in order
// to avoid overflow of the counts field (that is limited to 16 bits). // to avoid overflow of the counts field (that is limited to 16 bits).
if (!constants.TryGetValue(source.Value, out Operand constant) || constant.UsesCount > MaxConstantUses) if (!constants.TryGetValue(source.Value, out var constant) || constant.UsesCount > MaxConstantUses)
{ {
constant = Local(source.Type); constant = Local(source.Type);
+4 -4
View File
@@ -20,7 +20,7 @@ namespace ARMeilleure.Common
private List<PageInfo> _pages; private List<PageInfo> _pages;
private readonly ulong _pageSize; private readonly ulong _pageSize;
private readonly uint _pageCount; private readonly uint _pageCount;
private readonly List<nint> _extras; private readonly List<IntPtr> _extras;
public ArenaAllocator(uint pageSize, uint pageCount) public ArenaAllocator(uint pageSize, uint pageCount)
{ {
@@ -64,7 +64,7 @@ namespace ARMeilleure.Common
{ {
void* extra = NativeAllocator.Instance.Allocate(size); void* extra = NativeAllocator.Instance.Allocate(size);
_extras.Add((nint)extra); _extras.Add((IntPtr)extra);
return extra; return extra;
} }
@@ -114,7 +114,7 @@ namespace ARMeilleure.Common
} }
// Free extra blocks that are not page-sized // Free extra blocks that are not page-sized
foreach (nint ptr in _extras) foreach (IntPtr ptr in _extras)
{ {
NativeAllocator.Instance.Free((void*)ptr); NativeAllocator.Instance.Free((void*)ptr);
} }
@@ -173,7 +173,7 @@ namespace ARMeilleure.Common
NativeAllocator.Instance.Free(info.Pointer); NativeAllocator.Instance.Free(info.Pointer);
} }
foreach (nint ptr in _extras) foreach (IntPtr ptr in _extras)
{ {
NativeAllocator.Instance.Free((void*)ptr); NativeAllocator.Instance.Free((void*)ptr);
} }
+3 -3
View File
@@ -129,13 +129,13 @@ namespace ARMeilleure.Common
if (count > _count) if (count > _count)
{ {
long* oldMask = _masks; var oldMask = _masks;
Span<long> oldSpan = new(_masks, _count); var oldSpan = new Span<long>(_masks, _count);
_masks = _allocator.Allocate<long>((uint)count); _masks = _allocator.Allocate<long>((uint)count);
_count = count; _count = count;
Span<long> newSpan = new(_masks, _count); var newSpan = new Span<long>(_masks, _count);
oldSpan.CopyTo(newSpan); oldSpan.CopyTo(newSpan);
newSpan[oldSpan.Length..].Clear(); newSpan[oldSpan.Length..].Clear();
+8 -8
View File
@@ -15,7 +15,7 @@ namespace ARMeilleure.Common
private int _freeHint; private int _freeHint;
private readonly int _pageCapacity; // Number of entries per page. private readonly int _pageCapacity; // Number of entries per page.
private readonly int _pageLogCapacity; private readonly int _pageLogCapacity;
private readonly Dictionary<int, nint> _pages; private readonly Dictionary<int, IntPtr> _pages;
private readonly BitMap _allocated; private readonly BitMap _allocated;
/// <summary> /// <summary>
@@ -41,7 +41,7 @@ namespace ARMeilleure.Common
} }
_allocated = new BitMap(NativeAllocator.Instance); _allocated = new BitMap(NativeAllocator.Instance);
_pages = new Dictionary<int, nint>(); _pages = new Dictionary<int, IntPtr>();
_pageLogCapacity = BitOperations.Log2((uint)(pageSize / sizeof(TEntry))); _pageLogCapacity = BitOperations.Log2((uint)(pageSize / sizeof(TEntry)));
_pageCapacity = 1 << _pageLogCapacity; _pageCapacity = 1 << _pageLogCapacity;
} }
@@ -63,7 +63,7 @@ namespace ARMeilleure.Common
} }
int index = _freeHint++; int index = _freeHint++;
Span<TEntry> page = GetPage(index); var page = GetPage(index);
_allocated.Set(index); _allocated.Set(index);
@@ -111,7 +111,7 @@ namespace ARMeilleure.Common
throw new ArgumentException("Entry at the specified index was not allocated", nameof(index)); throw new ArgumentException("Entry at the specified index was not allocated", nameof(index));
} }
Span<TEntry> page = GetPage(index); var page = GetPage(index);
return ref GetValue(page, index); return ref GetValue(page, index);
} }
@@ -136,11 +136,11 @@ namespace ARMeilleure.Common
/// <returns>Page for the specified <see cref="index"/></returns> /// <returns>Page for the specified <see cref="index"/></returns>
private unsafe Span<TEntry> GetPage(int index) private unsafe Span<TEntry> GetPage(int index)
{ {
int pageIndex = (int)((uint)(index & ~(_pageCapacity - 1)) >> _pageLogCapacity); var pageIndex = (int)((uint)(index & ~(_pageCapacity - 1)) >> _pageLogCapacity);
if (!_pages.TryGetValue(pageIndex, out nint page)) if (!_pages.TryGetValue(pageIndex, out IntPtr page))
{ {
page = (nint)NativeAllocator.Instance.Allocate((uint)sizeof(TEntry) * (uint)_pageCapacity); page = (IntPtr)NativeAllocator.Instance.Allocate((uint)sizeof(TEntry) * (uint)_pageCapacity);
_pages.Add(pageIndex, page); _pages.Add(pageIndex, page);
} }
@@ -168,7 +168,7 @@ namespace ARMeilleure.Common
{ {
_allocated.Dispose(); _allocated.Dispose();
foreach (IntPtr page in _pages.Values) foreach (var page in _pages.Values)
{ {
NativeAllocator.Instance.Free((void*)page); NativeAllocator.Instance.Free((void*)page);
} }
+2 -2
View File
@@ -9,7 +9,7 @@ namespace ARMeilleure.Common
public override void* Allocate(ulong size) public override void* Allocate(ulong size)
{ {
void* result = (void*)Marshal.AllocHGlobal((nint)size); void* result = (void*)Marshal.AllocHGlobal((IntPtr)size);
if (result == null) if (result == null)
{ {
@@ -21,7 +21,7 @@ namespace ARMeilleure.Common
public override void Free(void* block) public override void Free(void* block)
{ {
Marshal.FreeHGlobal((nint)block); Marshal.FreeHGlobal((IntPtr)block);
} }
} }
} }
@@ -9,7 +9,7 @@ namespace ARMeilleure.Decoders
public OpCode32SimdDupElem(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode, isThumb) public OpCode32SimdDupElem(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode, isThumb)
{ {
int opc = (opCode >> 16) & 0xf; var opc = (opCode >> 16) & 0xf;
if ((opc & 0b1) == 1) if ((opc & 0b1) == 1)
{ {
@@ -21,7 +21,7 @@ namespace ARMeilleure.Decoders
Op = (opCode >> 20) & 0x1; Op = (opCode >> 20) & 0x1;
U = ((opCode >> 23) & 1) != 0; U = ((opCode >> 23) & 1) != 0;
int opc = (((opCode >> 23) & 1) << 4) | (((opCode >> 21) & 0x3) << 2) | ((opCode >> 5) & 0x3); var opc = (((opCode >> 23) & 1) << 4) | (((opCode >> 21) & 0x3) << 2) | ((opCode >> 5) & 0x3);
if ((opc & 0b01000) == 0b01000) if ((opc & 0b01000) == 0b01000)
{ {
+1 -1
View File
@@ -20,7 +20,7 @@ namespace ARMeilleure.Decoders
} }
else if (DataOp == DataOp.Logical) else if (DataOp == DataOp.Logical)
{ {
DecoderHelper.BitMask bm = DecoderHelper.DecodeBitMask(opCode, true); var bm = DecoderHelper.DecodeBitMask(opCode, true);
if (bm.IsUndefined) if (bm.IsUndefined)
{ {
+1 -1
View File
@@ -11,7 +11,7 @@ namespace ARMeilleure.Decoders
public OpCodeBfm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) public OpCodeBfm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
{ {
DecoderHelper.BitMask bm = DecoderHelper.DecodeBitMask(opCode, false); var bm = DecoderHelper.DecodeBitMask(opCode, false);
if (bm.IsUndefined) if (bm.IsUndefined)
{ {
@@ -69,7 +69,7 @@ namespace ARMeilleure.Decoders.Optimizations
} }
} }
List<Block> newBlocks = new(blocks.Count); var newBlocks = new List<Block>(blocks.Count);
// Finally, rebuild decoded block list, ignoring blocks outside the contiguous range. // Finally, rebuild decoded block list, ignoring blocks outside the contiguous range.
for (int i = 0; i < blocks.Count; i++) for (int i = 0; i < blocks.Count; i++)
+2 -2
View File
@@ -141,7 +141,7 @@ namespace ARMeilleure.Diagnostics
break; break;
case OperandKind.Memory: case OperandKind.Memory:
MemoryOperand memOp = operand.GetMemory(); var memOp = operand.GetMemory();
_builder.Append('['); _builder.Append('[');
@@ -284,7 +284,7 @@ namespace ARMeilleure.Diagnostics
public static string GetDump(ControlFlowGraph cfg) public static string GetDump(ControlFlowGraph cfg)
{ {
IRDumper dumper = new(1); var dumper = new IRDumper(1);
for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext) for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext)
{ {
@@ -415,7 +415,7 @@ namespace ARMeilleure.Instructions
{ {
IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp; IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp;
int msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width. var msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width.
Operand n = GetIntA32(context, op.Rn); Operand n = GetIntA32(context, op.Rn);
Operand res = context.ShiftRightSI(context.ShiftLeft(n, Const(31 - msb)), Const(31 - op.Msb)); Operand res = context.ShiftRightSI(context.ShiftLeft(n, Const(31 - msb)), Const(31 - op.Msb));
@@ -547,7 +547,7 @@ namespace ARMeilleure.Instructions
{ {
IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp; IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp;
int msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width. var msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width.
Operand n = GetIntA32(context, op.Rn); Operand n = GetIntA32(context, op.Rn);
Operand res = context.ShiftRightUI(context.ShiftLeft(n, Const(31 - msb)), Const(31 - op.Msb)); Operand res = context.ShiftRightUI(context.ShiftLeft(n, Const(31 - msb)), Const(31 - op.Msb));
@@ -1,5 +1,4 @@
using ARMeilleure.CodeGen.Linking; using ARMeilleure.CodeGen.Linking;
using ARMeilleure.Common;
using ARMeilleure.Decoders; using ARMeilleure.Decoders;
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.State; using ARMeilleure.State;
@@ -147,6 +146,12 @@ namespace ARMeilleure.Instructions
public static void EmitCall(ArmEmitterContext context, ulong immediate) public static void EmitCall(ArmEmitterContext context, ulong immediate)
{ {
if (context.IsSingleStep)
{
context.Return(Const(immediate));
return;
}
bool isRecursive = immediate == context.EntryAddress; bool isRecursive = immediate == context.EntryAddress;
if (isRecursive) if (isRecursive)
@@ -160,13 +165,25 @@ namespace ARMeilleure.Instructions
} }
public static void EmitVirtualCall(ArmEmitterContext context, Operand target) public static void EmitVirtualCall(ArmEmitterContext context, Operand target)
{
if (context.IsSingleStep)
{
if (target.Type == OperandType.I32)
{
target = context.ZeroExtend32(OperandType.I64, target);
}
context.Return(target);
}
else
{ {
EmitTableBranch(context, target, isJump: false); EmitTableBranch(context, target, isJump: false);
} }
}
public static void EmitVirtualJump(ArmEmitterContext context, Operand target, bool isReturn) public static void EmitVirtualJump(ArmEmitterContext context, Operand target, bool isReturn)
{ {
if (isReturn) if (isReturn || context.IsSingleStep)
{ {
EmitReturn(context, target); EmitReturn(context, target);
} }
@@ -206,7 +223,7 @@ namespace ARMeilleure.Instructions
Operand hostAddress; Operand hostAddress;
IAddressTable<ulong> table = context.FunctionTable; var table = context.FunctionTable;
// If address is mapped onto the function table, we can skip the table walk. Otherwise we fallback // If address is mapped onto the function table, we can skip the table walk. Otherwise we fallback
// onto the dispatch stub. // onto the dispatch stub.
@@ -231,7 +248,7 @@ namespace ARMeilleure.Instructions
for (int i = 0; i < table.Levels.Length; i++) for (int i = 0; i < table.Levels.Length; i++)
{ {
AddressTableLevel level = table.Levels[i]; var level = table.Levels[i];
int clearBits = 64 - (level.Index + level.Length); int clearBits = 64 - (level.Index + level.Length);
Operand index = context.ShiftLeft( Operand index = context.ShiftLeft(
@@ -143,8 +143,8 @@ namespace ARMeilleure.Instructions
Operand address = context.Copy(GetIntA32(context, op.Rn)); Operand address = context.Copy(GetIntA32(context, op.Rn));
bool exclusive = (accType & AccessType.Exclusive) != 0; var exclusive = (accType & AccessType.Exclusive) != 0;
bool ordered = (accType & AccessType.Ordered) != 0; var ordered = (accType & AccessType.Ordered) != 0;
if ((accType & AccessType.Load) != 0) if ((accType & AccessType.Load) != 0)
{ {
@@ -229,7 +229,7 @@ namespace ARMeilleure.Instructions
private static Operand ZerosOrOnes(ArmEmitterContext context, Operand fromBool, OperandType baseType) private static Operand ZerosOrOnes(ArmEmitterContext context, Operand fromBool, OperandType baseType)
{ {
Operand ones = (baseType == OperandType.I64) ? Const(-1L) : Const(-1); var ones = (baseType == OperandType.I64) ? Const(-1L) : Const(-1);
return context.ConditionalSelect(fromBool, ones, Const(baseType, 0L)); return context.ConditionalSelect(fromBool, ones, Const(baseType, 0L));
} }
@@ -118,15 +118,15 @@ namespace ARMeilleure.Instructions
{ {
OpCode32SimdCvtFFixed op = (OpCode32SimdCvtFFixed)context.CurrOp; OpCode32SimdCvtFFixed op = (OpCode32SimdCvtFFixed)context.CurrOp;
bool toFixed = op.Opc == 1; var toFixed = op.Opc == 1;
int fracBits = op.Fbits; int fracBits = op.Fbits;
bool unsigned = op.U; var unsigned = op.U;
if (toFixed) // F32 to S32 or U32 (fixed) if (toFixed) // F32 to S32 or U32 (fixed)
{ {
EmitVectorUnaryOpF32(context, (op1) => EmitVectorUnaryOpF32(context, (op1) =>
{ {
Operand scaledValue = context.Multiply(op1, ConstF(MathF.Pow(2f, fracBits))); var scaledValue = context.Multiply(op1, ConstF(MathF.Pow(2f, fracBits)));
MethodInfo info = unsigned ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU32)) : typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS32)); MethodInfo info = unsigned ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU32)) : typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS32));
return context.Call(info, scaledValue); return context.Call(info, scaledValue);
@@ -136,7 +136,7 @@ namespace ARMeilleure.Instructions
{ {
EmitVectorUnaryOpI32(context, (op1) => EmitVectorUnaryOpI32(context, (op1) =>
{ {
Operand floatValue = unsigned ? context.ConvertToFPUI(OperandType.FP32, op1) : context.ConvertToFP(OperandType.FP32, op1); var floatValue = unsigned ? context.ConvertToFPUI(OperandType.FP32, op1) : context.ConvertToFP(OperandType.FP32, op1);
return context.Multiply(floatValue, ConstF(1f / MathF.Pow(2f, fracBits))); return context.Multiply(floatValue, ConstF(1f / MathF.Pow(2f, fracBits)));
}, !unsigned); }, !unsigned);
@@ -87,7 +87,7 @@ namespace ARMeilleure.Instructions
{ {
if (op.Replicate) if (op.Replicate)
{ {
int regs = (count > 1) ? 1 : op.Increment; var regs = (count > 1) ? 1 : op.Increment;
for (int reg = 0; reg < regs; reg++) for (int reg = 0; reg < regs; reg++)
{ {
int dreg = reg + d; int dreg = reg + d;
@@ -1,59 +1,35 @@
using System; using System;
#if ANDROID
using System.Runtime.CompilerServices;
#else
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
#endif
namespace ARMeilleure.Instructions namespace ARMeilleure.Instructions
{ {
static class MathHelper static class MathHelper
{ {
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double Abs(double value) public static double Abs(double value)
{ {
return Math.Abs(value); return Math.Abs(value);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double Ceiling(double value) public static double Ceiling(double value)
{ {
return Math.Ceiling(value); return Math.Ceiling(value);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double Floor(double value) public static double Floor(double value)
{ {
return Math.Floor(value); return Math.Floor(value);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double Round(double value, int mode) public static double Round(double value, int mode)
{ {
return Math.Round(value, (MidpointRounding)mode); return Math.Round(value, (MidpointRounding)mode);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double Truncate(double value) public static double Truncate(double value)
{ {
return Math.Truncate(value); return Math.Truncate(value);
@@ -62,51 +38,31 @@ namespace ARMeilleure.Instructions
static class MathHelperF static class MathHelperF
{ {
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float Abs(float value) public static float Abs(float value)
{ {
return MathF.Abs(value); return MathF.Abs(value);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float Ceiling(float value) public static float Ceiling(float value)
{ {
return MathF.Ceiling(value); return MathF.Ceiling(value);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float Floor(float value) public static float Floor(float value)
{ {
return MathF.Floor(value); return MathF.Floor(value);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float Round(float value, int mode) public static float Round(float value, int mode)
{ {
return MathF.Round(value, (MidpointRounding)mode); return MathF.Round(value, (MidpointRounding)mode);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float Truncate(float value) public static float Truncate(float value)
{ {
return MathF.Truncate(value); return MathF.Truncate(value);
+4 -100
View File
@@ -2,11 +2,7 @@ using ARMeilleure.Memory;
using ARMeilleure.State; using ARMeilleure.State;
using ARMeilleure.Translation; using ARMeilleure.Translation;
using System; using System;
#if ANDROID
using System.Runtime.CompilerServices;
#else
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
#endif
namespace ARMeilleure.Instructions namespace ARMeilleure.Instructions
{ {
@@ -39,11 +35,7 @@ namespace ARMeilleure.Instructions
Context = null; Context = null;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static void Break(ulong address, int imm) public static void Break(ulong address, int imm)
{ {
Statistics.PauseTimer(); Statistics.PauseTimer();
@@ -53,11 +45,7 @@ namespace ARMeilleure.Instructions
Statistics.ResumeTimer(); Statistics.ResumeTimer();
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static void SupervisorCall(ulong address, int imm) public static void SupervisorCall(ulong address, int imm)
{ {
Statistics.PauseTimer(); Statistics.PauseTimer();
@@ -67,11 +55,7 @@ namespace ARMeilleure.Instructions
Statistics.ResumeTimer(); Statistics.ResumeTimer();
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static void Undefined(ulong address, int opCode) public static void Undefined(ulong address, int opCode)
{ {
Statistics.PauseTimer(); Statistics.PauseTimer();
@@ -82,51 +66,31 @@ namespace ARMeilleure.Instructions
} }
#region "System registers" #region "System registers"
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static ulong GetCtrEl0() public static ulong GetCtrEl0()
{ {
return GetContext().CtrEl0; return GetContext().CtrEl0;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static ulong GetDczidEl0() public static ulong GetDczidEl0()
{ {
return GetContext().DczidEl0; return GetContext().DczidEl0;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static ulong GetCntfrqEl0() public static ulong GetCntfrqEl0()
{ {
return GetContext().CntfrqEl0; return GetContext().CntfrqEl0;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static ulong GetCntpctEl0() public static ulong GetCntpctEl0()
{ {
return GetContext().CntpctEl0; return GetContext().CntpctEl0;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static ulong GetCntvctEl0() public static ulong GetCntvctEl0()
{ {
return GetContext().CntvctEl0; return GetContext().CntvctEl0;
@@ -134,51 +98,31 @@ namespace ARMeilleure.Instructions
#endregion #endregion
#region "Read" #region "Read"
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static byte ReadByte(ulong address) public static byte ReadByte(ulong address)
{ {
return GetMemoryManager().ReadGuest<byte>(address); return GetMemoryManager().ReadGuest<byte>(address);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static ushort ReadUInt16(ulong address) public static ushort ReadUInt16(ulong address)
{ {
return GetMemoryManager().ReadGuest<ushort>(address); return GetMemoryManager().ReadGuest<ushort>(address);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static uint ReadUInt32(ulong address) public static uint ReadUInt32(ulong address)
{ {
return GetMemoryManager().ReadGuest<uint>(address); return GetMemoryManager().ReadGuest<uint>(address);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static ulong ReadUInt64(ulong address) public static ulong ReadUInt64(ulong address)
{ {
return GetMemoryManager().ReadGuest<ulong>(address); return GetMemoryManager().ReadGuest<ulong>(address);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 ReadVector128(ulong address) public static V128 ReadVector128(ulong address)
{ {
return GetMemoryManager().ReadGuest<V128>(address); return GetMemoryManager().ReadGuest<V128>(address);
@@ -186,92 +130,56 @@ namespace ARMeilleure.Instructions
#endregion #endregion
#region "Write" #region "Write"
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static void WriteByte(ulong address, byte value) public static void WriteByte(ulong address, byte value)
{ {
GetMemoryManager().WriteGuest(address, value); GetMemoryManager().WriteGuest(address, value);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static void WriteUInt16(ulong address, ushort value) public static void WriteUInt16(ulong address, ushort value)
{ {
GetMemoryManager().WriteGuest(address, value); GetMemoryManager().WriteGuest(address, value);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static void WriteUInt32(ulong address, uint value) public static void WriteUInt32(ulong address, uint value)
{ {
GetMemoryManager().WriteGuest(address, value); GetMemoryManager().WriteGuest(address, value);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static void WriteUInt64(ulong address, ulong value) public static void WriteUInt64(ulong address, ulong value)
{ {
GetMemoryManager().WriteGuest(address, value); GetMemoryManager().WriteGuest(address, value);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static void WriteVector128(ulong address, V128 value) public static void WriteVector128(ulong address, V128 value)
{ {
GetMemoryManager().WriteGuest(address, value); GetMemoryManager().WriteGuest(address, value);
} }
#endregion #endregion
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static void EnqueueForRejit(ulong address) public static void EnqueueForRejit(ulong address)
{ {
Context.Translator.EnqueueForRejit(address, GetContext().ExecutionMode); Context.Translator.EnqueueForRejit(address, GetContext().ExecutionMode);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static void SignalMemoryTracking(ulong address, ulong size, byte write) public static void SignalMemoryTracking(ulong address, ulong size, byte write)
{ {
GetMemoryManager().SignalMemoryTracking(address, size, write == 1); GetMemoryManager().SignalMemoryTracking(address, size, write == 1);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static void ThrowInvalidMemoryAccess(ulong address) public static void ThrowInvalidMemoryAccess(ulong address)
{ {
throw new InvalidAccessException(address); throw new InvalidAccessException(address);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static ulong GetFunctionAddress(ulong address) public static ulong GetFunctionAddress(ulong address)
{ {
TranslatedFunction function = Context.Translator.GetOrTranslate(address, GetContext().ExecutionMode); TranslatedFunction function = Context.Translator.GetOrTranslate(address, GetContext().ExecutionMode);
@@ -279,28 +187,24 @@ namespace ARMeilleure.Instructions
return (ulong)function.FuncPointer.ToInt64(); return (ulong)function.FuncPointer.ToInt64();
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static void InvalidateCacheLine(ulong address) public static void InvalidateCacheLine(ulong address)
{ {
Context.Translator.InvalidateJitCacheRegion(address, InstEmit.DczSizeInBytes); Context.Translator.InvalidateJitCacheRegion(address, InstEmit.DczSizeInBytes);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static byte CheckSynchronization() public static byte CheckSynchronization()
{ {
Statistics.PauseTimer(); Statistics.PauseTimer();
ExecutionContext context = GetContext(); ExecutionContext context = GetContext();
// If debugging, we'll handle interrupts outside
if (!Optimizations.EnableDebugging)
{
context.CheckInterrupt(); context.CheckInterrupt();
}
Statistics.ResumeTimer(); Statistics.ResumeTimer();
@@ -1,21 +1,13 @@
using ARMeilleure.State; using ARMeilleure.State;
using System; using System;
#if ANDROID
using System.Runtime.CompilerServices;
#else
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
#endif
namespace ARMeilleure.Instructions namespace ARMeilleure.Instructions
{ {
static class SoftFallback static class SoftFallback
{ {
#region "ShrImm64" #region "ShrImm64"
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static long SignedShrImm64(long value, long roundConst, int shift) public static long SignedShrImm64(long value, long roundConst, int shift)
{ {
if (roundConst == 0L) if (roundConst == 0L)
@@ -58,11 +50,7 @@ namespace ARMeilleure.Instructions
} }
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static ulong UnsignedShrImm64(ulong value, long roundConst, int shift) public static ulong UnsignedShrImm64(ulong value, long roundConst, int shift)
{ {
if (roundConst == 0L) if (roundConst == 0L)
@@ -107,11 +95,7 @@ namespace ARMeilleure.Instructions
#endregion #endregion
#region "Saturation" #region "Saturation"
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static int SatF32ToS32(float value) public static int SatF32ToS32(float value)
{ {
if (float.IsNaN(value)) if (float.IsNaN(value))
@@ -123,11 +107,7 @@ namespace ARMeilleure.Instructions
value <= int.MinValue ? int.MinValue : (int)value; value <= int.MinValue ? int.MinValue : (int)value;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static long SatF32ToS64(float value) public static long SatF32ToS64(float value)
{ {
if (float.IsNaN(value)) if (float.IsNaN(value))
@@ -139,11 +119,7 @@ namespace ARMeilleure.Instructions
value <= long.MinValue ? long.MinValue : (long)value; value <= long.MinValue ? long.MinValue : (long)value;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static uint SatF32ToU32(float value) public static uint SatF32ToU32(float value)
{ {
if (float.IsNaN(value)) if (float.IsNaN(value))
@@ -155,11 +131,7 @@ namespace ARMeilleure.Instructions
value <= uint.MinValue ? uint.MinValue : (uint)value; value <= uint.MinValue ? uint.MinValue : (uint)value;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static ulong SatF32ToU64(float value) public static ulong SatF32ToU64(float value)
{ {
if (float.IsNaN(value)) if (float.IsNaN(value))
@@ -171,11 +143,7 @@ namespace ARMeilleure.Instructions
value <= ulong.MinValue ? ulong.MinValue : (ulong)value; value <= ulong.MinValue ? ulong.MinValue : (ulong)value;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static int SatF64ToS32(double value) public static int SatF64ToS32(double value)
{ {
if (double.IsNaN(value)) if (double.IsNaN(value))
@@ -187,11 +155,7 @@ namespace ARMeilleure.Instructions
value <= int.MinValue ? int.MinValue : (int)value; value <= int.MinValue ? int.MinValue : (int)value;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static long SatF64ToS64(double value) public static long SatF64ToS64(double value)
{ {
if (double.IsNaN(value)) if (double.IsNaN(value))
@@ -203,11 +167,7 @@ namespace ARMeilleure.Instructions
value <= long.MinValue ? long.MinValue : (long)value; value <= long.MinValue ? long.MinValue : (long)value;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static uint SatF64ToU32(double value) public static uint SatF64ToU32(double value)
{ {
if (double.IsNaN(value)) if (double.IsNaN(value))
@@ -219,11 +179,7 @@ namespace ARMeilleure.Instructions
value <= uint.MinValue ? uint.MinValue : (uint)value; value <= uint.MinValue ? uint.MinValue : (uint)value;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static ulong SatF64ToU64(double value) public static ulong SatF64ToU64(double value)
{ {
if (double.IsNaN(value)) if (double.IsNaN(value))
@@ -237,11 +193,7 @@ namespace ARMeilleure.Instructions
#endregion #endregion
#region "Count" #region "Count"
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static ulong CountLeadingSigns(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.). public static ulong CountLeadingSigns(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
{ {
value ^= value >> 1; value ^= value >> 1;
@@ -261,11 +213,7 @@ namespace ARMeilleure.Instructions
private static ReadOnlySpan<byte> ClzNibbleTbl => [4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]; private static ReadOnlySpan<byte> ClzNibbleTbl => [4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0];
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static ulong CountLeadingZeros(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.). public static ulong CountLeadingZeros(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
{ {
if (value == 0ul) if (value == 0ul)
@@ -289,81 +237,49 @@ namespace ARMeilleure.Instructions
#endregion #endregion
#region "Table" #region "Table"
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 Tbl1(V128 vector, int bytes, V128 tb0) public static V128 Tbl1(V128 vector, int bytes, V128 tb0)
{ {
return TblOrTbx(default, vector, bytes, tb0); return TblOrTbx(default, vector, bytes, tb0);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 Tbl2(V128 vector, int bytes, V128 tb0, V128 tb1) public static V128 Tbl2(V128 vector, int bytes, V128 tb0, V128 tb1)
{ {
return TblOrTbx(default, vector, bytes, tb0, tb1); return TblOrTbx(default, vector, bytes, tb0, tb1);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 Tbl3(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2) public static V128 Tbl3(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2)
{ {
return TblOrTbx(default, vector, bytes, tb0, tb1, tb2); return TblOrTbx(default, vector, bytes, tb0, tb1, tb2);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 Tbl4(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3) 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); return TblOrTbx(default, vector, bytes, tb0, tb1, tb2, tb3);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 Tbx1(V128 dest, V128 vector, int bytes, V128 tb0) public static V128 Tbx1(V128 dest, V128 vector, int bytes, V128 tb0)
{ {
return TblOrTbx(dest, vector, bytes, tb0); return TblOrTbx(dest, vector, bytes, tb0);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 Tbx2(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1) public static V128 Tbx2(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1)
{ {
return TblOrTbx(dest, vector, bytes, tb0, tb1); return TblOrTbx(dest, vector, bytes, tb0, tb1);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 Tbx3(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2) public static V128 Tbx3(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2)
{ {
return TblOrTbx(dest, vector, bytes, tb0, tb1, tb2); return TblOrTbx(dest, vector, bytes, tb0, tb1, tb2);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 Tbx4(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3) 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); return TblOrTbx(dest, vector, bytes, tb0, tb1, tb2, tb3);
@@ -405,54 +321,22 @@ namespace ARMeilleure.Instructions
private const uint Crc32RevPoly = 0xedb88320; private const uint Crc32RevPoly = 0xedb88320;
private const uint Crc32cRevPoly = 0x82f63b78; private const uint Crc32cRevPoly = 0x82f63b78;
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static uint Crc32b(uint crc, byte value) => Crc32(crc, Crc32RevPoly, value); public static uint Crc32b(uint crc, byte value) => Crc32(crc, Crc32RevPoly, value);
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static uint Crc32h(uint crc, ushort value) => Crc32h(crc, Crc32RevPoly, value); public static uint Crc32h(uint crc, ushort value) => Crc32h(crc, Crc32RevPoly, value);
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static uint Crc32w(uint crc, uint value) => Crc32w(crc, Crc32RevPoly, value); public static uint Crc32w(uint crc, uint value) => Crc32w(crc, Crc32RevPoly, value);
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static uint Crc32x(uint crc, ulong value) => Crc32x(crc, Crc32RevPoly, value); public static uint Crc32x(uint crc, ulong value) => Crc32x(crc, Crc32RevPoly, value);
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static uint Crc32cb(uint crc, byte value) => Crc32(crc, Crc32cRevPoly, value); public static uint Crc32cb(uint crc, byte value) => Crc32(crc, Crc32cRevPoly, value);
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static uint Crc32ch(uint crc, ushort value) => Crc32h(crc, Crc32cRevPoly, value); public static uint Crc32ch(uint crc, ushort value) => Crc32h(crc, Crc32cRevPoly, value);
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static uint Crc32cw(uint crc, uint value) => Crc32w(crc, Crc32cRevPoly, value); public static uint Crc32cw(uint crc, uint value) => Crc32w(crc, Crc32cRevPoly, value);
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static uint Crc32cx(uint crc, ulong value) => Crc32x(crc, Crc32cRevPoly, value); public static uint Crc32cx(uint crc, ulong value) => Crc32x(crc, Crc32cRevPoly, value);
private static uint Crc32h(uint crc, uint poly, ushort val) private static uint Crc32h(uint crc, uint poly, ushort val)
@@ -503,41 +387,25 @@ namespace ARMeilleure.Instructions
#endregion #endregion
#region "Aes" #region "Aes"
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 Decrypt(V128 value, V128 roundKey) public static V128 Decrypt(V128 value, V128 roundKey)
{ {
return CryptoHelper.AesInvSubBytes(CryptoHelper.AesInvShiftRows(value ^ roundKey)); return CryptoHelper.AesInvSubBytes(CryptoHelper.AesInvShiftRows(value ^ roundKey));
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 Encrypt(V128 value, V128 roundKey) public static V128 Encrypt(V128 value, V128 roundKey)
{ {
return CryptoHelper.AesSubBytes(CryptoHelper.AesShiftRows(value ^ roundKey)); return CryptoHelper.AesSubBytes(CryptoHelper.AesShiftRows(value ^ roundKey));
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 InverseMixColumns(V128 value) public static V128 InverseMixColumns(V128 value)
{ {
return CryptoHelper.AesInvMixColumns(value); return CryptoHelper.AesInvMixColumns(value);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 MixColumns(V128 value) public static V128 MixColumns(V128 value)
{ {
return CryptoHelper.AesMixColumns(value); return CryptoHelper.AesMixColumns(value);
@@ -545,11 +413,7 @@ namespace ARMeilleure.Instructions
#endregion #endregion
#region "Sha1" #region "Sha1"
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 HashChoose(V128 hash_abcd, uint hash_e, V128 wk) public static V128 HashChoose(V128 hash_abcd, uint hash_e, V128 wk)
{ {
for (int e = 0; e <= 3; e++) for (int e = 0; e <= 3; e++)
@@ -570,21 +434,13 @@ namespace ARMeilleure.Instructions
return hash_abcd; return hash_abcd;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static uint FixedRotate(uint hash_e) public static uint FixedRotate(uint hash_e)
{ {
return hash_e.Rol(30); return hash_e.Rol(30);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 HashMajority(V128 hash_abcd, uint hash_e, V128 wk) public static V128 HashMajority(V128 hash_abcd, uint hash_e, V128 wk)
{ {
for (int e = 0; e <= 3; e++) for (int e = 0; e <= 3; e++)
@@ -605,11 +461,7 @@ namespace ARMeilleure.Instructions
return hash_abcd; return hash_abcd;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 HashParity(V128 hash_abcd, uint hash_e, V128 wk) public static V128 HashParity(V128 hash_abcd, uint hash_e, V128 wk)
{ {
for (int e = 0; e <= 3; e++) for (int e = 0; e <= 3; e++)
@@ -630,11 +482,7 @@ namespace ARMeilleure.Instructions
return hash_abcd; return hash_abcd;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 Sha1SchedulePart1(V128 w0_3, V128 w4_7, V128 w8_11) public static V128 Sha1SchedulePart1(V128 w0_3, V128 w4_7, V128 w8_11)
{ {
ulong t2 = w4_7.Extract<ulong>(0); ulong t2 = w4_7.Extract<ulong>(0);
@@ -645,11 +493,7 @@ namespace ARMeilleure.Instructions
return result ^ (w0_3 ^ w8_11); return result ^ (w0_3 ^ w8_11);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 Sha1SchedulePart2(V128 tw0_3, V128 w12_15) public static V128 Sha1SchedulePart2(V128 tw0_3, V128 w12_15)
{ {
V128 t = tw0_3 ^ (w12_15 >> 32); V128 t = tw0_3 ^ (w12_15 >> 32);
@@ -694,31 +538,19 @@ namespace ARMeilleure.Instructions
#endregion #endregion
#region "Sha256" #region "Sha256"
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 HashLower(V128 hash_abcd, V128 hash_efgh, V128 wk) public static V128 HashLower(V128 hash_abcd, V128 hash_efgh, V128 wk)
{ {
return Sha256Hash(hash_abcd, hash_efgh, wk, part1: true); return Sha256Hash(hash_abcd, hash_efgh, wk, part1: true);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 HashUpper(V128 hash_abcd, V128 hash_efgh, V128 wk) public static V128 HashUpper(V128 hash_abcd, V128 hash_efgh, V128 wk)
{ {
return Sha256Hash(hash_abcd, hash_efgh, wk, part1: false); return Sha256Hash(hash_abcd, hash_efgh, wk, part1: false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 Sha256SchedulePart1(V128 w0_3, V128 w4_7) public static V128 Sha256SchedulePart1(V128 w0_3, V128 w4_7)
{ {
V128 result = new(); V128 result = new();
@@ -737,11 +569,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 Sha256SchedulePart2(V128 w0_3, V128 w8_11, V128 w12_15) public static V128 Sha256SchedulePart2(V128 w0_3, V128 w8_11, V128 w12_15)
{ {
V128 result = new(); V128 result = new();
@@ -843,11 +671,7 @@ namespace ARMeilleure.Instructions
} }
#endregion #endregion
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static V128 PolynomialMult64_128(ulong op1, ulong op2) public static V128 PolynomialMult64_128(ulong op1, ulong op2)
{ {
V128 result = V128.Zero; V128 result = V128.Zero;
+2 -358
View File
@@ -1,11 +1,7 @@
using ARMeilleure.State; using ARMeilleure.State;
using System; using System;
using System.Diagnostics; using System.Diagnostics;
#if ANDROID
using System.Runtime.CompilerServices;
#else
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
#endif
namespace ARMeilleure.Instructions namespace ARMeilleure.Instructions
{ {
@@ -317,11 +313,7 @@ namespace ARMeilleure.Instructions
static class SoftFloat16_32 static class SoftFloat16_32
{ {
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPConvert(ushort valueBits) public static float FPConvert(ushort valueBits)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -497,11 +489,7 @@ namespace ARMeilleure.Instructions
static class SoftFloat16_64 static class SoftFloat16_64
{ {
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPConvert(ushort valueBits) public static double FPConvert(ushort valueBits)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -677,11 +665,7 @@ namespace ARMeilleure.Instructions
static class SoftFloat32_16 static class SoftFloat32_16
{ {
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static ushort FPConvert(float value) public static ushort FPConvert(float value)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -801,21 +785,13 @@ namespace ARMeilleure.Instructions
static class SoftFloat32 static class SoftFloat32
{ {
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPAdd(float value1, float value2) public static float FPAdd(float value1, float value2)
{ {
return FPAddFpscrImpl(value1, value2, false); return FPAddFpscrImpl(value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPAddFpscr(float value1, float value2, byte standardFpscr) public static float FPAddFpscr(float value1, float value2, byte standardFpscr)
{ {
return FPAddFpscrImpl(value1, value2, standardFpscr == 1); return FPAddFpscrImpl(value1, value2, standardFpscr == 1);
@@ -872,11 +848,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static int FPCompare(float value1, float value2, byte signalNaNs) public static int FPCompare(float value1, float value2, byte signalNaNs)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -915,11 +887,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPCompareEQ(float value1, float value2) public static float FPCompareEQ(float value1, float value2)
{ {
return FPCompareEQFpscrImpl(value1, value2, false); return FPCompareEQFpscrImpl(value1, value2, false);
@@ -952,31 +920,19 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPCompareEQFpscr(float value1, float value2, byte standardFpscr) public static float FPCompareEQFpscr(float value1, float value2, byte standardFpscr)
{ {
return FPCompareEQFpscrImpl(value1, value2, standardFpscr == 1); return FPCompareEQFpscrImpl(value1, value2, standardFpscr == 1);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPCompareGE(float value1, float value2) public static float FPCompareGE(float value1, float value2)
{ {
return FPCompareGEFpscrImpl(value1, value2, false); return FPCompareGEFpscrImpl(value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPCompareGEFpscr(float value1, float value2, byte standardFpscr) public static float FPCompareGEFpscr(float value1, float value2, byte standardFpscr)
{ {
return FPCompareGEFpscrImpl(value1, value2, standardFpscr == 1); return FPCompareGEFpscrImpl(value1, value2, standardFpscr == 1);
@@ -1006,21 +962,13 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPCompareGT(float value1, float value2) public static float FPCompareGT(float value1, float value2)
{ {
return FPCompareGTFpscrImpl(value1, value2, false); return FPCompareGTFpscrImpl(value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPCompareGTFpscr(float value1, float value2, byte standardFpscr) public static float FPCompareGTFpscr(float value1, float value2, byte standardFpscr)
{ {
return FPCompareGTFpscrImpl(value1, value2, standardFpscr == 1); return FPCompareGTFpscrImpl(value1, value2, standardFpscr == 1);
@@ -1050,51 +998,31 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPCompareLE(float value1, float value2) public static float FPCompareLE(float value1, float value2)
{ {
return FPCompareGEFpscrImpl(value2, value1, false); return FPCompareGEFpscrImpl(value2, value1, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPCompareLT(float value1, float value2) public static float FPCompareLT(float value1, float value2)
{ {
return FPCompareGTFpscrImpl(value2, value1, false); return FPCompareGTFpscrImpl(value2, value1, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPCompareLEFpscr(float value1, float value2, byte standardFpscr) public static float FPCompareLEFpscr(float value1, float value2, byte standardFpscr)
{ {
return FPCompareGEFpscrImpl(value2, value1, standardFpscr == 1); return FPCompareGEFpscrImpl(value2, value1, standardFpscr == 1);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPCompareLTFpscr(float value1, float value2, byte standardFpscr) public static float FPCompareLTFpscr(float value1, float value2, byte standardFpscr)
{ {
return FPCompareGEFpscrImpl(value2, value1, standardFpscr == 1); return FPCompareGEFpscrImpl(value2, value1, standardFpscr == 1);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPDiv(float value1, float value2) public static float FPDiv(float value1, float value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -1147,21 +1075,13 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPMax(float value1, float value2) public static float FPMax(float value1, float value2)
{ {
return FPMaxFpscrImpl(value1, value2, false); return FPMaxFpscrImpl(value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPMaxFpscr(float value1, float value2, byte standardFpscr) public static float FPMaxFpscr(float value1, float value2, byte standardFpscr)
{ {
return FPMaxFpscrImpl(value1, value2, standardFpscr == 1); return FPMaxFpscrImpl(value1, value2, standardFpscr == 1);
@@ -1228,11 +1148,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPMaxNum(float value1, float value2) public static float FPMaxNum(float value1, float value2)
{ {
return FPMaxNumFpscrImpl(value1, value2, false); return FPMaxNumFpscrImpl(value1, value2, false);
@@ -1258,31 +1174,19 @@ namespace ARMeilleure.Instructions
return FPMaxFpscrImpl(value1, value2, standardFpscr); return FPMaxFpscrImpl(value1, value2, standardFpscr);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPMaxNumFpscr(float value1, float value2, byte standardFpscr) public static float FPMaxNumFpscr(float value1, float value2, byte standardFpscr)
{ {
return FPMaxNumFpscrImpl(value1, value2, standardFpscr == 1); return FPMaxNumFpscrImpl(value1, value2, standardFpscr == 1);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPMin(float value1, float value2) public static float FPMin(float value1, float value2)
{ {
return FPMinFpscrImpl(value1, value2, false); return FPMinFpscrImpl(value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPMinFpscr(float value1, float value2, byte standardFpscr) public static float FPMinFpscr(float value1, float value2, byte standardFpscr)
{ {
return FPMinFpscrImpl(value1, value2, standardFpscr == 1); return FPMinFpscrImpl(value1, value2, standardFpscr == 1);
@@ -1349,21 +1253,13 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPMinNum(float value1, float value2) public static float FPMinNum(float value1, float value2)
{ {
return FPMinNumFpscrImpl(value1, value2, false); return FPMinNumFpscrImpl(value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPMinNumFpscr(float value1, float value2, byte standardFpscr) public static float FPMinNumFpscr(float value1, float value2, byte standardFpscr)
{ {
return FPMinNumFpscrImpl(value1, value2, standardFpscr == 1); return FPMinNumFpscrImpl(value1, value2, standardFpscr == 1);
@@ -1389,21 +1285,13 @@ namespace ARMeilleure.Instructions
return FPMinFpscrImpl(value1, value2, standardFpscr); return FPMinFpscrImpl(value1, value2, standardFpscr);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPMul(float value1, float value2) public static float FPMul(float value1, float value2)
{ {
return FPMulFpscrImpl(value1, value2, false); return FPMulFpscrImpl(value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPMulFpscr(float value1, float value2, byte standardFpscr) public static float FPMulFpscr(float value1, float value2, byte standardFpscr)
{ {
return FPMulFpscrImpl(value1, value2, standardFpscr == 1); return FPMulFpscrImpl(value1, value2, standardFpscr == 1);
@@ -1456,21 +1344,13 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPMulAdd(float valueA, float value1, float value2) public static float FPMulAdd(float valueA, float value1, float value2)
{ {
return FPMulAddFpscrImpl(valueA, value1, value2, false); return FPMulAddFpscrImpl(valueA, value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPMulAddFpscr(float valueA, float value1, float value2, byte standardFpscr) public static float FPMulAddFpscr(float valueA, float value1, float value2, byte standardFpscr)
{ {
return FPMulAddFpscrImpl(valueA, value1, value2, standardFpscr == 1); return FPMulAddFpscrImpl(valueA, value1, value2, standardFpscr == 1);
@@ -1542,11 +1422,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPMulSub(float valueA, float value1, float value2) public static float FPMulSub(float valueA, float value1, float value2)
{ {
value1 = value1.FPNeg(); value1 = value1.FPNeg();
@@ -1554,11 +1430,7 @@ namespace ARMeilleure.Instructions
return FPMulAddFpscrImpl(valueA, value1, value2, false); return FPMulAddFpscrImpl(valueA, value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPMulSubFpscr(float valueA, float value1, float value2, byte standardFpscr) public static float FPMulSubFpscr(float valueA, float value1, float value2, byte standardFpscr)
{ {
value1 = value1.FPNeg(); value1 = value1.FPNeg();
@@ -1566,11 +1438,7 @@ namespace ARMeilleure.Instructions
return FPMulAddFpscrImpl(valueA, value1, value2, standardFpscr == 1); return FPMulAddFpscrImpl(valueA, value1, value2, standardFpscr == 1);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPMulX(float value1, float value2) public static float FPMulX(float value1, float value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -1616,11 +1484,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPNegMulAdd(float valueA, float value1, float value2) public static float FPNegMulAdd(float valueA, float value1, float value2)
{ {
valueA = valueA.FPNeg(); valueA = valueA.FPNeg();
@@ -1629,11 +1493,7 @@ namespace ARMeilleure.Instructions
return FPMulAddFpscrImpl(valueA, value1, value2, false); return FPMulAddFpscrImpl(valueA, value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPNegMulSub(float valueA, float value1, float value2) public static float FPNegMulSub(float valueA, float value1, float value2)
{ {
valueA = valueA.FPNeg(); valueA = valueA.FPNeg();
@@ -1641,21 +1501,13 @@ namespace ARMeilleure.Instructions
return FPMulAddFpscrImpl(valueA, value1, value2, false); return FPMulAddFpscrImpl(valueA, value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPRecipEstimate(float value) public static float FPRecipEstimate(float value)
{ {
return FPRecipEstimateFpscrImpl(value, false); return FPRecipEstimateFpscrImpl(value, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPRecipEstimateFpscr(float value, byte standardFpscr) public static float FPRecipEstimateFpscr(float value, byte standardFpscr)
{ {
return FPRecipEstimateFpscrImpl(value, standardFpscr == 1); return FPRecipEstimateFpscrImpl(value, standardFpscr == 1);
@@ -1686,7 +1538,7 @@ namespace ARMeilleure.Instructions
} }
else if (MathF.Abs(value) < MathF.Pow(2f, -128)) else if (MathF.Abs(value) < MathF.Pow(2f, -128))
{ {
bool overflowToInf = fpcr.GetRoundingMode() switch var overflowToInf = fpcr.GetRoundingMode() switch
{ {
FPRoundingMode.ToNearest => true, FPRoundingMode.ToNearest => true,
FPRoundingMode.TowardsPlusInfinity => !sign, FPRoundingMode.TowardsPlusInfinity => !sign,
@@ -1748,11 +1600,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPRecipStep(float value1, float value2) public static float FPRecipStep(float value1, float value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -1787,11 +1635,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPRecipStepFused(float value1, float value2) public static float FPRecipStepFused(float value1, float value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -1835,11 +1679,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPRecpX(float value) public static float FPRecpX(float value)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -1865,21 +1705,13 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPRSqrtEstimate(float value) public static float FPRSqrtEstimate(float value)
{ {
return FPRSqrtEstimateFpscrImpl(value, false); return FPRSqrtEstimateFpscrImpl(value, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPRSqrtEstimateFpscr(float value, byte standardFpscr) public static float FPRSqrtEstimateFpscr(float value, byte standardFpscr)
{ {
return FPRSqrtEstimateFpscrImpl(value, standardFpscr == 1); return FPRSqrtEstimateFpscrImpl(value, standardFpscr == 1);
@@ -1999,11 +1831,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPRSqrtStep(float value1, float value2) public static float FPRSqrtStep(float value1, float value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -2038,11 +1866,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPRSqrtStepFused(float value1, float value2) public static float FPRSqrtStepFused(float value1, float value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -2086,11 +1910,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPSqrt(float value) public static float FPSqrt(float value)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -2133,11 +1953,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static float FPSub(float value1, float value2) public static float FPSub(float value1, float value2)
{ {
return FPSubFpscrImpl(value1, value2, false); return FPSubFpscrImpl(value1, value2, false);
@@ -2384,11 +2200,7 @@ namespace ARMeilleure.Instructions
static class SoftFloat64_16 static class SoftFloat64_16
{ {
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static ushort FPConvert(double value) public static ushort FPConvert(double value)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -2508,21 +2320,13 @@ namespace ARMeilleure.Instructions
static class SoftFloat64 static class SoftFloat64
{ {
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPAdd(double value1, double value2) public static double FPAdd(double value1, double value2)
{ {
return FPAddFpscrImpl(value1, value2, false); return FPAddFpscrImpl(value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPAddFpscr(double value1, double value2, byte standardFpscr) public static double FPAddFpscr(double value1, double value2, byte standardFpscr)
{ {
return FPAddFpscrImpl(value1, value2, standardFpscr == 1); return FPAddFpscrImpl(value1, value2, standardFpscr == 1);
@@ -2579,11 +2383,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static int FPCompare(double value1, double value2, byte signalNaNs) public static int FPCompare(double value1, double value2, byte signalNaNs)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -2622,21 +2422,13 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPCompareEQ(double value1, double value2) public static double FPCompareEQ(double value1, double value2)
{ {
return FPCompareEQFpscrImpl(value1, value2, false); return FPCompareEQFpscrImpl(value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPCompareEQFpscr(double value1, double value2, byte standardFpscr) public static double FPCompareEQFpscr(double value1, double value2, byte standardFpscr)
{ {
return FPCompareEQFpscrImpl(value1, value2, standardFpscr == 1); return FPCompareEQFpscrImpl(value1, value2, standardFpscr == 1);
@@ -2669,21 +2461,13 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPCompareGE(double value1, double value2) public static double FPCompareGE(double value1, double value2)
{ {
return FPCompareGEFpscrImpl(value1, value2, false); return FPCompareGEFpscrImpl(value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPCompareGEFpscr(double value1, double value2, byte standardFpscr) public static double FPCompareGEFpscr(double value1, double value2, byte standardFpscr)
{ {
return FPCompareGEFpscrImpl(value1, value2, standardFpscr == 1); return FPCompareGEFpscrImpl(value1, value2, standardFpscr == 1);
@@ -2713,21 +2497,13 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPCompareGT(double value1, double value2) public static double FPCompareGT(double value1, double value2)
{ {
return FPCompareGTFpscrImpl(value1, value2, false); return FPCompareGTFpscrImpl(value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPCompareGTFpscr(double value1, double value2, byte standardFpscr) public static double FPCompareGTFpscr(double value1, double value2, byte standardFpscr)
{ {
return FPCompareGTFpscrImpl(value1, value2, standardFpscr == 1); return FPCompareGTFpscrImpl(value1, value2, standardFpscr == 1);
@@ -2757,51 +2533,31 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPCompareLE(double value1, double value2) public static double FPCompareLE(double value1, double value2)
{ {
return FPCompareGEFpscrImpl(value2, value1, false); return FPCompareGEFpscrImpl(value2, value1, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPCompareLT(double value1, double value2) public static double FPCompareLT(double value1, double value2)
{ {
return FPCompareGTFpscrImpl(value2, value1, false); return FPCompareGTFpscrImpl(value2, value1, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPCompareLEFpscr(double value1, double value2, byte standardFpscr) public static double FPCompareLEFpscr(double value1, double value2, byte standardFpscr)
{ {
return FPCompareGEFpscrImpl(value2, value1, standardFpscr == 1); return FPCompareGEFpscrImpl(value2, value1, standardFpscr == 1);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPCompareLTFpscr(double value1, double value2, byte standardFpscr) public static double FPCompareLTFpscr(double value1, double value2, byte standardFpscr)
{ {
return FPCompareGTFpscrImpl(value2, value1, standardFpscr == 1); return FPCompareGTFpscrImpl(value2, value1, standardFpscr == 1);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPDiv(double value1, double value2) public static double FPDiv(double value1, double value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -2854,21 +2610,13 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPMax(double value1, double value2) public static double FPMax(double value1, double value2)
{ {
return FPMaxFpscrImpl(value1, value2, false); return FPMaxFpscrImpl(value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPMaxFpscr(double value1, double value2, byte standardFpscr) public static double FPMaxFpscr(double value1, double value2, byte standardFpscr)
{ {
return FPMaxFpscrImpl(value1, value2, standardFpscr == 1); return FPMaxFpscrImpl(value1, value2, standardFpscr == 1);
@@ -2935,21 +2683,13 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPMaxNum(double value1, double value2) public static double FPMaxNum(double value1, double value2)
{ {
return FPMaxNumFpscrImpl(value1, value2, false); return FPMaxNumFpscrImpl(value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPMaxNumFpscr(double value1, double value2, byte standardFpscr) public static double FPMaxNumFpscr(double value1, double value2, byte standardFpscr)
{ {
return FPMaxNumFpscrImpl(value1, value2, standardFpscr == 1); return FPMaxNumFpscrImpl(value1, value2, standardFpscr == 1);
@@ -2975,21 +2715,13 @@ namespace ARMeilleure.Instructions
return FPMaxFpscrImpl(value1, value2, standardFpscr); return FPMaxFpscrImpl(value1, value2, standardFpscr);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPMin(double value1, double value2) public static double FPMin(double value1, double value2)
{ {
return FPMinFpscrImpl(value1, value2, false); return FPMinFpscrImpl(value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPMinFpscr(double value1, double value2, byte standardFpscr) public static double FPMinFpscr(double value1, double value2, byte standardFpscr)
{ {
return FPMinFpscrImpl(value1, value2, standardFpscr == 1); return FPMinFpscrImpl(value1, value2, standardFpscr == 1);
@@ -3056,21 +2788,13 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPMinNum(double value1, double value2) public static double FPMinNum(double value1, double value2)
{ {
return FPMinNumFpscrImpl(value1, value2, false); return FPMinNumFpscrImpl(value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPMinNumFpscr(double value1, double value2, byte standardFpscr) public static double FPMinNumFpscr(double value1, double value2, byte standardFpscr)
{ {
return FPMinNumFpscrImpl(value1, value2, standardFpscr == 1); return FPMinNumFpscrImpl(value1, value2, standardFpscr == 1);
@@ -3096,21 +2820,13 @@ namespace ARMeilleure.Instructions
return FPMinFpscrImpl(value1, value2, standardFpscr); return FPMinFpscrImpl(value1, value2, standardFpscr);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPMul(double value1, double value2) public static double FPMul(double value1, double value2)
{ {
return FPMulFpscrImpl(value1, value2, false); return FPMulFpscrImpl(value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPMulFpscr(double value1, double value2, byte standardFpscr) public static double FPMulFpscr(double value1, double value2, byte standardFpscr)
{ {
return FPMulFpscrImpl(value1, value2, standardFpscr == 1); return FPMulFpscrImpl(value1, value2, standardFpscr == 1);
@@ -3163,21 +2879,13 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPMulAdd(double valueA, double value1, double value2) public static double FPMulAdd(double valueA, double value1, double value2)
{ {
return FPMulAddFpscrImpl(valueA, value1, value2, false); return FPMulAddFpscrImpl(valueA, value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPMulAddFpscr(double valueA, double value1, double value2, byte standardFpscr) public static double FPMulAddFpscr(double valueA, double value1, double value2, byte standardFpscr)
{ {
return FPMulAddFpscrImpl(valueA, value1, value2, standardFpscr == 1); return FPMulAddFpscrImpl(valueA, value1, value2, standardFpscr == 1);
@@ -3249,11 +2957,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPMulSub(double valueA, double value1, double value2) public static double FPMulSub(double valueA, double value1, double value2)
{ {
value1 = value1.FPNeg(); value1 = value1.FPNeg();
@@ -3261,11 +2965,7 @@ namespace ARMeilleure.Instructions
return FPMulAddFpscrImpl(valueA, value1, value2, false); return FPMulAddFpscrImpl(valueA, value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPMulSubFpscr(double valueA, double value1, double value2, byte standardFpscr) public static double FPMulSubFpscr(double valueA, double value1, double value2, byte standardFpscr)
{ {
value1 = value1.FPNeg(); value1 = value1.FPNeg();
@@ -3273,11 +2973,7 @@ namespace ARMeilleure.Instructions
return FPMulAddFpscrImpl(valueA, value1, value2, standardFpscr == 1); return FPMulAddFpscrImpl(valueA, value1, value2, standardFpscr == 1);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPMulX(double value1, double value2) public static double FPMulX(double value1, double value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -3323,11 +3019,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPNegMulAdd(double valueA, double value1, double value2) public static double FPNegMulAdd(double valueA, double value1, double value2)
{ {
valueA = valueA.FPNeg(); valueA = valueA.FPNeg();
@@ -3336,11 +3028,7 @@ namespace ARMeilleure.Instructions
return FPMulAddFpscrImpl(valueA, value1, value2, false); return FPMulAddFpscrImpl(valueA, value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPNegMulSub(double valueA, double value1, double value2) public static double FPNegMulSub(double valueA, double value1, double value2)
{ {
valueA = valueA.FPNeg(); valueA = valueA.FPNeg();
@@ -3348,21 +3036,13 @@ namespace ARMeilleure.Instructions
return FPMulAddFpscrImpl(valueA, value1, value2, false); return FPMulAddFpscrImpl(valueA, value1, value2, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPRecipEstimate(double value) public static double FPRecipEstimate(double value)
{ {
return FPRecipEstimateFpscrImpl(value, false); return FPRecipEstimateFpscrImpl(value, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPRecipEstimateFpscr(double value, byte standardFpscr) public static double FPRecipEstimateFpscr(double value, byte standardFpscr)
{ {
return FPRecipEstimateFpscrImpl(value, standardFpscr == 1); return FPRecipEstimateFpscrImpl(value, standardFpscr == 1);
@@ -3393,7 +3073,7 @@ namespace ARMeilleure.Instructions
} }
else if (Math.Abs(value) < Math.Pow(2d, -1024)) else if (Math.Abs(value) < Math.Pow(2d, -1024))
{ {
bool overflowToInf = fpcr.GetRoundingMode() switch var overflowToInf = fpcr.GetRoundingMode() switch
{ {
FPRoundingMode.ToNearest => true, FPRoundingMode.ToNearest => true,
FPRoundingMode.TowardsPlusInfinity => !sign, FPRoundingMode.TowardsPlusInfinity => !sign,
@@ -3455,11 +3135,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPRecipStep(double value1, double value2) public static double FPRecipStep(double value1, double value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -3494,11 +3170,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPRecipStepFused(double value1, double value2) public static double FPRecipStepFused(double value1, double value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -3542,11 +3214,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPRecpX(double value) public static double FPRecpX(double value)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -3572,21 +3240,13 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPRSqrtEstimate(double value) public static double FPRSqrtEstimate(double value)
{ {
return FPRSqrtEstimateFpscrImpl(value, false); return FPRSqrtEstimateFpscrImpl(value, false);
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPRSqrtEstimateFpscr(double value, byte standardFpscr) public static double FPRSqrtEstimateFpscr(double value, byte standardFpscr)
{ {
return FPRSqrtEstimateFpscrImpl(value, standardFpscr == 1); return FPRSqrtEstimateFpscrImpl(value, standardFpscr == 1);
@@ -3706,11 +3366,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPRSqrtStep(double value1, double value2) public static double FPRSqrtStep(double value1, double value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -3745,11 +3401,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPRSqrtStepFused(double value1, double value2) public static double FPRSqrtStepFused(double value1, double value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -3793,11 +3445,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPSqrt(double value) public static double FPSqrt(double value)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -3840,11 +3488,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
#if ANDROID
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
#endif
public static double FPSub(double value1, double value2) public static double FPSub(double value1, double value2)
{ {
return FPSubFpscr(value1, value2, false); return FPSubFpscr(value1, value2, false);
@@ -32,7 +32,7 @@ namespace ARMeilleure.IntermediateRepresentation
/// <exception cref="ArgumentException"><typeparamref name="T"/> is not pointer sized.</exception> /// <exception cref="ArgumentException"><typeparamref name="T"/> is not pointer sized.</exception>
public IntrusiveList() public IntrusiveList()
{ {
if (Unsafe.SizeOf<T>() != nint.Size) if (Unsafe.SizeOf<T>() != IntPtr.Size)
{ {
throw new ArgumentException("T must be a reference type or a pointer sized struct."); throw new ArgumentException("T must be a reference type or a pointer sized struct.");
} }
@@ -1,3 +1,4 @@
using System;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@@ -23,7 +24,7 @@ namespace ARMeilleure.IntermediateRepresentation
{ {
Debug.Assert(operand.Kind == OperandKind.Memory); Debug.Assert(operand.Kind == OperandKind.Memory);
_data = (Data*)Unsafe.As<Operand, nint>(ref operand); _data = (Data*)Unsafe.As<Operand, IntPtr>(ref operand);
} }
public Operand BaseAddress public Operand BaseAddress
@@ -304,7 +304,7 @@ namespace ARMeilleure.IntermediateRepresentation
ushort newCount = checked((ushort)(count + 1)); ushort newCount = checked((ushort)(count + 1));
ushort newCapacity = (ushort)Math.Min(capacity * 2, ushort.MaxValue); ushort newCapacity = (ushort)Math.Min(capacity * 2, ushort.MaxValue);
Span<T> oldSpan = new(data, count); var oldSpan = new Span<T>(data, count);
capacity = newCapacity; capacity = newCapacity;
data = Allocators.References.Allocate<T>(capacity); data = Allocators.References.Allocate<T>(capacity);
@@ -338,7 +338,7 @@ namespace ARMeilleure.IntermediateRepresentation
throw new OverflowException(); throw new OverflowException();
} }
Span<T> oldSpan = new(data, (int)count); var oldSpan = new Span<T>(data, (int)count);
capacity = newCapacity; capacity = newCapacity;
data = Allocators.References.Allocate<T>(capacity); data = Allocators.References.Allocate<T>(capacity);
@@ -352,7 +352,7 @@ namespace ARMeilleure.IntermediateRepresentation
private static void Remove<T>(in T item, ref T* data, ref ushort count) where T : unmanaged private static void Remove<T>(in T item, ref T* data, ref ushort count) where T : unmanaged
{ {
Span<T> span = new(data, count); var span = new Span<T>(data, count);
for (int i = 0; i < span.Length; i++) for (int i = 0; i < span.Length; i++)
{ {
@@ -372,7 +372,7 @@ namespace ARMeilleure.IntermediateRepresentation
private static void Remove<T>(in T item, ref T* data, ref uint count) where T : unmanaged private static void Remove<T>(in T item, ref T* data, ref uint count) where T : unmanaged
{ {
Span<T> span = new(data, (int)count); var span = new Span<T>(data, (int)count);
for (int i = 0; i < span.Length; i++) for (int i = 0; i < span.Length; i++)
{ {
@@ -228,7 +228,7 @@ namespace ARMeilleure.IntermediateRepresentation
public readonly override int GetHashCode() public readonly override int GetHashCode()
{ {
return HashCode.Combine((nint)_data); return HashCode.Combine((IntPtr)_data);
} }
public static bool operator ==(Operation a, Operation b) public static bool operator ==(Operation a, Operation b)
+1 -1
View File
@@ -4,7 +4,7 @@ namespace ARMeilleure.Memory
{ {
public interface IJitMemoryBlock : IDisposable public interface IJitMemoryBlock : IDisposable
{ {
nint Pointer { get; } IntPtr Pointer { get; }
void Commit(ulong offset, ulong size); void Commit(ulong offset, ulong size);
+1 -1
View File
@@ -6,7 +6,7 @@ namespace ARMeilleure.Memory
{ {
int AddressSpaceBits { get; } int AddressSpaceBits { get; }
nint PageTablePointer { get; } IntPtr PageTablePointer { get; }
MemoryManagerType Type { get; } MemoryManagerType Type { get; }
+1 -1
View File
@@ -9,7 +9,7 @@ namespace ARMeilleure.Memory
public IJitMemoryBlock Block { get; } public IJitMemoryBlock Block { get; }
public IJitMemoryAllocator Allocator { get; } public IJitMemoryAllocator Allocator { get; }
public nint Pointer => Block.Pointer; public IntPtr Pointer => Block.Pointer;
private readonly ulong _maxSize; private readonly ulong _maxSize;
private readonly ulong _sizeGranularity; private readonly ulong _sizeGranularity;
+2 -1
View File
@@ -1,3 +1,4 @@
using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Versioning; using System.Runtime.Versioning;
@@ -7,6 +8,6 @@ namespace ARMeilleure.Native
static partial class JitSupportDarwin static partial class JitSupportDarwin
{ {
[LibraryImport("libarmeilleure-jitsupport", EntryPoint = "armeilleure_jit_memcpy")] [LibraryImport("libarmeilleure-jitsupport", EntryPoint = "armeilleure_jit_memcpy")]
public static partial void Copy(nint dst, nint src, ulong n); public static partial void Copy(IntPtr dst, IntPtr src, ulong n);
} }
} }
+1 -3
View File
@@ -8,13 +8,11 @@ namespace ARMeilleure
// low-core count PPTC // low-core count PPTC
public static bool EcoFriendly { get; set; } = false; public static bool EcoFriendly { get; set; } = false;
// Jit cache eviction
public static bool CacheEviction { get; set; } = false;
public static bool FastFP { get; set; } = true; public static bool FastFP { get; set; } = true;
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 EnableDeepCallRecursionProtection { get; set; } = true; public static bool EnableDeepCallRecursionProtection { get; set; } = true;
public static bool UseAdvSimdIfAvailable { get; set; } = true; public static bool UseAdvSimdIfAvailable { get; set; } = true;
@@ -8,7 +8,7 @@ namespace ARMeilleure.Signal
{ {
public static class NativeSignalHandlerGenerator public static class NativeSignalHandlerGenerator
{ {
public const int MaxTrackedRanges = 8; public const int MaxTrackedRanges = 16;
private const int StructAddressOffset = 0; private const int StructAddressOffset = 0;
private const int StructWriteOffset = 4; private const int StructWriteOffset = 4;
@@ -21,7 +21,7 @@ namespace ARMeilleure.Signal
private const uint EXCEPTION_ACCESS_VIOLATION = 0xc0000005; private const uint EXCEPTION_ACCESS_VIOLATION = 0xc0000005;
private static Operand EmitGenericRegionCheck(EmitterContext context, nint signalStructPtr, Operand faultAddress, Operand isWrite, int rangeStructSize) private static Operand EmitGenericRegionCheck(EmitterContext context, IntPtr signalStructPtr, Operand faultAddress, Operand isWrite, int rangeStructSize)
{ {
Operand inRegionLocal = context.AllocateLocal(OperandType.I32); Operand inRegionLocal = context.AllocateLocal(OperandType.I32);
context.Copy(inRegionLocal, Const(0)); context.Copy(inRegionLocal, Const(0));
@@ -155,7 +155,7 @@ namespace ARMeilleure.Signal
throw new PlatformNotSupportedException(); throw new PlatformNotSupportedException();
} }
public static byte[] GenerateUnixSignalHandler(nint signalStructPtr, int rangeStructSize) public static byte[] GenerateUnixSignalHandler(IntPtr signalStructPtr, int rangeStructSize)
{ {
EmitterContext context = new(); EmitterContext context = new();
@@ -203,7 +203,7 @@ namespace ARMeilleure.Signal
return Compiler.Compile(cfg, argTypes, OperandType.None, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Code; return Compiler.Compile(cfg, argTypes, OperandType.None, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Code;
} }
public static byte[] GenerateWindowsSignalHandler(nint signalStructPtr, int rangeStructSize) public static byte[] GenerateWindowsSignalHandler(IntPtr signalStructPtr, int rangeStructSize)
{ {
EmitterContext context = new(); EmitterContext context = new();
+5 -4
View File
@@ -1,5 +1,6 @@
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation; using ARMeilleure.Translation;
using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
@@ -15,13 +16,13 @@ namespace ARMeilleure.Signal
{ {
public delegate bool DebugPartialUnmap(); public delegate bool DebugPartialUnmap();
public delegate int DebugThreadLocalMapGetOrReserve(int threadId, int initialState); public delegate int DebugThreadLocalMapGetOrReserve(int threadId, int initialState);
public delegate void DebugNativeWriteLoop(nint nativeWriteLoopPtr, nint writePtr); public delegate void DebugNativeWriteLoop(IntPtr nativeWriteLoopPtr, IntPtr writePtr);
public static DebugPartialUnmap GenerateDebugPartialUnmap() public static DebugPartialUnmap GenerateDebugPartialUnmap()
{ {
EmitterContext context = new(); EmitterContext context = new();
Operand result = WindowsPartialUnmapHandler.EmitRetryFromAccessViolation(context); var result = WindowsPartialUnmapHandler.EmitRetryFromAccessViolation(context);
context.Return(result); context.Return(result);
@@ -34,11 +35,11 @@ namespace ARMeilleure.Signal
return Compiler.Compile(cfg, argTypes, OperandType.I32, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<DebugPartialUnmap>(); return Compiler.Compile(cfg, argTypes, OperandType.I32, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<DebugPartialUnmap>();
} }
public static DebugThreadLocalMapGetOrReserve GenerateDebugThreadLocalMapGetOrReserve(nint structPtr) public static DebugThreadLocalMapGetOrReserve GenerateDebugThreadLocalMapGetOrReserve(IntPtr structPtr)
{ {
EmitterContext context = new(); EmitterContext context = new();
Operand result = WindowsPartialUnmapHandler.EmitThreadLocalMapIntGetOrReserve(context, structPtr, context.LoadArgument(OperandType.I32, 0), context.LoadArgument(OperandType.I32, 1)); var result = WindowsPartialUnmapHandler.EmitThreadLocalMapIntGetOrReserve(context, structPtr, context.LoadArgument(OperandType.I32, 0), context.LoadArgument(OperandType.I32, 1));
context.Return(result); context.Return(result);
@@ -1,6 +1,7 @@
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation; using ARMeilleure.Translation;
using Ryujinx.Common.Memory.PartialUnmaps; using Ryujinx.Common.Memory.PartialUnmaps;
using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
@@ -12,18 +13,18 @@ namespace ARMeilleure.Signal
internal static partial class WindowsPartialUnmapHandler internal static partial class WindowsPartialUnmapHandler
{ {
[LibraryImport("kernel32.dll", SetLastError = true, EntryPoint = "LoadLibraryA")] [LibraryImport("kernel32.dll", SetLastError = true, EntryPoint = "LoadLibraryA")]
private static partial nint LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName); private static partial IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName);
[LibraryImport("kernel32.dll", SetLastError = true)] [LibraryImport("kernel32.dll", SetLastError = true)]
private static partial nint GetProcAddress(nint hModule, [MarshalAs(UnmanagedType.LPStr)] string procName); private static partial IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string procName);
private static nint _getCurrentThreadIdPtr; private static IntPtr _getCurrentThreadIdPtr;
public static nint GetCurrentThreadIdFunc() public static IntPtr GetCurrentThreadIdFunc()
{ {
if (_getCurrentThreadIdPtr == nint.Zero) if (_getCurrentThreadIdPtr == IntPtr.Zero)
{ {
nint handle = LoadLibrary("kernel32.dll"); IntPtr handle = LoadLibrary("kernel32.dll");
_getCurrentThreadIdPtr = GetProcAddress(handle, "GetCurrentThreadId"); _getCurrentThreadIdPtr = GetProcAddress(handle, "GetCurrentThreadId");
} }
@@ -33,13 +34,13 @@ namespace ARMeilleure.Signal
public static Operand EmitRetryFromAccessViolation(EmitterContext context) public static Operand EmitRetryFromAccessViolation(EmitterContext context)
{ {
nint partialRemapStatePtr = PartialUnmapState.GlobalState; IntPtr partialRemapStatePtr = PartialUnmapState.GlobalState;
nint localCountsPtr = nint.Add(partialRemapStatePtr, PartialUnmapState.LocalCountsOffset); IntPtr localCountsPtr = IntPtr.Add(partialRemapStatePtr, PartialUnmapState.LocalCountsOffset);
// Get the lock first. // Get the lock first.
EmitNativeReaderLockAcquire(context, nint.Add(partialRemapStatePtr, PartialUnmapState.PartialUnmapLockOffset)); EmitNativeReaderLockAcquire(context, IntPtr.Add(partialRemapStatePtr, PartialUnmapState.PartialUnmapLockOffset));
nint getCurrentThreadId = GetCurrentThreadIdFunc(); IntPtr getCurrentThreadId = GetCurrentThreadIdFunc();
Operand threadId = context.Call(Const((ulong)getCurrentThreadId), OperandType.I32); Operand threadId = context.Call(Const((ulong)getCurrentThreadId), OperandType.I32);
Operand threadIndex = EmitThreadLocalMapIntGetOrReserve(context, localCountsPtr, threadId, Const(0)); Operand threadIndex = EmitThreadLocalMapIntGetOrReserve(context, localCountsPtr, threadId, Const(0));
@@ -57,7 +58,7 @@ namespace ARMeilleure.Signal
Operand threadLocalPartialUnmapsPtr = EmitThreadLocalMapIntGetValuePtr(context, localCountsPtr, threadIndex); Operand threadLocalPartialUnmapsPtr = EmitThreadLocalMapIntGetValuePtr(context, localCountsPtr, threadIndex);
Operand threadLocalPartialUnmaps = context.Load(OperandType.I32, threadLocalPartialUnmapsPtr); Operand threadLocalPartialUnmaps = context.Load(OperandType.I32, threadLocalPartialUnmapsPtr);
Operand partialUnmapsCount = context.Load(OperandType.I32, Const((ulong)nint.Add(partialRemapStatePtr, PartialUnmapState.PartialUnmapsCountOffset))); Operand partialUnmapsCount = context.Load(OperandType.I32, Const((ulong)IntPtr.Add(partialRemapStatePtr, PartialUnmapState.PartialUnmapsCountOffset)));
context.Copy(retry, context.ICompareNotEqual(threadLocalPartialUnmaps, partialUnmapsCount)); context.Copy(retry, context.ICompareNotEqual(threadLocalPartialUnmaps, partialUnmapsCount));
@@ -78,14 +79,14 @@ namespace ARMeilleure.Signal
context.MarkLabel(endLabel); context.MarkLabel(endLabel);
// Finally, release the lock and return the retry value. // Finally, release the lock and return the retry value.
EmitNativeReaderLockRelease(context, nint.Add(partialRemapStatePtr, PartialUnmapState.PartialUnmapLockOffset)); EmitNativeReaderLockRelease(context, IntPtr.Add(partialRemapStatePtr, PartialUnmapState.PartialUnmapLockOffset));
return retry; return retry;
} }
public static Operand EmitThreadLocalMapIntGetOrReserve(EmitterContext context, nint threadLocalMapPtr, Operand threadId, Operand initialState) public static Operand EmitThreadLocalMapIntGetOrReserve(EmitterContext context, IntPtr threadLocalMapPtr, Operand threadId, Operand initialState)
{ {
Operand idsPtr = Const((ulong)nint.Add(threadLocalMapPtr, ThreadLocalMap<int>.ThreadIdsOffset)); Operand idsPtr = Const((ulong)IntPtr.Add(threadLocalMapPtr, ThreadLocalMap<int>.ThreadIdsOffset));
Operand i = context.AllocateLocal(OperandType.I32); Operand i = context.AllocateLocal(OperandType.I32);
@@ -129,7 +130,7 @@ namespace ARMeilleure.Signal
// If it was 0, then we need to initialize the struct entry and return i. // If it was 0, then we need to initialize the struct entry and return i.
context.BranchIfFalse(idNot0Label, context.ICompareEqual(existingId2, Const(0))); context.BranchIfFalse(idNot0Label, context.ICompareEqual(existingId2, Const(0)));
Operand structsPtr = Const((ulong)nint.Add(threadLocalMapPtr, ThreadLocalMap<int>.StructsOffset)); Operand structsPtr = Const((ulong)IntPtr.Add(threadLocalMapPtr, ThreadLocalMap<int>.StructsOffset));
Operand structPtr = context.Add(structsPtr, context.SignExtend32(OperandType.I64, offset2)); Operand structPtr = context.Add(structsPtr, context.SignExtend32(OperandType.I64, offset2));
context.Store(structPtr, initialState); context.Store(structPtr, initialState);
@@ -148,10 +149,10 @@ namespace ARMeilleure.Signal
return context.Copy(i); return context.Copy(i);
} }
private static Operand EmitThreadLocalMapIntGetValuePtr(EmitterContext context, nint threadLocalMapPtr, Operand index) private static Operand EmitThreadLocalMapIntGetValuePtr(EmitterContext context, IntPtr threadLocalMapPtr, Operand index)
{ {
Operand offset = context.Multiply(index, Const(sizeof(int))); Operand offset = context.Multiply(index, Const(sizeof(int)));
Operand structsPtr = Const((ulong)nint.Add(threadLocalMapPtr, ThreadLocalMap<int>.StructsOffset)); Operand structsPtr = Const((ulong)IntPtr.Add(threadLocalMapPtr, ThreadLocalMap<int>.StructsOffset));
return context.Add(structsPtr, context.SignExtend32(OperandType.I64, offset)); return context.Add(structsPtr, context.SignExtend32(OperandType.I64, offset));
} }
@@ -169,9 +170,9 @@ namespace ARMeilleure.Signal
context.BranchIfFalse(loop, context.ICompareEqual(initial, replaced)); context.BranchIfFalse(loop, context.ICompareEqual(initial, replaced));
} }
private static void EmitNativeReaderLockAcquire(EmitterContext context, nint nativeReaderLockPtr) private static void EmitNativeReaderLockAcquire(EmitterContext context, IntPtr nativeReaderLockPtr)
{ {
Operand writeLockPtr = Const((ulong)nint.Add(nativeReaderLockPtr, NativeReaderWriterLock.WriteLockOffset)); Operand writeLockPtr = Const((ulong)IntPtr.Add(nativeReaderLockPtr, NativeReaderWriterLock.WriteLockOffset));
// Spin until we can acquire the write lock. // Spin until we can acquire the write lock.
Operand spinLabel = Label(); Operand spinLabel = Label();
@@ -181,16 +182,16 @@ namespace ARMeilleure.Signal
context.BranchIfTrue(spinLabel, context.CompareAndSwap(writeLockPtr, Const(0), Const(1))); context.BranchIfTrue(spinLabel, context.CompareAndSwap(writeLockPtr, Const(0), Const(1)));
// Increment reader count. // Increment reader count.
EmitAtomicAddI32(context, Const((ulong)nint.Add(nativeReaderLockPtr, NativeReaderWriterLock.ReaderCountOffset)), Const(1)); EmitAtomicAddI32(context, Const((ulong)IntPtr.Add(nativeReaderLockPtr, NativeReaderWriterLock.ReaderCountOffset)), Const(1));
// Release write lock. // Release write lock.
context.CompareAndSwap(writeLockPtr, Const(1), Const(0)); context.CompareAndSwap(writeLockPtr, Const(1), Const(0));
} }
private static void EmitNativeReaderLockRelease(EmitterContext context, nint nativeReaderLockPtr) private static void EmitNativeReaderLockRelease(EmitterContext context, IntPtr nativeReaderLockPtr)
{ {
// Decrement reader count. // Decrement reader count.
EmitAtomicAddI32(context, Const((ulong)nint.Add(nativeReaderLockPtr, NativeReaderWriterLock.ReaderCountOffset)), Const(-1)); EmitAtomicAddI32(context, Const((ulong)IntPtr.Add(nativeReaderLockPtr, NativeReaderWriterLock.ReaderCountOffset)), Const(-1));
} }
} }
} }
+36 -5
View File
@@ -1,4 +1,6 @@
using ARMeilleure.Memory; using ARMeilleure.Memory;
using System;
using System.Threading;
namespace ARMeilleure.State namespace ARMeilleure.State
{ {
@@ -8,9 +10,9 @@ namespace ARMeilleure.State
private readonly NativeContext _nativeContext; private readonly NativeContext _nativeContext;
internal nint NativeContextPtr => _nativeContext.BasePtr; internal IntPtr NativeContextPtr => _nativeContext.BasePtr;
private bool _interrupted; internal bool Interrupted { get; private set; }
private readonly ICounter _counter; private readonly ICounter _counter;
@@ -67,6 +69,8 @@ namespace ARMeilleure.State
public bool IsAarch32 { get; set; } public bool IsAarch32 { get; set; }
public ulong ThreadUid { get; set; }
internal ExecutionMode ExecutionMode internal ExecutionMode ExecutionMode
{ {
get get
@@ -92,14 +96,19 @@ namespace ARMeilleure.State
private readonly ExceptionCallbackNoArgs _interruptCallback; private readonly ExceptionCallbackNoArgs _interruptCallback;
private readonly ExceptionCallback _breakCallback; private readonly ExceptionCallback _breakCallback;
private readonly ExceptionCallbackNoArgs _stepCallback;
private readonly ExceptionCallback _supervisorCallback; private readonly ExceptionCallback _supervisorCallback;
private readonly ExceptionCallback _undefinedCallback; private readonly ExceptionCallback _undefinedCallback;
internal int ShouldStep;
public ulong DebugPc { get; set; }
public ExecutionContext( public ExecutionContext(
IJitMemoryAllocator allocator, IJitMemoryAllocator allocator,
ICounter counter, ICounter counter,
ExceptionCallbackNoArgs interruptCallback = null, ExceptionCallbackNoArgs interruptCallback = null,
ExceptionCallback breakCallback = null, ExceptionCallback breakCallback = null,
ExceptionCallbackNoArgs stepCallback = null,
ExceptionCallback supervisorCallback = null, ExceptionCallback supervisorCallback = null,
ExceptionCallback undefinedCallback = null) ExceptionCallback undefinedCallback = null)
{ {
@@ -107,6 +116,7 @@ namespace ARMeilleure.State
_counter = counter; _counter = counter;
_interruptCallback = interruptCallback; _interruptCallback = interruptCallback;
_breakCallback = breakCallback; _breakCallback = breakCallback;
_stepCallback = stepCallback;
_supervisorCallback = supervisorCallback; _supervisorCallback = supervisorCallback;
_undefinedCallback = undefinedCallback; _undefinedCallback = undefinedCallback;
@@ -134,9 +144,9 @@ namespace ARMeilleure.State
internal void CheckInterrupt() internal void CheckInterrupt()
{ {
if (_interrupted) if (Interrupted)
{ {
_interrupted = false; Interrupted = false;
_interruptCallback?.Invoke(this); _interruptCallback?.Invoke(this);
} }
@@ -146,16 +156,37 @@ namespace ARMeilleure.State
public void RequestInterrupt() public void RequestInterrupt()
{ {
_interrupted = true; Interrupted = true;
}
public void StepHandler()
{
_stepCallback?.Invoke(this);
}
public void RequestDebugStep()
{
Interlocked.Exchange(ref ShouldStep, 1);
RequestInterrupt();
} }
internal void OnBreak(ulong address, int imm) internal void OnBreak(ulong address, int imm)
{ {
if (Optimizations.EnableDebugging)
{
DebugPc = Pc;
}
_breakCallback?.Invoke(this, address, imm); _breakCallback?.Invoke(this, address, imm);
} }
internal void OnSupervisorCall(ulong address, int imm) internal void OnSupervisorCall(ulong address, int imm)
{ {
if (Optimizations.EnableDebugging)
{
DebugPc = Pc;
}
_supervisorCallback?.Invoke(this, address, imm); _supervisorCallback?.Invoke(this, address, imm);
} }
+17 -1
View File
@@ -23,13 +23,19 @@ namespace ARMeilleure.State
public int Running; public int Running;
public int CallDepth; public int CallDepth;
public long Tpidr2El0; public long Tpidr2El0;
/// <summary>
/// Precise PC value used for debugging.
/// This will only be set when Optimizations.EnableDebugging is true.
/// </summary>
public ulong DebugPrecisePc;
} }
private static NativeCtxStorage _dummyStorage = new(); private static NativeCtxStorage _dummyStorage = new();
private readonly IJitMemoryBlock _block; private readonly IJitMemoryBlock _block;
public nint BasePtr => _block.Pointer; public IntPtr BasePtr => _block.Pointer;
public NativeContext(IJitMemoryAllocator allocator) public NativeContext(IJitMemoryAllocator allocator)
{ {
@@ -40,6 +46,11 @@ namespace ARMeilleure.State
public ulong GetPc() public ulong GetPc()
{ {
if (Optimizations.EnableDebugging)
{
return GetStorage().DebugPrecisePc;
}
// TODO: More precise tracking of PC value. // TODO: More precise tracking of PC value.
return GetStorage().DispatchAddress; return GetStorage().DispatchAddress;
} }
@@ -269,6 +280,11 @@ namespace ARMeilleure.State
return StorageOffset(ref _dummyStorage, ref _dummyStorage.Running); return StorageOffset(ref _dummyStorage, ref _dummyStorage.Running);
} }
public static int GetDebugPrecisePcOffset()
{
return StorageOffset(ref _dummyStorage, ref _dummyStorage.DebugPrecisePc);
}
public static int GetCallDepthOffset() public static int GetCallDepthOffset()
{ {
return StorageOffset(ref _dummyStorage, ref _dummyStorage.CallDepth); return StorageOffset(ref _dummyStorage, ref _dummyStorage.CallDepth);
@@ -6,6 +6,7 @@ using ARMeilleure.Instructions;
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Memory; using ARMeilleure.Memory;
using ARMeilleure.State; using ARMeilleure.State;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
@@ -52,6 +53,7 @@ namespace ARMeilleure.Translation
public bool HighCq { get; } public bool HighCq { get; }
public bool HasPtc { get; } public bool HasPtc { get; }
public Aarch32Mode Mode { get; } public Aarch32Mode Mode { get; }
public bool IsSingleStep { get; }
private int _ifThenBlockStateIndex = 0; private int _ifThenBlockStateIndex = 0;
private Condition[] _ifThenBlockState = []; private Condition[] _ifThenBlockState = [];
@@ -66,7 +68,8 @@ namespace ARMeilleure.Translation
ulong entryAddress, ulong entryAddress,
bool highCq, bool highCq,
bool hasPtc, bool hasPtc,
Aarch32Mode mode) Aarch32Mode mode,
bool isSingleStep)
{ {
Memory = memory; Memory = memory;
CountTable = countTable; CountTable = countTable;
@@ -76,6 +79,7 @@ namespace ARMeilleure.Translation
HighCq = highCq; HighCq = highCq;
HasPtc = hasPtc; HasPtc = hasPtc;
Mode = mode; Mode = mode;
IsSingleStep = isSingleStep;
_labels = new Dictionary<ulong, Operand>(); _labels = new Dictionary<ulong, Operand>();
} }
@@ -91,7 +95,7 @@ namespace ARMeilleure.Translation
else else
{ {
int index = Delegates.GetDelegateIndex(info); int index = Delegates.GetDelegateIndex(info);
nint funcPtr = Delegates.GetDelegateFuncPtrByIndex(index); IntPtr funcPtr = Delegates.GetDelegateFuncPtrByIndex(index);
OperandType returnType = GetOperandType(info.ReturnType); OperandType returnType = GetOperandType(info.ReturnType);
+82 -195
View File
@@ -2,12 +2,12 @@ using ARMeilleure.CodeGen;
using ARMeilleure.CodeGen.Unwinding; using ARMeilleure.CodeGen.Unwinding;
using ARMeilleure.Memory; using ARMeilleure.Memory;
using ARMeilleure.Native; using ARMeilleure.Native;
using Humanizer;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Memory; using Ryujinx.Memory;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Versioning; using System.Runtime.Versioning;
using System.Threading; using System.Threading;
@@ -19,123 +19,83 @@ namespace ARMeilleure.Translation.Cache
private static readonly int _pageSize = (int)MemoryBlock.GetPageSize(); private static readonly int _pageSize = (int)MemoryBlock.GetPageSize();
private static readonly int _pageMask = _pageSize - 1; private static readonly int _pageMask = _pageSize - 1;
private const int CodeAlignment = 4; private const int CodeAlignment = 4; // Bytes.
private const int FullCacheSize = 2047 * 1024 * 1024; private const int CacheSize = 256 * 1024 * 1024;
private const int ReducedCacheSize = FullCacheSize / 8;
private const float EvictionTargetPercentage = 0.20f;
private const int MaxEntriesToEvictAtOnce = 100;
// Simple logging configuration
private const int LogInterval = 5000; // Log every 5000 allocations
private static ReservedRegion _jitRegion;
private static JitCacheInvalidation _jitCacheInvalidator; private static JitCacheInvalidation _jitCacheInvalidator;
private static CacheMemoryAllocator _cacheAllocator; private static List<CacheMemoryAllocator> _cacheAllocators = [];
private static readonly List<CacheEntry> _cacheEntries = []; private static readonly List<CacheEntry> _cacheEntries = [];
private static readonly Dictionary<int, EntryUsageStats> _entryUsageStats = [];
private static readonly Lock _lock = new(); private static readonly Lock _lock = new();
private static bool _initialized; private static bool _initialized;
private static int _cacheSize;
// Basic statistics private static readonly List<ReservedRegion> _jitRegions = [];
private static int _totalAllocations = 0; private static int _activeRegionIndex = 0;
private static int _totalEvictions = 0;
private class EntryUsageStats
{
public long LastAccessTime { get; private set; }
public int UsageCount { get; private set; }
public EntryUsageStats()
{
LastAccessTime = DateTime.UtcNow.Ticks;
UsageCount = 1;
}
public void UpdateUsage()
{
LastAccessTime = DateTime.UtcNow.Ticks;
UsageCount++;
}
}
[SupportedOSPlatform("windows")] [SupportedOSPlatform("windows")]
[LibraryImport("kernel32.dll", SetLastError = true)] [LibraryImport("kernel32.dll", SetLastError = true)]
public static partial nint FlushInstructionCache(nint hProcess, nint lpAddress, nuint dwSize); public static partial IntPtr FlushInstructionCache(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize);
public static void Initialize(IJitMemoryAllocator allocator) public static void Initialize(IJitMemoryAllocator allocator)
{ {
if (_initialized)
{
return;
}
lock (_lock) lock (_lock)
{ {
if (_initialized) if (_initialized)
{ {
return; if (OperatingSystem.IsWindows())
{
JitUnwindWindows.RemoveFunctionTableHandler(
_jitRegions[0].Pointer);
} }
_cacheSize = Optimizations.CacheEviction ? ReducedCacheSize : FullCacheSize; for (int i = 0; i < _jitRegions.Count; i++)
_jitRegion = new ReservedRegion(allocator, (ulong)_cacheSize); {
_jitRegions[i].Dispose();
}
_jitRegions.Clear();
_cacheAllocators.Clear();
}
else
{
_initialized = true;
}
_activeRegionIndex = 0;
var firstRegion = new ReservedRegion(allocator, CacheSize);
_jitRegions.Add(firstRegion);
CacheMemoryAllocator firstCacheAllocator = new(CacheSize);
_cacheAllocators.Add(firstCacheAllocator);
if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS()) if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS())
{ {
_jitCacheInvalidator = new JitCacheInvalidation(allocator); _jitCacheInvalidator = new JitCacheInvalidation(allocator);
} }
_cacheAllocator = new CacheMemoryAllocator(_cacheSize);
if (OperatingSystem.IsWindows()) if (OperatingSystem.IsWindows())
{ {
JitUnwindWindows.InstallFunctionTableHandler(_jitRegion.Pointer, (uint)_cacheSize, _jitRegion.Pointer + Allocate(_pageSize)); JitUnwindWindows.InstallFunctionTableHandler(
firstRegion.Pointer, CacheSize, firstRegion.Pointer + Allocate(_pageSize)
);
} }
Logger.Info?.Print(LogClass.Cpu, $"JIT Cache initialized: Size={_cacheSize / (1024 * 1024)} MB, Eviction={Optimizations.CacheEviction}");
_initialized = true;
} }
} }
public static nint Map(CompiledFunction func) public static IntPtr Map(CompiledFunction func)
{ {
byte[] code = func.Code; byte[] code = func.Code;
lock (_lock) lock (_lock)
{ {
Debug.Assert(_initialized); Debug.Assert(_initialized);
_totalAllocations++;
int funcOffset; int funcOffset = Allocate(code.Length);
ReservedRegion targetRegion = _jitRegions[_activeRegionIndex];
if (Optimizations.CacheEviction) IntPtr funcPtr = targetRegion.Pointer + funcOffset;
{
int codeSize = AlignCodeSize(code.Length);
funcOffset = _cacheAllocator.Allocate(codeSize);
if (funcOffset < 0)
{
EvictEntries(codeSize);
funcOffset = _cacheAllocator.Allocate(codeSize);
if (funcOffset < 0)
{
throw new OutOfMemoryException("JIT Cache exhausted even after eviction.");
}
}
_jitRegion.ExpandIfNeeded((ulong)funcOffset + (ulong)codeSize);
}
else
{
funcOffset = Allocate(code.Length);
}
nint funcPtr = _jitRegion.Pointer + funcOffset;
if (OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64) if (OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
{ {
@@ -143,19 +103,19 @@ namespace ARMeilleure.Translation.Cache
{ {
fixed (byte* codePtr = code) fixed (byte* codePtr = code)
{ {
JitSupportDarwin.Copy(funcPtr, (nint)codePtr, (ulong)code.Length); JitSupportDarwin.Copy(funcPtr, (IntPtr)codePtr, (ulong)code.Length);
} }
} }
} }
else else
{ {
ReprotectAsWritable(funcOffset, code.Length); ReprotectAsWritable(targetRegion, funcOffset, code.Length);
Marshal.Copy(code, 0, funcPtr, code.Length); Marshal.Copy(code, 0, funcPtr, code.Length);
ReprotectAsExecutable(funcOffset, code.Length); ReprotectAsExecutable(targetRegion, funcOffset, code.Length);
if (OperatingSystem.IsWindows() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64) if (OperatingSystem.IsWindows() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
{ {
FlushInstructionCache(Process.GetCurrentProcess().Handle, funcPtr, (nuint)code.Length); FlushInstructionCache(Process.GetCurrentProcess().Handle, funcPtr, (UIntPtr)code.Length);
} }
else else
{ {
@@ -165,71 +125,84 @@ namespace ARMeilleure.Translation.Cache
Add(funcOffset, code.Length, func.UnwindInfo); Add(funcOffset, code.Length, func.UnwindInfo);
// Simple periodic logging
if (_totalAllocations % LogInterval == 0)
{
LogCacheStatus();
}
return funcPtr; return funcPtr;
} }
} }
public static void Unmap(nint pointer) public static void Unmap(IntPtr pointer)
{ {
lock (_lock) lock (_lock)
{ {
Debug.Assert(_initialized); Debug.Assert(_initialized);
int funcOffset = (int)(pointer.ToInt64() - _jitRegion.Pointer.ToInt64()); foreach (var region in _jitRegions)
{
if (pointer.ToInt64() < region.Pointer.ToInt64() ||
pointer.ToInt64() >= (region.Pointer + CacheSize).ToInt64())
{
continue;
}
int funcOffset = (int)(pointer.ToInt64() - region.Pointer.ToInt64());
if (TryFind(funcOffset, out CacheEntry entry, out int entryIndex) && entry.Offset == funcOffset) if (TryFind(funcOffset, out CacheEntry entry, out int entryIndex) && entry.Offset == funcOffset)
{ {
_cacheAllocator.Free(funcOffset, AlignCodeSize(entry.Size)); _cacheAllocators[_activeRegionIndex].Free(funcOffset, AlignCodeSize(entry.Size));
_cacheEntries.RemoveAt(entryIndex); _cacheEntries.RemoveAt(entryIndex);
if (Optimizations.CacheEviction)
{
_entryUsageStats.Remove(funcOffset);
} }
return;
} }
} }
} }
private static void ReprotectAsWritable(int offset, int size) private static void ReprotectAsWritable(ReservedRegion region, int offset, int size)
{ {
int endOffs = offset + size; int endOffs = offset + size;
int regionStart = offset & ~_pageMask; int regionStart = offset & ~_pageMask;
int regionEnd = (endOffs + _pageMask) & ~_pageMask; int regionEnd = (endOffs + _pageMask) & ~_pageMask;
_jitRegion.Block.MapAsRwx((ulong)regionStart, (ulong)(regionEnd - regionStart)); region.Block.MapAsRwx((ulong)regionStart, (ulong)(regionEnd - regionStart));
} }
private static void ReprotectAsExecutable(int offset, int size) private static void ReprotectAsExecutable(ReservedRegion region, int offset, int size)
{ {
int endOffs = offset + size; int endOffs = offset + size;
int regionStart = offset & ~_pageMask; int regionStart = offset & ~_pageMask;
int regionEnd = (endOffs + _pageMask) & ~_pageMask; int regionEnd = (endOffs + _pageMask) & ~_pageMask;
_jitRegion.Block.MapAsRx((ulong)regionStart, (ulong)(regionEnd - regionStart)); region.Block.MapAsRx((ulong)regionStart, (ulong)(regionEnd - regionStart));
} }
private static int Allocate(int codeSize) private static int Allocate(int codeSize)
{ {
codeSize = AlignCodeSize(codeSize); codeSize = AlignCodeSize(codeSize);
int allocOffset = _cacheAllocator.Allocate(codeSize); int allocOffset = _cacheAllocators[_activeRegionIndex].Allocate(codeSize);
if (allocOffset < 0) if (allocOffset >= 0)
{ {
throw new OutOfMemoryException("JIT Cache exhausted."); _jitRegions[_activeRegionIndex].ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize);
return allocOffset;
} }
_jitRegion.ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize); int exhaustedRegion = _activeRegionIndex;
var newRegion = new ReservedRegion(_jitRegions[0].Allocator, CacheSize);
_jitRegions.Add(newRegion);
_activeRegionIndex = _jitRegions.Count - 1;
return allocOffset; Logger.Warning?.Print(LogClass.Cpu, $"JIT Cache Region {exhaustedRegion} exhausted, creating new Cache Region {_activeRegionIndex} ({((long)(_activeRegionIndex + 1) * CacheSize).Bytes()} Total Allocation).");
_cacheAllocators.Add(new CacheMemoryAllocator(CacheSize));
int allocOffsetNew = _cacheAllocators[_activeRegionIndex].Allocate(codeSize);
if (allocOffsetNew < 0)
{
throw new OutOfMemoryException("Failed to allocate in new Cache Region!");
}
newRegion.ExpandIfNeeded((ulong)allocOffsetNew + (ulong)codeSize);
return allocOffsetNew;
} }
private static int AlignCodeSize(int codeSize) private static int AlignCodeSize(int codeSize)
@@ -249,16 +222,13 @@ namespace ARMeilleure.Translation.Cache
} }
_cacheEntries.Insert(index, entry); _cacheEntries.Insert(index, entry);
if (Optimizations.CacheEviction)
{
_entryUsageStats[offset] = new EntryUsageStats();
}
} }
public static bool TryFind(int offset, out CacheEntry entry, out int entryIndex) public static bool TryFind(int offset, out CacheEntry entry, out int entryIndex)
{ {
lock (_lock) lock (_lock)
{
foreach (var region in _jitRegions)
{ {
int index = _cacheEntries.BinarySearch(new CacheEntry(offset, 0, default)); int index = _cacheEntries.BinarySearch(new CacheEntry(offset, 0, default));
@@ -270,98 +240,15 @@ namespace ARMeilleure.Translation.Cache
if (index >= 0) if (index >= 0)
{ {
entry = _cacheEntries[index]; entry = _cacheEntries[index];
if (Optimizations.CacheEviction && _entryUsageStats.TryGetValue(offset, out EntryUsageStats stats))
{
stats.UpdateUsage();
}
entryIndex = index; entryIndex = index;
return true; return true;
} }
} }
}
entry = default; entry = default;
entryIndex = 0; entryIndex = 0;
return false; return false;
} }
private static void EvictEntries(int requiredSize)
{
if (!Optimizations.CacheEviction)
{
return;
}
lock (_lock)
{
int targetSpace = Math.Max(requiredSize, (int)(_cacheSize * EvictionTargetPercentage));
int freedSpace = 0;
int evictedCount = 0;
var entriesWithStats = _cacheEntries
.Where(e => _entryUsageStats.ContainsKey(e.Offset))
.Select(e => new {
Entry = e,
Stats = _entryUsageStats[e.Offset],
Score = CalculateEvictionScore(_entryUsageStats[e.Offset])
})
.OrderBy(x => x.Score)
.Take(MaxEntriesToEvictAtOnce)
.ToList();
foreach (var item in entriesWithStats)
{
int entrySize = AlignCodeSize(item.Entry.Size);
int entryIndex = _cacheEntries.BinarySearch(item.Entry);
if (entryIndex >= 0)
{
_cacheAllocator.Free(item.Entry.Offset, entrySize);
_cacheEntries.RemoveAt(entryIndex);
_entryUsageStats.Remove(item.Entry.Offset);
freedSpace += entrySize;
evictedCount++;
if (freedSpace >= targetSpace)
{
break;
}
}
}
_totalEvictions += evictedCount;
Logger.Info?.Print(LogClass.Cpu, $"JIT Cache: Evicted {evictedCount} entries, freed {freedSpace / (1024 * 1024.0):F2} MB");
}
}
private static double CalculateEvictionScore(EntryUsageStats stats)
{
long currentTime = DateTime.UtcNow.Ticks;
long ageInTicks = currentTime - stats.LastAccessTime;
double ageInSeconds = ageInTicks / 10_000_000.0;
const double usageWeight = 1.0;
const double ageWeight = 2.0;
double usageScore = Math.Log10(stats.UsageCount + 1) * usageWeight;
double ageScore = (10.0 / (ageInSeconds + 1.0)) * ageWeight;
return usageScore + ageScore;
}
private static void LogCacheStatus()
{
int estimatedUsedSize = _cacheEntries.Sum(e => AlignCodeSize(e.Size));
double usagePercentage = 100.0 * estimatedUsedSize / _cacheSize;
Logger.Info?.Print(LogClass.Cpu,
$"JIT Cache status: entries={_cacheEntries.Count}, " +
$"est. used={estimatedUsedSize / (1024 * 1024.0):F2} MB ({usagePercentage:F1}%), " +
$"evictions={_totalEvictions}, allocations={_totalAllocations}");
}
} }
} }
@@ -1,4 +1,5 @@
using ARMeilleure.Memory; using ARMeilleure.Memory;
using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace ARMeilleure.Translation.Cache namespace ARMeilleure.Translation.Cache
@@ -67,7 +68,7 @@ namespace ARMeilleure.Translation.Cache
} }
} }
public void Invalidate(nint basePointer, ulong size) public void Invalidate(IntPtr basePointer, ulong size)
{ {
if (_needsInvalidation) if (_needsInvalidation)
{ {
@@ -40,7 +40,7 @@ namespace ARMeilleure.Translation.Cache
PushMachframe = 10, PushMachframe = 10,
} }
private unsafe delegate RuntimeFunction* GetRuntimeFunctionCallback(ulong controlPc, nint context); private unsafe delegate RuntimeFunction* GetRuntimeFunctionCallback(ulong controlPc, IntPtr context);
[LibraryImport("kernel32.dll")] [LibraryImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)] [return: MarshalAs(UnmanagedType.Bool)]
@@ -49,7 +49,7 @@ namespace ARMeilleure.Translation.Cache
ulong baseAddress, ulong baseAddress,
uint length, uint length,
GetRuntimeFunctionCallback callback, GetRuntimeFunctionCallback callback,
nint context, IntPtr context,
[MarshalAs(UnmanagedType.LPWStr)] string outOfProcessCallbackDll); [MarshalAs(UnmanagedType.LPWStr)] string outOfProcessCallbackDll);
[LibraryImport("kernel32.dll")] [LibraryImport("kernel32.dll")]
@@ -65,7 +65,7 @@ namespace ARMeilleure.Translation.Cache
private unsafe static UnwindInfo* _unwindInfo; private unsafe static UnwindInfo* _unwindInfo;
public static void InstallFunctionTableHandler(nint codeCachePointer, uint codeCacheLength, nint workBufferPtr) public static void InstallFunctionTableHandler(IntPtr codeCachePointer, uint codeCacheLength, IntPtr workBufferPtr)
{ {
ulong codeCachePtr = (ulong)codeCachePointer.ToInt64(); ulong codeCachePtr = (ulong)codeCachePointer.ToInt64();
@@ -96,7 +96,7 @@ namespace ARMeilleure.Translation.Cache
} }
} }
public static void RemoveFunctionTableHandler(nint codeCachePointer) public static void RemoveFunctionTableHandler(IntPtr codeCachePointer)
{ {
ulong codeCachePtr = (ulong)codeCachePointer.ToInt64(); ulong codeCachePtr = (ulong)codeCachePointer.ToInt64();
@@ -113,7 +113,7 @@ namespace ARMeilleure.Translation.Cache
} }
} }
private static unsafe RuntimeFunction* FunctionTableHandler(ulong controlPc, nint context) private static unsafe RuntimeFunction* FunctionTableHandler(ulong controlPc, IntPtr context)
{ {
int offset = (int)((long)controlPc - context.ToInt64()); int offset = (int)((long)controlPc - context.ToInt64());
@@ -122,13 +122,13 @@ namespace ARMeilleure.Translation.Cache
return null; // Not found. return null; // Not found.
} }
CodeGen.Unwinding.UnwindInfo unwindInfo = funcEntry.UnwindInfo; var unwindInfo = funcEntry.UnwindInfo;
int codeIndex = 0; int codeIndex = 0;
for (int index = unwindInfo.PushEntries.Length - 1; index >= 0; index--) for (int index = unwindInfo.PushEntries.Length - 1; index >= 0; index--)
{ {
UnwindPushEntry entry = unwindInfo.PushEntries[index]; var entry = unwindInfo.PushEntries[index];
switch (entry.PseudoOp) switch (entry.PseudoOp)
{ {
@@ -47,8 +47,8 @@ namespace ARMeilleure.Translation
{ {
RemoveUnreachableBlocks(Blocks); RemoveUnreachableBlocks(Blocks);
HashSet<BasicBlock> visited = new(); var visited = new HashSet<BasicBlock>();
Stack<BasicBlock> blockStack = new(); var blockStack = new Stack<BasicBlock>();
Array.Resize(ref _postOrderBlocks, Blocks.Count); Array.Resize(ref _postOrderBlocks, Blocks.Count);
Array.Resize(ref _postOrderMap, Blocks.Count); Array.Resize(ref _postOrderMap, Blocks.Count);
@@ -88,8 +88,8 @@ namespace ARMeilleure.Translation
private void RemoveUnreachableBlocks(IntrusiveList<BasicBlock> blocks) private void RemoveUnreachableBlocks(IntrusiveList<BasicBlock> blocks)
{ {
HashSet<BasicBlock> visited = new(); var visited = new HashSet<BasicBlock>();
Queue<BasicBlock> workQueue = new(); var workQueue = new Queue<BasicBlock>();
visited.Add(Entry); visited.Add(Entry);
workQueue.Enqueue(Entry); workQueue.Enqueue(Entry);
+5 -3
View File
@@ -1,10 +1,12 @@
using System;
namespace ARMeilleure.Translation namespace ARMeilleure.Translation
{ {
public class DelegateInfo class DelegateInfo
{ {
public nint FuncPtr { get; } public IntPtr FuncPtr { get; }
public DelegateInfo(nint funcPtr) public DelegateInfo(IntPtr funcPtr)
{ {
FuncPtr = funcPtr; FuncPtr = funcPtr;
} }
+37 -593
View File
@@ -2,359 +2,12 @@ using ARMeilleure.Instructions;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
#if ANDROID
using ARMeilleure.State;
using System.Runtime.InteropServices;
#endif
namespace ARMeilleure.Translation namespace ARMeilleure.Translation
{ {
static class Delegates static class Delegates
{ {
#if ANDROID public static bool TryGetDelegateFuncPtrByIndex(int index, out IntPtr funcPtr)
// MathHelper delegates
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double MathHelperAbsDelegate(double value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double MathHelperCeilingDelegate(double value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double MathHelperFloorDelegate(double value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double MathHelperRoundDelegate(double value, int mode);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double MathHelperTruncateDelegate(double value);
// MathHelperF delegates
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float MathHelperFAbsDelegate(float value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float MathHelperFCeilingDelegate(float value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float MathHelperFFloorDelegate(float value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float MathHelperFRoundDelegate(float value, int mode);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float MathHelperFTruncateDelegate(float value);
// NativeInterface delegates
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void NativeInterfaceBreakDelegate(ulong address, int imm);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate byte NativeInterfaceCheckSynchronizationDelegate();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void NativeInterfaceEnqueueForRejitDelegate(ulong address);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate ulong NativeInterfaceGetCntfrqEl0Delegate();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate ulong NativeInterfaceGetCntpctEl0Delegate();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate ulong NativeInterfaceGetCntvctEl0Delegate();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate ulong NativeInterfaceGetCtrEl0Delegate();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate ulong NativeInterfaceGetDczidEl0Delegate();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate ulong NativeInterfaceGetFunctionAddressDelegate(ulong address);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void NativeInterfaceInvalidateCacheLineDelegate(ulong address);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate byte NativeInterfaceReadByteDelegate(ulong address);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate ushort NativeInterfaceReadUInt16Delegate(ulong address);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate uint NativeInterfaceReadUInt32Delegate(ulong address);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate ulong NativeInterfaceReadUInt64Delegate(ulong address);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 NativeInterfaceReadVector128Delegate(ulong address);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void NativeInterfaceSignalMemoryTrackingDelegate(ulong address, ulong size, byte write);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void NativeInterfaceSupervisorCallDelegate(ulong address, int imm);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void NativeInterfaceThrowInvalidMemoryAccessDelegate(ulong address);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void NativeInterfaceUndefinedDelegate(ulong address, int opCode);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void NativeInterfaceWriteByteDelegate(ulong address, byte value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void NativeInterfaceWriteUInt16Delegate(ulong address, ushort value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void NativeInterfaceWriteUInt32Delegate(ulong address, uint value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void NativeInterfaceWriteUInt64Delegate(ulong address, ulong value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void NativeInterfaceWriteVector128Delegate(ulong address, V128 value);
// SoftFallback delegates
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate ulong SoftFallbackCountLeadingSignsDelegate(ulong value, int size);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate ulong SoftFallbackCountLeadingZerosDelegate(ulong value, int size);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate uint SoftFallbackCrc32bDelegate(uint crc, byte val);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate uint SoftFallbackCrc32cbDelegate(uint crc, byte val);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate uint SoftFallbackCrc32chDelegate(uint crc, ushort val);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate uint SoftFallbackCrc32cwDelegate(uint crc, uint val);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate uint SoftFallbackCrc32cxDelegate(uint crc, ulong val);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate uint SoftFallbackCrc32hDelegate(uint crc, ushort val);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate uint SoftFallbackCrc32wDelegate(uint crc, uint val);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate uint SoftFallbackCrc32xDelegate(uint crc, ulong val);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackDecryptDelegate(V128 value, V128 roundKey);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackEncryptDelegate(V128 value, V128 roundKey);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate uint SoftFallbackFixedRotateDelegate(uint hash_e);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackHashChooseDelegate(V128 hash_abcd, uint hash_e, V128 wk);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackHashLowerDelegate(V128 hash_abcd, V128 hash_efgh, V128 wk);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackHashMajorityDelegate(V128 hash_abcd, uint hash_e, V128 wk);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackHashParityDelegate(V128 hash_abcd, uint hash_e, V128 wk);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackHashUpperDelegate(V128 hash_abcd, V128 hash_efgh, V128 wk);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackInverseMixColumnsDelegate(V128 value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackMixColumnsDelegate(V128 value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackPolynomialMult64_128Delegate(ulong op1, ulong op2);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int SoftFallbackSatF32ToS32Delegate(float value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate long SoftFallbackSatF32ToS64Delegate(float value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate uint SoftFallbackSatF32ToU32Delegate(float value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate ulong SoftFallbackSatF32ToU64Delegate(float value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int SoftFallbackSatF64ToS32Delegate(double value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate long SoftFallbackSatF64ToS64Delegate(double value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate uint SoftFallbackSatF64ToU32Delegate(double value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate ulong SoftFallbackSatF64ToU64Delegate(double value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackSha1SchedulePart1Delegate(V128 w0_3, V128 w4_7, V128 w8_11);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackSha1SchedulePart2Delegate(V128 tw0_3, V128 w12_15);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackSha256SchedulePart1Delegate(V128 w0_3, V128 w4_7);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackSha256SchedulePart2Delegate(V128 w0_3, V128 w8_11, V128 w12_15);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate long SoftFallbackSignedShrImm64Delegate(long value, long roundConst, int shift);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackTbl1Delegate(V128 vector, int bytes, V128 table);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackTbl2Delegate(V128 vector, int bytes, V128 table0, V128 table1);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackTbl3Delegate(V128 vector, int bytes, V128 table0, V128 table1, V128 table2);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackTbl4Delegate(V128 vector, int bytes, V128 table0, V128 table1, V128 table2, V128 table3);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackTbx1Delegate(V128 dest, V128 vector, int bytes, V128 table);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackTbx2Delegate(V128 dest, V128 vector, int bytes, V128 table0, V128 table1);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackTbx3Delegate(V128 dest, V128 vector, int bytes, V128 table0, V128 table1, V128 table2);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate V128 SoftFallbackTbx4Delegate(V128 dest, V128 vector, int bytes, V128 table0, V128 table1, V128 table2, V128 table3);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate ulong SoftFallbackUnsignedShrImm64Delegate(ulong value, long roundConst, int shift);
// SoftFloat delegates
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat16_32FPConvertDelegate(ushort value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat16_64FPConvertDelegate(ushort value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPAddDelegate(float a, float b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPAddFpscrDelegate(float a, float b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int SoftFloat32FPCompareDelegate(float a, float b, byte signalNaNs);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPCompareEQDelegate(float a, float b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPCompareEQFpscrDelegate(float a, float b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPCompareGEDelegate(float a, float b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPCompareGEFpscrDelegate(float a, float b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPCompareGTDelegate(float a, float b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPCompareGTFpscrDelegate(float a, float b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPCompareLEDelegate(float a, float b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPCompareLEFpscrDelegate(float a, float b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPCompareLTDelegate(float a, float b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPCompareLTFpscrDelegate(float a, float b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPDivDelegate(float a, float b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPMaxDelegate(float a, float b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPMaxFpscrDelegate(float a, float b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPMaxNumDelegate(float a, float b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPMaxNumFpscrDelegate(float a, float b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPMinDelegate(float a, float b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPMinFpscrDelegate(float a, float b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPMinNumDelegate(float a, float b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPMinNumFpscrDelegate(float a, float b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPMulDelegate(float a, float b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPMulFpscrDelegate(float a, float b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPMulAddDelegate(float a, float b, float c);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPMulAddFpscrDelegate(float a, float b, float c, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPMulSubDelegate(float a, float b, float c);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPMulSubFpscrDelegate(float a, float b, float c, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPMulXDelegate(float a, float b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPNegMulAddDelegate(float a, float b, float c);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPNegMulSubDelegate(float a, float b, float c);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPRecipEstimateDelegate(float a);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPRecipEstimateFpscrDelegate(float a, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPRecipStepDelegate(float a, float b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPRecipStepFusedDelegate(float a, float b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPRecpXDelegate(float a);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPRSqrtEstimateDelegate(float a);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPRSqrtEstimateFpscrDelegate(float a, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPRSqrtStepDelegate(float a, float b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPRSqrtStepFusedDelegate(float a, float b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPSqrtDelegate(float a);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float SoftFloat32FPSubDelegate(float a, float b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate ushort SoftFloat32_16FPConvertDelegate(float value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPAddDelegate(double a, double b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPAddFpscrDelegate(double a, double b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int SoftFloat64FPCompareDelegate(double a, double b, byte signalNaNs);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPCompareEQDelegate(double a, double b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPCompareEQFpscrDelegate(double a, double b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPCompareGEDelegate(double a, double b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPCompareGEFpscrDelegate(double a, double b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPCompareGTDelegate(double a, double b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPCompareGTFpscrDelegate(double a, double b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPCompareLEDelegate(double a, double b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPCompareLEFpscrDelegate(double a, double b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPCompareLTDelegate(double a, double b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPCompareLTFpscrDelegate(double a, double b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPDivDelegate(double a, double b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPMaxDelegate(double a, double b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPMaxFpscrDelegate(double a, double b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPMaxNumDelegate(double a, double b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPMaxNumFpscrDelegate(double a, double b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPMinDelegate(double a, double b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPMinFpscrDelegate(double a, double b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPMinNumDelegate(double a, double b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPMinNumFpscrDelegate(double a, double b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPMulDelegate(double a, double b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPMulFpscrDelegate(double a, double b, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPMulAddDelegate(double a, double b, double c);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPMulAddFpscrDelegate(double a, double b, double c, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPMulSubDelegate(double a, double b, double c);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPMulSubFpscrDelegate(double a, double b, double c, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPMulXDelegate(double a, double b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPNegMulAddDelegate(double a, double b, double c);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPNegMulSubDelegate(double a, double b, double c);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPRecipEstimateDelegate(double a);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPRecipEstimateFpscrDelegate(double a, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPRecipStepDelegate(double a, double b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPRecipStepFusedDelegate(double a, double b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPRecpXDelegate(double a);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPRSqrtEstimateDelegate(double a);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPRSqrtEstimateFpscrDelegate(double a, byte standardFpscr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPRSqrtStepDelegate(double a, double b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPRSqrtStepFusedDelegate(double a, double b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPSqrtDelegate(double a);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate double SoftFloat64FPSubDelegate(double a, double b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate ushort SoftFloat64_16FPConvertDelegate(double value);
private static readonly Dictionary<string, Delegate> _androidDelegates;
#endif
public static bool TryGetDelegateFuncPtrByIndex(int index, out nint funcPtr)
{ {
if (index >= 0 && index < _delegates.Count) if (index >= 0 && index < _delegates.Count)
{ {
@@ -370,7 +23,7 @@ namespace ARMeilleure.Translation
} }
} }
public static nint GetDelegateFuncPtrByIndex(int index) public static IntPtr GetDelegateFuncPtrByIndex(int index)
{ {
if (index < 0 || index >= _delegates.Count) if (index < 0 || index >= _delegates.Count)
{ {
@@ -400,32 +53,7 @@ namespace ARMeilleure.Translation
{ {
string key = GetKey(method); string key = GetKey(method);
#if ANDROID _delegates.Add(key, new DelegateInfo(method.MethodHandle.GetFunctionPointer())); // ArgumentException (key).
if (_androidDelegates.TryGetValue(key, out Delegate del))
{
nint funcPtr = Marshal.GetFunctionPointerForDelegate(del);
_delegates.Add(key, new DelegateInfo(funcPtr));
return;
}
#endif
try
{
_delegates.Add(key, new DelegateInfo(method.MethodHandle.GetFunctionPointer()));
}
catch (NotSupportedException) when (IsRunningOnAndroid())
{
throw new PlatformNotSupportedException($"Cannot obtain function pointer {key}: it must be registered.");
}
}
private static bool IsRunningOnAndroid()
{
#if ANDROID
return true;
#else
return false;
#endif
} }
private static string GetKey(MethodInfo info) private static string GetKey(MethodInfo info)
@@ -439,190 +67,6 @@ namespace ARMeilleure.Translation
{ {
_delegates = new SortedList<string, DelegateInfo>(); _delegates = new SortedList<string, DelegateInfo>();
#if ANDROID
_androidDelegates = new Dictionary<string, Delegate>
{
// MathHelper delegates
{ "MathHelper.Abs", new MathHelperAbsDelegate(Math.Abs) },
{ "MathHelper.Ceiling", new MathHelperCeilingDelegate(Math.Ceiling) },
{ "MathHelper.Floor", new MathHelperFloorDelegate(Math.Floor) },
{ "MathHelper.Round", new MathHelperRoundDelegate((value, mode) => Math.Round(value, (MidpointRounding)mode)) },
{ "MathHelper.Truncate", new MathHelperTruncateDelegate(Math.Truncate) },
// MathHelperF delegates
{ "MathHelperF.Abs", new MathHelperFAbsDelegate(MathF.Abs) },
{ "MathHelperF.Ceiling", new MathHelperFCeilingDelegate(MathF.Ceiling) },
{ "MathHelperF.Floor", new MathHelperFFloorDelegate(MathF.Floor) },
{ "MathHelperF.Round", new MathHelperFRoundDelegate((value, mode) => MathF.Round(value, (MidpointRounding)mode)) },
{ "MathHelperF.Truncate", new MathHelperFTruncateDelegate(MathF.Truncate) },
// NativeInterface delegates
{ "NativeInterface.Break", new NativeInterfaceBreakDelegate(NativeInterface.Break) },
{ "NativeInterface.CheckSynchronization", new NativeInterfaceCheckSynchronizationDelegate(NativeInterface.CheckSynchronization) },
{ "NativeInterface.EnqueueForRejit", new NativeInterfaceEnqueueForRejitDelegate(NativeInterface.EnqueueForRejit) },
{ "NativeInterface.GetCntfrqEl0", new NativeInterfaceGetCntfrqEl0Delegate(NativeInterface.GetCntfrqEl0) },
{ "NativeInterface.GetCntpctEl0", new NativeInterfaceGetCntpctEl0Delegate(NativeInterface.GetCntpctEl0) },
{ "NativeInterface.GetCntvctEl0", new NativeInterfaceGetCntvctEl0Delegate(NativeInterface.GetCntvctEl0) },
{ "NativeInterface.GetCtrEl0", new NativeInterfaceGetCtrEl0Delegate(NativeInterface.GetCtrEl0) },
{ "NativeInterface.GetDczidEl0", new NativeInterfaceGetDczidEl0Delegate(NativeInterface.GetDczidEl0) },
{ "NativeInterface.GetFunctionAddress", new NativeInterfaceGetFunctionAddressDelegate(NativeInterface.GetFunctionAddress) },
{ "NativeInterface.InvalidateCacheLine", new NativeInterfaceInvalidateCacheLineDelegate(NativeInterface.InvalidateCacheLine) },
{ "NativeInterface.ReadByte", new NativeInterfaceReadByteDelegate(NativeInterface.ReadByte) },
{ "NativeInterface.ReadUInt16", new NativeInterfaceReadUInt16Delegate(NativeInterface.ReadUInt16) },
{ "NativeInterface.ReadUInt32", new NativeInterfaceReadUInt32Delegate(NativeInterface.ReadUInt32) },
{ "NativeInterface.ReadUInt64", new NativeInterfaceReadUInt64Delegate(NativeInterface.ReadUInt64) },
{ "NativeInterface.ReadVector128", new NativeInterfaceReadVector128Delegate(NativeInterface.ReadVector128) },
{ "NativeInterface.SignalMemoryTracking", new NativeInterfaceSignalMemoryTrackingDelegate(NativeInterface.SignalMemoryTracking) },
{ "NativeInterface.SupervisorCall", new NativeInterfaceSupervisorCallDelegate(NativeInterface.SupervisorCall) },
{ "NativeInterface.ThrowInvalidMemoryAccess", new NativeInterfaceThrowInvalidMemoryAccessDelegate(NativeInterface.ThrowInvalidMemoryAccess) },
{ "NativeInterface.Undefined", new NativeInterfaceUndefinedDelegate(NativeInterface.Undefined) },
{ "NativeInterface.WriteByte", new NativeInterfaceWriteByteDelegate(NativeInterface.WriteByte) },
{ "NativeInterface.WriteUInt16", new NativeInterfaceWriteUInt16Delegate(NativeInterface.WriteUInt16) },
{ "NativeInterface.WriteUInt32", new NativeInterfaceWriteUInt32Delegate(NativeInterface.WriteUInt32) },
{ "NativeInterface.WriteUInt64", new NativeInterfaceWriteUInt64Delegate(NativeInterface.WriteUInt64) },
{ "NativeInterface.WriteVector128", new NativeInterfaceWriteVector128Delegate(NativeInterface.WriteVector128) },
// SoftFallback delegates
{ "SoftFallback.CountLeadingSigns", new SoftFallbackCountLeadingSignsDelegate(SoftFallback.CountLeadingSigns) },
{ "SoftFallback.CountLeadingZeros", new SoftFallbackCountLeadingZerosDelegate(SoftFallback.CountLeadingZeros) },
{ "SoftFallback.Crc32b", new SoftFallbackCrc32bDelegate(SoftFallback.Crc32b) },
{ "SoftFallback.Crc32cb", new SoftFallbackCrc32cbDelegate(SoftFallback.Crc32cb) },
{ "SoftFallback.Crc32ch", new SoftFallbackCrc32chDelegate(SoftFallback.Crc32ch) },
{ "SoftFallback.Crc32cw", new SoftFallbackCrc32cwDelegate(SoftFallback.Crc32cw) },
{ "SoftFallback.Crc32cx", new SoftFallbackCrc32cxDelegate(SoftFallback.Crc32cx) },
{ "SoftFallback.Crc32h", new SoftFallbackCrc32hDelegate(SoftFallback.Crc32h) },
{ "SoftFallback.Crc32w", new SoftFallbackCrc32wDelegate(SoftFallback.Crc32w) },
{ "SoftFallback.Crc32x", new SoftFallbackCrc32xDelegate(SoftFallback.Crc32x) },
{ "SoftFallback.Decrypt", new SoftFallbackDecryptDelegate(SoftFallback.Decrypt) },
{ "SoftFallback.Encrypt", new SoftFallbackEncryptDelegate(SoftFallback.Encrypt) },
{ "SoftFallback.FixedRotate", new SoftFallbackFixedRotateDelegate(SoftFallback.FixedRotate) },
{ "SoftFallback.HashChoose", new SoftFallbackHashChooseDelegate(SoftFallback.HashChoose) },
{ "SoftFallback.HashLower", new SoftFallbackHashLowerDelegate(SoftFallback.HashLower) },
{ "SoftFallback.HashMajority", new SoftFallbackHashMajorityDelegate(SoftFallback.HashMajority) },
{ "SoftFallback.HashParity", new SoftFallbackHashParityDelegate(SoftFallback.HashParity) },
{ "SoftFallback.HashUpper", new SoftFallbackHashUpperDelegate(SoftFallback.HashUpper) },
{ "SoftFallback.InverseMixColumns", new SoftFallbackInverseMixColumnsDelegate(SoftFallback.InverseMixColumns) },
{ "SoftFallback.MixColumns", new SoftFallbackMixColumnsDelegate(SoftFallback.MixColumns) },
{ "SoftFallback.PolynomialMult64_128", new SoftFallbackPolynomialMult64_128Delegate(SoftFallback.PolynomialMult64_128) },
{ "SoftFallback.SatF32ToS32", new SoftFallbackSatF32ToS32Delegate(SoftFallback.SatF32ToS32) },
{ "SoftFallback.SatF32ToS64", new SoftFallbackSatF32ToS64Delegate(SoftFallback.SatF32ToS64) },
{ "SoftFallback.SatF32ToU32", new SoftFallbackSatF32ToU32Delegate(SoftFallback.SatF32ToU32) },
{ "SoftFallback.SatF32ToU64", new SoftFallbackSatF32ToU64Delegate(SoftFallback.SatF32ToU64) },
{ "SoftFallback.SatF64ToS32", new SoftFallbackSatF64ToS32Delegate(SoftFallback.SatF64ToS32) },
{ "SoftFallback.SatF64ToS64", new SoftFallbackSatF64ToS64Delegate(SoftFallback.SatF64ToS64) },
{ "SoftFallback.SatF64ToU32", new SoftFallbackSatF64ToU32Delegate(SoftFallback.SatF64ToU32) },
{ "SoftFallback.SatF64ToU64", new SoftFallbackSatF64ToU64Delegate(SoftFallback.SatF64ToU64) },
{ "SoftFallback.Sha1SchedulePart1", new SoftFallbackSha1SchedulePart1Delegate(SoftFallback.Sha1SchedulePart1) },
{ "SoftFallback.Sha1SchedulePart2", new SoftFallbackSha1SchedulePart2Delegate(SoftFallback.Sha1SchedulePart2) },
{ "SoftFallback.Sha256SchedulePart1", new SoftFallbackSha256SchedulePart1Delegate(SoftFallback.Sha256SchedulePart1) },
{ "SoftFallback.Sha256SchedulePart2", new SoftFallbackSha256SchedulePart2Delegate(SoftFallback.Sha256SchedulePart2) },
{ "SoftFallback.SignedShrImm64", new SoftFallbackSignedShrImm64Delegate(SoftFallback.SignedShrImm64) },
{ "SoftFallback.Tbl1", new SoftFallbackTbl1Delegate(SoftFallback.Tbl1) },
{ "SoftFallback.Tbl2", new SoftFallbackTbl2Delegate(SoftFallback.Tbl2) },
{ "SoftFallback.Tbl3", new SoftFallbackTbl3Delegate(SoftFallback.Tbl3) },
{ "SoftFallback.Tbl4", new SoftFallbackTbl4Delegate(SoftFallback.Tbl4) },
{ "SoftFallback.Tbx1", new SoftFallbackTbx1Delegate(SoftFallback.Tbx1) },
{ "SoftFallback.Tbx2", new SoftFallbackTbx2Delegate(SoftFallback.Tbx2) },
{ "SoftFallback.Tbx3", new SoftFallbackTbx3Delegate(SoftFallback.Tbx3) },
{ "SoftFallback.Tbx4", new SoftFallbackTbx4Delegate(SoftFallback.Tbx4) },
{ "SoftFallback.UnsignedShrImm64", new SoftFallbackUnsignedShrImm64Delegate(SoftFallback.UnsignedShrImm64) },
// SoftFloat delegates
{ "SoftFloat16_32.FPConvert", new SoftFloat16_32FPConvertDelegate(SoftFloat16_32.FPConvert) },
{ "SoftFloat16_64.FPConvert", new SoftFloat16_64FPConvertDelegate(SoftFloat16_64.FPConvert) },
{ "SoftFloat32.FPAdd", new SoftFloat32FPAddDelegate(SoftFloat32.FPAdd) },
{ "SoftFloat32.FPAddFpscr", new SoftFloat32FPAddFpscrDelegate(SoftFloat32.FPAddFpscr) },
{ "SoftFloat32.FPCompare", new SoftFloat32FPCompareDelegate(SoftFloat32.FPCompare) },
{ "SoftFloat32.FPCompareEQ", new SoftFloat32FPCompareEQDelegate(SoftFloat32.FPCompareEQ) },
{ "SoftFloat32.FPCompareEQFpscr", new SoftFloat32FPCompareEQFpscrDelegate(SoftFloat32.FPCompareEQFpscr) },
{ "SoftFloat32.FPCompareGE", new SoftFloat32FPCompareGEDelegate(SoftFloat32.FPCompareGE) },
{ "SoftFloat32.FPCompareGEFpscr", new SoftFloat32FPCompareGEFpscrDelegate(SoftFloat32.FPCompareGEFpscr) },
{ "SoftFloat32.FPCompareGT", new SoftFloat32FPCompareGTDelegate(SoftFloat32.FPCompareGT) },
{ "SoftFloat32.FPCompareGTFpscr", new SoftFloat32FPCompareGTFpscrDelegate(SoftFloat32.FPCompareGTFpscr) },
{ "SoftFloat32.FPCompareLE", new SoftFloat32FPCompareLEDelegate(SoftFloat32.FPCompareLE) },
{ "SoftFloat32.FPCompareLEFpscr", new SoftFloat32FPCompareLEFpscrDelegate(SoftFloat32.FPCompareLEFpscr) },
{ "SoftFloat32.FPCompareLT", new SoftFloat32FPCompareLTDelegate(SoftFloat32.FPCompareLT) },
{ "SoftFloat32.FPCompareLTFpscr", new SoftFloat32FPCompareLTFpscrDelegate(SoftFloat32.FPCompareLTFpscr) },
{ "SoftFloat32.FPDiv", new SoftFloat32FPDivDelegate(SoftFloat32.FPDiv) },
{ "SoftFloat32.FPMax", new SoftFloat32FPMaxDelegate(SoftFloat32.FPMax) },
{ "SoftFloat32.FPMaxFpscr", new SoftFloat32FPMaxFpscrDelegate(SoftFloat32.FPMaxFpscr) },
{ "SoftFloat32.FPMaxNum", new SoftFloat32FPMaxNumDelegate(SoftFloat32.FPMaxNum) },
{ "SoftFloat32.FPMaxNumFpscr", new SoftFloat32FPMaxNumFpscrDelegate(SoftFloat32.FPMaxNumFpscr) },
{ "SoftFloat32.FPMin", new SoftFloat32FPMinDelegate(SoftFloat32.FPMin) },
{ "SoftFloat32.FPMinFpscr", new SoftFloat32FPMinFpscrDelegate(SoftFloat32.FPMinFpscr) },
{ "SoftFloat32.FPMinNum", new SoftFloat32FPMinNumDelegate(SoftFloat32.FPMinNum) },
{ "SoftFloat32.FPMinNumFpscr", new SoftFloat32FPMinNumFpscrDelegate(SoftFloat32.FPMinNumFpscr) },
{ "SoftFloat32.FPMul", new SoftFloat32FPMulDelegate(SoftFloat32.FPMul) },
{ "SoftFloat32.FPMulFpscr", new SoftFloat32FPMulFpscrDelegate(SoftFloat32.FPMulFpscr) },
{ "SoftFloat32.FPMulAdd", new SoftFloat32FPMulAddDelegate(SoftFloat32.FPMulAdd) },
{ "SoftFloat32.FPMulAddFpscr", new SoftFloat32FPMulAddFpscrDelegate(SoftFloat32.FPMulAddFpscr) },
{ "SoftFloat32.FPMulSub", new SoftFloat32FPMulSubDelegate(SoftFloat32.FPMulSub) },
{ "SoftFloat32.FPMulSubFpscr", new SoftFloat32FPMulSubFpscrDelegate(SoftFloat32.FPMulSubFpscr) },
{ "SoftFloat32.FPMulX", new SoftFloat32FPMulXDelegate(SoftFloat32.FPMulX) },
{ "SoftFloat32.FPNegMulAdd", new SoftFloat32FPNegMulAddDelegate(SoftFloat32.FPNegMulAdd) },
{ "SoftFloat32.FPNegMulSub", new SoftFloat32FPNegMulSubDelegate(SoftFloat32.FPNegMulSub) },
{ "SoftFloat32.FPRecipEstimate", new SoftFloat32FPRecipEstimateDelegate(SoftFloat32.FPRecipEstimate) },
{ "SoftFloat32.FPRecipEstimateFpscr", new SoftFloat32FPRecipEstimateFpscrDelegate(SoftFloat32.FPRecipEstimateFpscr) },
{ "SoftFloat32.FPRecipStep", new SoftFloat32FPRecipStepDelegate(SoftFloat32.FPRecipStep) },
{ "SoftFloat32.FPRecipStepFused", new SoftFloat32FPRecipStepFusedDelegate(SoftFloat32.FPRecipStepFused) },
{ "SoftFloat32.FPRecpX", new SoftFloat32FPRecpXDelegate(SoftFloat32.FPRecpX) },
{ "SoftFloat32.FPRSqrtEstimate", new SoftFloat32FPRSqrtEstimateDelegate(SoftFloat32.FPRSqrtEstimate) },
{ "SoftFloat32.FPRSqrtEstimateFpscr", new SoftFloat32FPRSqrtEstimateFpscrDelegate(SoftFloat32.FPRSqrtEstimateFpscr) },
{ "SoftFloat32.FPRSqrtStep", new SoftFloat32FPRSqrtStepDelegate(SoftFloat32.FPRSqrtStep) },
{ "SoftFloat32.FPRSqrtStepFused", new SoftFloat32FPRSqrtStepFusedDelegate(SoftFloat32.FPRSqrtStepFused) },
{ "SoftFloat32.FPSqrt", new SoftFloat32FPSqrtDelegate(SoftFloat32.FPSqrt) },
{ "SoftFloat32.FPSub", new SoftFloat32FPSubDelegate(SoftFloat32.FPSub) },
{ "SoftFloat32_16.FPConvert", new SoftFloat32_16FPConvertDelegate(SoftFloat32_16.FPConvert) },
{ "SoftFloat64.FPAdd", new SoftFloat64FPAddDelegate(SoftFloat64.FPAdd) },
{ "SoftFloat64.FPAddFpscr", new SoftFloat64FPAddFpscrDelegate(SoftFloat64.FPAddFpscr) },
{ "SoftFloat64.FPCompare", new SoftFloat64FPCompareDelegate(SoftFloat64.FPCompare) },
{ "SoftFloat64.FPCompareEQ", new SoftFloat64FPCompareEQDelegate(SoftFloat64.FPCompareEQ) },
{ "SoftFloat64.FPCompareEQFpscr", new SoftFloat64FPCompareEQFpscrDelegate(SoftFloat64.FPCompareEQFpscr) },
{ "SoftFloat64.FPCompareGE", new SoftFloat64FPCompareGEDelegate(SoftFloat64.FPCompareGE) },
{ "SoftFloat64.FPCompareGEFpscr", new SoftFloat64FPCompareGEFpscrDelegate(SoftFloat64.FPCompareGEFpscr) },
{ "SoftFloat64.FPCompareGT", new SoftFloat64FPCompareGTDelegate(SoftFloat64.FPCompareGT) },
{ "SoftFloat64.FPCompareGTFpscr", new SoftFloat64FPCompareGTFpscrDelegate(SoftFloat64.FPCompareGTFpscr) },
{ "SoftFloat64.FPCompareLE", new SoftFloat64FPCompareLEDelegate(SoftFloat64.FPCompareLE) },
{ "SoftFloat64.FPCompareLEFpscr", new SoftFloat64FPCompareLEFpscrDelegate(SoftFloat64.FPCompareLEFpscr) },
{ "SoftFloat64.FPCompareLT", new SoftFloat64FPCompareLTDelegate(SoftFloat64.FPCompareLT) },
{ "SoftFloat64.FPCompareLTFpscr", new SoftFloat64FPCompareLTFpscrDelegate(SoftFloat64.FPCompareLTFpscr) },
{ "SoftFloat64.FPDiv", new SoftFloat64FPDivDelegate(SoftFloat64.FPDiv) },
{ "SoftFloat64.FPMax", new SoftFloat64FPMaxDelegate(SoftFloat64.FPMax) },
{ "SoftFloat64.FPMaxFpscr", new SoftFloat64FPMaxFpscrDelegate(SoftFloat64.FPMaxFpscr) },
{ "SoftFloat64.FPMaxNum", new SoftFloat64FPMaxNumDelegate(SoftFloat64.FPMaxNum) },
{ "SoftFloat64.FPMaxNumFpscr", new SoftFloat64FPMaxNumFpscrDelegate(SoftFloat64.FPMaxNumFpscr) },
{ "SoftFloat64.FPMin", new SoftFloat64FPMinDelegate(SoftFloat64.FPMin) },
{ "SoftFloat64.FPMinFpscr", new SoftFloat64FPMinFpscrDelegate(SoftFloat64.FPMinFpscr) },
{ "SoftFloat64.FPMinNum", new SoftFloat64FPMinNumDelegate(SoftFloat64.FPMinNum) },
{ "SoftFloat64.FPMinNumFpscr", new SoftFloat64FPMinNumFpscrDelegate(SoftFloat64.FPMinNumFpscr) },
{ "SoftFloat64.FPMul", new SoftFloat64FPMulDelegate(SoftFloat64.FPMul) },
{ "SoftFloat64.FPMulFpscr", new SoftFloat64FPMulFpscrDelegate(SoftFloat64.FPMulFpscr) },
{ "SoftFloat64.FPMulAdd", new SoftFloat64FPMulAddDelegate(SoftFloat64.FPMulAdd) },
{ "SoftFloat64.FPMulAddFpscr", new SoftFloat64FPMulAddFpscrDelegate(SoftFloat64.FPMulAddFpscr) },
{ "SoftFloat64.FPMulSub", new SoftFloat64FPMulSubDelegate(SoftFloat64.FPMulSub) },
{ "SoftFloat64.FPMulSubFpscr", new SoftFloat64FPMulSubFpscrDelegate(SoftFloat64.FPMulSubFpscr) },
{ "SoftFloat64.FPMulX", new SoftFloat64FPMulXDelegate(SoftFloat64.FPMulX) },
{ "SoftFloat64.FPNegMulAdd", new SoftFloat64FPNegMulAddDelegate(SoftFloat64.FPNegMulAdd) },
{ "SoftFloat64.FPNegMulSub", new SoftFloat64FPNegMulSubDelegate(SoftFloat64.FPNegMulSub) },
{ "SoftFloat64.FPRecipEstimate", new SoftFloat64FPRecipEstimateDelegate(SoftFloat64.FPRecipEstimate) },
{ "SoftFloat64.FPRecipEstimateFpscr", new SoftFloat64FPRecipEstimateFpscrDelegate(SoftFloat64.FPRecipEstimateFpscr) },
{ "SoftFloat64.FPRecipStep", new SoftFloat64FPRecipStepDelegate(SoftFloat64.FPRecipStep) },
{ "SoftFloat64.FPRecipStepFused", new SoftFloat64FPRecipStepFusedDelegate(SoftFloat64.FPRecipStepFused) },
{ "SoftFloat64.FPRecpX", new SoftFloat64FPRecpXDelegate(SoftFloat64.FPRecpX) },
{ "SoftFloat64.FPRSqrtEstimate", new SoftFloat64FPRSqrtEstimateDelegate(SoftFloat64.FPRSqrtEstimate) },
{ "SoftFloat64.FPRSqrtEstimateFpscr", new SoftFloat64FPRSqrtEstimateFpscrDelegate(SoftFloat64.FPRSqrtEstimateFpscr) },
{ "SoftFloat64.FPRSqrtStep", new SoftFloat64FPRSqrtStepDelegate(SoftFloat64.FPRSqrtStep) },
{ "SoftFloat64.FPRSqrtStepFused", new SoftFloat64FPRSqrtStepFusedDelegate(SoftFloat64.FPRSqrtStepFused) },
{ "SoftFloat64.FPSqrt", new SoftFloat64FPSqrtDelegate(SoftFloat64.FPSqrt) },
{ "SoftFloat64.FPSub", new SoftFloat64FPSubDelegate(SoftFloat64.FPSub) },
{ "SoftFloat64_16.FPConvert", new SoftFloat64_16FPConvertDelegate(SoftFloat64_16.FPConvert) }
};
#endif
SetDelegateInfo(typeof(MathHelper).GetMethod(nameof(MathHelper.Abs))); SetDelegateInfo(typeof(MathHelper).GetMethod(nameof(MathHelper.Abs)));
SetDelegateInfo(typeof(MathHelper).GetMethod(nameof(MathHelper.Ceiling))); SetDelegateInfo(typeof(MathHelper).GetMethod(nameof(MathHelper.Ceiling)));
SetDelegateInfo(typeof(MathHelper).GetMethod(nameof(MathHelper.Floor))); SetDelegateInfo(typeof(MathHelper).GetMethod(nameof(MathHelper.Floor)));
@@ -708,44 +152,44 @@ namespace ARMeilleure.Translation
SetDelegateInfo(typeof(SoftFloat16_64).GetMethod(nameof(SoftFloat16_64.FPConvert))); SetDelegateInfo(typeof(SoftFloat16_64).GetMethod(nameof(SoftFloat16_64.FPConvert)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPAdd))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPAdd)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPAddFpscr))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPAddFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompare))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompare)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareEQ))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareEQ)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareEQFpscr))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareEQFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGE))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGE)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGEFpscr))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGEFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGT))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGT)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGTFpscr))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGTFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLE))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLE)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLEFpscr))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLEFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLT))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLT)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLTFpscr))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLTFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPDiv))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPDiv)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMax))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMax)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxFpscr))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxNum))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxNum)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxNumFpscr))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxNumFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMin))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMin)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinFpscr))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinNum))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinNum)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinNumFpscr))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinNumFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMul))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMul)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulFpscr))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulAdd))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulAdd)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulAddFpscr))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulAddFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulSub))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulSub)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulSubFpscr))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulSubFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulX))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulX)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPNegMulAdd))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPNegMulAdd)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPNegMulSub))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPNegMulSub)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipEstimate))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipEstimate)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipEstimateFpscr))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipEstimateFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipStep))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipStep))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipStepFused))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipStepFused)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecpX))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecpX)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtEstimate))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtEstimate)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtEstimateFpscr))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtEstimateFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtStep))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtStep))); // A32 only.
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtStepFused))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtStepFused)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPSqrt))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPSqrt)));
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPSub))); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPSub)));
@@ -753,44 +197,44 @@ namespace ARMeilleure.Translation
SetDelegateInfo(typeof(SoftFloat32_16).GetMethod(nameof(SoftFloat32_16.FPConvert))); SetDelegateInfo(typeof(SoftFloat32_16).GetMethod(nameof(SoftFloat32_16.FPConvert)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPAdd))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPAdd)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPAddFpscr))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPAddFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompare))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompare)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareEQ))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareEQ)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareEQFpscr))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareEQFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGE))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGE)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGEFpscr))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGEFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGT))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGT)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGTFpscr))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGTFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLE))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLE)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLEFpscr))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLEFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLT))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLT)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLTFpscr))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLTFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPDiv))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPDiv)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMax))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMax)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxFpscr))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxNum))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxNum)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxNumFpscr))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxNumFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMin))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMin)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinFpscr))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinNum))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinNum)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinNumFpscr))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinNumFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMul))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMul)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulFpscr))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulAdd))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulAdd)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulAddFpscr))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulAddFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulSub))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulSub)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulSubFpscr))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulSubFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulX))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulX)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPNegMulAdd))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPNegMulAdd)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPNegMulSub))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPNegMulSub)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipEstimate))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipEstimate)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipEstimateFpscr))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipEstimateFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipStep))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipStep))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipStepFused))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipStepFused)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecpX))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecpX)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtEstimate))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtEstimate)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtEstimateFpscr))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtEstimateFpscr))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtStep))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtStep))); // A32 only.
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtStepFused))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtStepFused)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPSqrt))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPSqrt)));
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPSub))); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPSub)));
@@ -1,5 +1,7 @@
using System;
namespace ARMeilleure.Translation namespace ARMeilleure.Translation
{ {
delegate void DispatcherFunction(nint nativeContext, ulong startAddress); delegate void DispatcherFunction(IntPtr nativeContext, ulong startAddress);
delegate ulong WrapperFunction(nint nativeContext, ulong startAddress); delegate ulong WrapperFunction(IntPtr nativeContext, ulong startAddress);
} }
@@ -97,14 +97,7 @@ namespace ARMeilleure.Translation
public virtual Operand Call(MethodInfo info, params Operand[] callArgs) public virtual Operand Call(MethodInfo info, params Operand[] callArgs)
{ {
#if ANDROID IntPtr funcPtr = info.MethodHandle.GetFunctionPointer();
// For Android, use the Delegates class to get the function pointer
int index = Delegates.GetDelegateIndex(info);
nint funcPtr = Delegates.GetDelegateFuncPtrByIndex(index);
#else
// For other platforms, use direct method handle approach
nint funcPtr = info.MethodHandle.GetFunctionPointer();
#endif
OperandType returnType = GetOperandType(info.ReturnType); OperandType returnType = GetOperandType(info.ReturnType);
+3 -1
View File
@@ -1,4 +1,6 @@
using System;
namespace ARMeilleure.Translation namespace ARMeilleure.Translation
{ {
delegate ulong GuestFunction(nint nativeContextPtr); delegate ulong GuestFunction(IntPtr nativeContextPtr);
} }
+1 -1
View File
@@ -316,7 +316,7 @@ namespace ARMeilleure.Translation
{ {
_root = newNode; _root = newNode;
} }
else if (start.CompareTo(parent!.Start) < 0) else if (start.CompareTo(parent.Start) < 0)
{ {
parent.Left = newNode; parent.Left = newNode;
} }
+47 -51
View File
@@ -10,7 +10,6 @@ using Ryujinx.Common.Logging;
using Ryujinx.Common.Memory; using Ryujinx.Common.Memory;
using System; using System;
using System.Buffers.Binary; using System.Buffers.Binary;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
@@ -31,11 +30,14 @@ 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 = 7031; //! 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";
private const string TitleIdTextDefault = "0000000000000000";
private const string DisplayVersionDefault = "0";
public static readonly Symbol PageTableSymbol = new(SymbolType.Special, 1); public static readonly Symbol PageTableSymbol = new(SymbolType.Special, 1);
public static readonly Symbol CountTableSymbol = new(SymbolType.Special, 2); public static readonly Symbol CountTableSymbol = new(SymbolType.Special, 2);
public static readonly Symbol DispatchStubSymbol = new(SymbolType.Special, 3); public static readonly Symbol DispatchStubSymbol = new(SymbolType.Special, 3);
@@ -61,7 +63,8 @@ namespace ARMeilleure.Translation.PTC
private bool _disposed; private bool _disposed;
public PtcCacheInfo CacheInfo { get; private set; } public string TitleIdText { get; private set; }
public string DisplayVersion { get; private set; }
private MemoryManagerType _memoryMode; private MemoryManagerType _memoryMode;
@@ -88,7 +91,8 @@ namespace ARMeilleure.Translation.PTC
_disposed = false; _disposed = false;
CacheInfo = new PtcCacheInfo(0, null, null, 0, null, "Unknown", "default"); TitleIdText = TitleIdTextDefault;
DisplayVersion = DisplayVersionDefault;
CachePathActual = string.Empty; CachePathActual = string.Empty;
CachePathBackup = string.Empty; CachePathBackup = string.Empty;
@@ -96,24 +100,20 @@ namespace ARMeilleure.Translation.PTC
Disable(); Disable();
} }
public void Initialize(PtcCacheInfo cacheInfo, bool enabled, MemoryManagerType memoryMode) public void Initialize(string titleIdText, string displayVersion, bool enabled, MemoryManagerType memoryMode, string cacheSelector)
{ {
Wait(); Wait();
Profiler.Wait(); Profiler.Wait();
Profiler.ClearEntries(); Profiler.ClearEntries();
CacheInfo = cacheInfo; Logger.Info?.Print(LogClass.Ptc, $"Initializing Profiled Persistent Translation Cache (enabled: {enabled}).");
Logger.Info?.Print( if (!enabled || string.IsNullOrEmpty(titleIdText) || titleIdText == TitleIdTextDefault)
LogClass.Ptc,
$"Initializing Profiled Persistent Translation Cache v{InternalVersion}\n\t\t " +
$"(pid: {cacheInfo.ProcessId}, title: {cacheInfo.TitleIdText}, application: {cacheInfo.ApplicationIdText}, " +
$"programIndex: {cacheInfo.ProgramIndex}, version: '{cacheInfo.DisplayVersion}', kind: {cacheInfo.ProcessKind}, " +
$"selector: '{cacheInfo.CacheSelector}', key: '{cacheInfo.CacheKey}', enabled: {enabled}).");
if (!enabled || cacheInfo.TitleIdText == PtcCacheInfo.TitleIdTextDefault)
{ {
TitleIdText = TitleIdTextDefault;
DisplayVersion = DisplayVersionDefault;
CachePathActual = string.Empty; CachePathActual = string.Empty;
CachePathBackup = string.Empty; CachePathBackup = string.Empty;
@@ -122,10 +122,14 @@ namespace ARMeilleure.Translation.PTC
return; return;
} }
TitleIdText = titleIdText;
DisplayVersion = !string.IsNullOrEmpty(displayVersion) ? displayVersion : DisplayVersionDefault;
_memoryMode = memoryMode; _memoryMode = memoryMode;
string workPathActual = Path.Combine(AppDataManager.GamesDirPath, CacheInfo.TitleIdText, "cache", "cpu", ActualDir); Logger.Info?.Print(LogClass.Ptc, $"PPTC (v{InternalVersion}) Profile: {DisplayVersion}-{cacheSelector}");
string workPathBackup = Path.Combine(AppDataManager.GamesDirPath, CacheInfo.TitleIdText, "cache", "cpu", BackupDir);
string workPathActual = Path.Combine(AppDataManager.GamesDirPath, TitleIdText, "cache", "cpu", ActualDir);
string workPathBackup = Path.Combine(AppDataManager.GamesDirPath, TitleIdText, "cache", "cpu", BackupDir);
if (!Directory.Exists(workPathActual)) if (!Directory.Exists(workPathActual))
{ {
@@ -137,14 +141,8 @@ namespace ARMeilleure.Translation.PTC
Directory.CreateDirectory(workPathBackup); Directory.CreateDirectory(workPathBackup);
} }
CachePathActual = Path.Combine(workPathActual, CacheInfo.DisplayVersion) + "-" + CacheInfo.CacheSelector; CachePathActual = Path.Combine(workPathActual, DisplayVersion) + "-" + cacheSelector;
CachePathBackup = Path.Combine(workPathBackup, CacheInfo.DisplayVersion) + "-" + CacheInfo.CacheSelector; CachePathBackup = Path.Combine(workPathBackup, DisplayVersion) + "-" + cacheSelector;
Logger.Info?.Print(
LogClass.Ptc,
$"PPTC cache owner selected (pid: {CacheInfo.ProcessId}, title: {CacheInfo.TitleIdText}, application: {CacheInfo.ApplicationIdText}, " +
$"version: '{CacheInfo.DisplayVersion}', kind: {CacheInfo.ProcessKind}, selector: '{CacheInfo.CacheSelector}', " +
$"key: '{CacheInfo.CacheKey}', path: '{CachePathActual}').");
PreLoad(); PreLoad();
Profiler.PreLoad(); Profiler.PreLoad();
@@ -253,18 +251,19 @@ namespace ARMeilleure.Translation.PTC
outerHeader.FeatureInfo != GetFeatureInfo() || outerHeader.FeatureInfo != GetFeatureInfo() ||
outerHeader.MemoryManagerMode != GetMemoryManagerMode() || outerHeader.MemoryManagerMode != GetMemoryManagerMode() ||
outerHeader.OSPlatform != GetOSPlatform() || outerHeader.OSPlatform != GetOSPlatform() ||
outerHeader.Architecture != (uint)RuntimeInformation.ProcessArchitecture) outerHeader.Architecture != (uint)RuntimeInformation.ProcessArchitecture ||
outerHeader.DebuggerMode != Optimizations.EnableDebugging)
{ {
InvalidateCompressedStream(compressedStream); InvalidateCompressedStream(compressedStream);
return false; return false;
} }
nint intPtr = nint.Zero; IntPtr intPtr = IntPtr.Zero;
try try
{ {
intPtr = Marshal.AllocHGlobal(new nint(outerHeader.UncompressedStreamSize)); intPtr = Marshal.AllocHGlobal(new IntPtr(outerHeader.UncompressedStreamSize));
using UnmanagedMemoryStream stream = new((byte*)intPtr.ToPointer(), outerHeader.UncompressedStreamSize, outerHeader.UncompressedStreamSize, FileAccess.ReadWrite); using UnmanagedMemoryStream stream = new((byte*)intPtr.ToPointer(), outerHeader.UncompressedStreamSize, outerHeader.UncompressedStreamSize, FileAccess.ReadWrite);
try try
@@ -358,7 +357,7 @@ namespace ARMeilleure.Translation.PTC
} }
finally finally
{ {
if (intPtr != nint.Zero) if (intPtr != IntPtr.Zero)
{ {
Marshal.FreeHGlobal(intPtr); Marshal.FreeHGlobal(intPtr);
} }
@@ -367,12 +366,7 @@ namespace ARMeilleure.Translation.PTC
long fileSize = new FileInfo(fileName).Length; long fileSize = new FileInfo(fileName).Length;
Logger.Info?.Print( Logger.Info?.Print(LogClass.Ptc, $"{(isBackup ? "Loaded Backup Translation Cache" : "Loaded Translation Cache")} (size: {fileSize} bytes, translated functions: {GetEntriesCount()}).");
LogClass.Ptc,
$"{(isBackup ? "Loaded Backup Translation Cache" : "Loaded Translation Cache")} " +
$"(pid: {CacheInfo.ProcessId}, title: {CacheInfo.TitleIdText}, version: '{CacheInfo.DisplayVersion}', kind: {CacheInfo.ProcessKind}, " +
$"selector: '{CacheInfo.CacheSelector}', key: '{CacheInfo.CacheKey}', path: '{fileName}', " +
$"size: {fileSize} bytes, translated functions: {GetEntriesCount()}).");
return true; return true;
} }
@@ -434,6 +428,7 @@ namespace ARMeilleure.Translation.PTC
MemoryManagerMode = GetMemoryManagerMode(), MemoryManagerMode = GetMemoryManagerMode(),
OSPlatform = GetOSPlatform(), OSPlatform = GetOSPlatform(),
Architecture = (uint)RuntimeInformation.ProcessArchitecture, Architecture = (uint)RuntimeInformation.ProcessArchitecture,
DebuggerMode = Optimizations.EnableDebugging,
UncompressedStreamSize = UncompressedStreamSize =
(long)Unsafe.SizeOf<InnerHeader>() + (long)Unsafe.SizeOf<InnerHeader>() +
@@ -445,11 +440,11 @@ namespace ARMeilleure.Translation.PTC
outerHeader.SetHeaderHash(); outerHeader.SetHeaderHash();
nint intPtr = nint.Zero; IntPtr intPtr = IntPtr.Zero;
try try
{ {
intPtr = Marshal.AllocHGlobal(new nint(outerHeader.UncompressedStreamSize)); intPtr = Marshal.AllocHGlobal(new IntPtr(outerHeader.UncompressedStreamSize));
using UnmanagedMemoryStream stream = new((byte*)intPtr.ToPointer(), outerHeader.UncompressedStreamSize, outerHeader.UncompressedStreamSize, FileAccess.ReadWrite); using UnmanagedMemoryStream stream = new((byte*)intPtr.ToPointer(), outerHeader.UncompressedStreamSize, outerHeader.UncompressedStreamSize, FileAccess.ReadWrite);
stream.Seek((long)Unsafe.SizeOf<InnerHeader>(), SeekOrigin.Begin); stream.Seek((long)Unsafe.SizeOf<InnerHeader>(), SeekOrigin.Begin);
@@ -503,7 +498,7 @@ namespace ARMeilleure.Translation.PTC
} }
finally finally
{ {
if (intPtr != nint.Zero) if (intPtr != IntPtr.Zero)
{ {
Marshal.FreeHGlobal(intPtr); Marshal.FreeHGlobal(intPtr);
} }
@@ -551,7 +546,7 @@ namespace ARMeilleure.Translation.PTC
bool isEntryChanged = infoEntry.Hash != ComputeHash(translator.Memory, infoEntry.Address, infoEntry.GuestSize); bool isEntryChanged = infoEntry.Hash != ComputeHash(translator.Memory, infoEntry.Address, infoEntry.GuestSize);
if (isEntryChanged || (!infoEntry.HighCq && Profiler.ProfiledFuncs.TryGetValue(infoEntry.Address, out PtcProfiler.FuncProfile value) && value.HighCq)) if (isEntryChanged || (!infoEntry.HighCq && Profiler.ProfiledFuncs.TryGetValue(infoEntry.Address, out var value) && value.HighCq))
{ {
infoEntry.Stubbed = true; infoEntry.Stubbed = true;
infoEntry.CodeLength = 0; infoEntry.CodeLength = 0;
@@ -655,7 +650,7 @@ namespace ARMeilleure.Translation.PTC
foreach (RelocEntry relocEntry in relocEntries) foreach (RelocEntry relocEntry in relocEntries)
{ {
nint? imm = null; IntPtr? imm = null;
Symbol symbol = relocEntry.Symbol; Symbol symbol = relocEntry.Symbol;
if (symbol.Type == SymbolType.FunctionTable) if (symbol.Type == SymbolType.FunctionTable)
@@ -666,7 +661,7 @@ namespace ARMeilleure.Translation.PTC
{ {
unsafe unsafe
{ {
imm = (nint)Unsafe.AsPointer(ref translator.FunctionTable.GetValue(guestAddress)); imm = (IntPtr)Unsafe.AsPointer(ref translator.FunctionTable.GetValue(guestAddress));
} }
} }
} }
@@ -674,7 +669,7 @@ namespace ARMeilleure.Translation.PTC
{ {
int index = (int)symbol.Value; int index = (int)symbol.Value;
if (Delegates.TryGetDelegateFuncPtrByIndex(index, out nint funcPtr)) if (Delegates.TryGetDelegateFuncPtrByIndex(index, out IntPtr funcPtr))
{ {
imm = funcPtr; imm = funcPtr;
} }
@@ -689,7 +684,7 @@ namespace ARMeilleure.Translation.PTC
unsafe unsafe
{ {
imm = (nint)Unsafe.AsPointer(ref callCounter.Value); imm = (IntPtr)Unsafe.AsPointer(ref callCounter.Value);
} }
} }
else if (symbol == DispatchStubSymbol) else if (symbol == DispatchStubSymbol)
@@ -738,8 +733,8 @@ namespace ARMeilleure.Translation.PTC
UnwindInfo unwindInfo, UnwindInfo unwindInfo,
bool highCq) bool highCq)
{ {
CompiledFunction cFunc = new(code, unwindInfo, RelocInfo.Empty); var cFunc = new CompiledFunction(code, unwindInfo, RelocInfo.Empty);
GuestFunction gFunc = cFunc.MapWithPointer<GuestFunction>(out nint gFuncPointer); var gFunc = cFunc.MapWithPointer<GuestFunction>(out IntPtr gFuncPointer);
return new TranslatedFunction(gFunc, gFuncPointer, callCounter, guestSize, highCq); return new TranslatedFunction(gFunc, gFuncPointer, callCounter, guestSize, highCq);
} }
@@ -776,7 +771,7 @@ namespace ARMeilleure.Translation.PTC
public void MakeAndSaveTranslations(Translator translator) public void MakeAndSaveTranslations(Translator translator)
{ {
ConcurrentQueue<(ulong address, PtcProfiler.FuncProfile funcProfile)> profiledFuncsToTranslate = Profiler.GetProfiledFuncsToTranslate(translator.Functions); var profiledFuncsToTranslate = Profiler.GetProfiledFuncsToTranslate(translator.Functions);
_translateCount = 0; _translateCount = 0;
_translateTotalCount = profiledFuncsToTranslate.Count; _translateTotalCount = profiledFuncsToTranslate.Count;
@@ -820,7 +815,7 @@ namespace ARMeilleure.Translation.PTC
void TranslateFuncs() void TranslateFuncs()
{ {
while (profiledFuncsToTranslate.TryDequeue(out (ulong address, PtcProfiler.FuncProfile funcProfile) item)) while (profiledFuncsToTranslate.TryDequeue(out var item))
{ {
ulong address = item.address; ulong address = item.address;
ExecutionMode executionMode = item.funcProfile.Mode; ExecutionMode executionMode = item.funcProfile.Mode;
@@ -865,11 +860,11 @@ namespace ARMeilleure.Translation.PTC
Stopwatch sw = Stopwatch.StartNew(); Stopwatch sw = Stopwatch.StartNew();
foreach (Thread thread in threads) foreach (var thread in threads)
{ {
thread.Start(); thread.Start();
} }
foreach (Thread thread in threads) foreach (var thread in threads)
{ {
thread.Join(); thread.Join();
} }
@@ -949,7 +944,7 @@ namespace ARMeilleure.Translation.PTC
WriteCode(code.AsSpan()); WriteCode(code.AsSpan());
// WriteReloc. // WriteReloc.
using BinaryWriter relocInfoWriter = new(_relocsStream, EncodingCache.UTF8NoBOM, true); using var relocInfoWriter = new BinaryWriter(_relocsStream, EncodingCache.UTF8NoBOM, true);
foreach (RelocEntry entry in relocInfo.Entries) foreach (RelocEntry entry in relocInfo.Entries)
{ {
@@ -959,7 +954,7 @@ namespace ARMeilleure.Translation.PTC
} }
// WriteUnwindInfo. // WriteUnwindInfo.
using BinaryWriter unwindInfoWriter = new(_unwindInfosStream, EncodingCache.UTF8NoBOM, true); using var unwindInfoWriter = new BinaryWriter(_unwindInfosStream, EncodingCache.UTF8NoBOM, true);
unwindInfoWriter.Write(unwindInfo.PushEntries.Length); unwindInfoWriter.Write(unwindInfo.PushEntries.Length);
@@ -1030,7 +1025,7 @@ namespace ARMeilleure.Translation.PTC
return osPlatform; return osPlatform;
} }
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 86*/)] [StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 87*/)]
private struct OuterHeader private struct OuterHeader
{ {
public ulong Magic; public ulong Magic;
@@ -1042,6 +1037,7 @@ namespace ARMeilleure.Translation.PTC
public byte MemoryManagerMode; public byte MemoryManagerMode;
public uint OSPlatform; public uint OSPlatform;
public uint Architecture; public uint Architecture;
public bool DebuggerMode;
public long UncompressedStreamSize; public long UncompressedStreamSize;
@@ -1,37 +0,0 @@
namespace ARMeilleure.Translation.PTC
{
public readonly struct PtcCacheInfo
{
public const string TitleIdTextDefault = "0000000000000000";
public const string ApplicationIdTextDefault = "0000000000000000";
public const string DisplayVersionDefault = "0";
public ulong ProcessId { get; }
public string TitleIdText { get; }
public string ApplicationIdText { get; }
public byte ProgramIndex { get; }
public string DisplayVersion { get; }
public string ProcessKind { get; }
public string CacheSelector { get; }
public string CacheKey => $"{DisplayVersion}-{CacheSelector}";
public PtcCacheInfo(
ulong processId,
string titleIdText,
string applicationIdText,
byte programIndex,
string displayVersion,
string processKind,
string cacheSelector)
{
ProcessId = processId;
TitleIdText = !string.IsNullOrEmpty(titleIdText) ? titleIdText : TitleIdTextDefault;
ApplicationIdText = !string.IsNullOrEmpty(applicationIdText) ? applicationIdText : ApplicationIdTextDefault;
ProgramIndex = programIndex;
DisplayVersion = !string.IsNullOrEmpty(displayVersion) ? displayVersion : DisplayVersionDefault;
ProcessKind = processKind ?? string.Empty;
CacheSelector = string.IsNullOrEmpty(cacheSelector) ? "default" : cacheSelector;
}
}
}
+7 -16
View File
@@ -9,13 +9,13 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.IO.Compression; using System.IO.Compression;
using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using System.Timers; using System.Timers;
using static ARMeilleure.Translation.PTC.PtcFormatter; using static ARMeilleure.Translation.PTC.PtcFormatter;
using Timer = System.Timers.Timer; using Timer = System.Timers.Timer;
using System.Linq;
namespace ARMeilleure.Translation.PTC namespace ARMeilleure.Translation.PTC
{ {
@@ -23,7 +23,7 @@ namespace ARMeilleure.Translation.PTC
{ {
private const string OuterHeaderMagicString = "Pohd\0\0\0\0"; private const string OuterHeaderMagicString = "Pohd\0\0\0\0";
private const uint InternalVersion = 7031; //! Not to be incremented manually for each change to the ARMeilleure project. private const uint InternalVersion = 6698; //! Not to be incremented manually for each change to the ARMeilleure project.
private static readonly uint[] _migrateInternalVersions = private static readonly uint[] _migrateInternalVersions =
[ [
@@ -119,9 +119,9 @@ namespace ARMeilleure.Translation.PTC
public ConcurrentQueue<(ulong address, FuncProfile funcProfile)> GetProfiledFuncsToTranslate(TranslatorCache<TranslatedFunction> funcs) public ConcurrentQueue<(ulong address, FuncProfile funcProfile)> GetProfiledFuncsToTranslate(TranslatorCache<TranslatedFunction> funcs)
{ {
ConcurrentQueue<(ulong address, FuncProfile funcProfile)> profiledFuncsToTranslate = new(); var profiledFuncsToTranslate = new ConcurrentQueue<(ulong address, FuncProfile funcProfile)>();
foreach (KeyValuePair<ulong, FuncProfile> profiledFunc in ProfiledFuncs) foreach (var profiledFunc in ProfiledFuncs)
{ {
if (!funcs.ContainsKey(profiledFunc.Key) && !profiledFunc.Value.Blacklist) if (!funcs.ContainsKey(profiledFunc.Key) && !profiledFunc.Value.Blacklist)
{ {
@@ -142,7 +142,7 @@ namespace ARMeilleure.Translation.PTC
{ {
List<ulong> funcs = []; List<ulong> funcs = [];
foreach (KeyValuePair<ulong, FuncProfile> profiledFunc in ProfiledFuncs) foreach (var profiledFunc in ProfiledFuncs)
{ {
if (profiledFunc.Value.Blacklist) if (profiledFunc.Value.Blacklist)
{ {
@@ -254,12 +254,7 @@ namespace ARMeilleure.Translation.PTC
long fileSize = new FileInfo(fileName).Length; long fileSize = new FileInfo(fileName).Length;
Logger.Info?.Print( Logger.Info?.Print(LogClass.Ptc, $"{(isBackup ? "Loaded Backup Profiling Info" : "Loaded Profiling Info")} (size: {fileSize} bytes, profiled functions: {ProfiledFuncs.Count}).");
LogClass.Ptc,
$"{(isBackup ? "Loaded Backup Profiling Info" : "Loaded Profiling Info")} " +
$"(pid: {_ptc.CacheInfo.ProcessId}, title: {_ptc.CacheInfo.TitleIdText}, version: '{_ptc.CacheInfo.DisplayVersion}', " +
$"kind: {_ptc.CacheInfo.ProcessKind}, selector: '{_ptc.CacheInfo.CacheSelector}', key: '{_ptc.CacheInfo.CacheKey}', " +
$"path: '{fileName}', size: {fileSize} bytes, profiled functions: {ProfiledFuncs.Count}).");
return true; return true;
} }
@@ -380,11 +375,7 @@ namespace ARMeilleure.Translation.PTC
if (fileSize != 0L) if (fileSize != 0L)
{ {
Logger.Info?.Print( Logger.Info?.Print(LogClass.Ptc, $"Saved Profiling Info (size: {fileSize} bytes, profiled functions: {profiledFuncsCount}).");
LogClass.Ptc,
$"Saved Profiling Info (pid: {_ptc.CacheInfo.ProcessId}, title: {_ptc.CacheInfo.TitleIdText}, version: '{_ptc.CacheInfo.DisplayVersion}', " +
$"kind: {_ptc.CacheInfo.ProcessKind}, selector: '{_ptc.CacheInfo.CacheSelector}', key: '{_ptc.CacheInfo.CacheKey}', " +
$"path: '{fileName}', size: {fileSize} bytes, profiled functions: {profiledFuncsCount}).");
} }
} }
@@ -44,10 +44,10 @@ namespace ARMeilleure.Translation
public static void Construct(ControlFlowGraph cfg) public static void Construct(ControlFlowGraph cfg)
{ {
DefMap[] globalDefs = new DefMap[cfg.Blocks.Count]; var globalDefs = new DefMap[cfg.Blocks.Count];
Operand[] localDefs = new Operand[cfg.LocalsCount + RegisterConsts.TotalCount]; var localDefs = new Operand[cfg.LocalsCount + RegisterConsts.TotalCount];
Queue<BasicBlock> dfPhiBlocks = new(); var dfPhiBlocks = new Queue<BasicBlock>();
for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext) for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext)
{ {
@@ -1,4 +1,5 @@
using ARMeilleure.Common; using ARMeilleure.Common;
using System;
namespace ARMeilleure.Translation namespace ARMeilleure.Translation
{ {
@@ -6,12 +7,12 @@ namespace ARMeilleure.Translation
{ {
private readonly GuestFunction _func; // Ensure that this delegate will not be garbage collected. private readonly GuestFunction _func; // Ensure that this delegate will not be garbage collected.
public nint FuncPointer { get; } public IntPtr FuncPointer { get; }
public Counter<uint> CallCounter { get; } public Counter<uint> CallCounter { get; }
public ulong GuestSize { get; } public ulong GuestSize { get; }
public bool HighCq { get; } public bool HighCq { get; }
public TranslatedFunction(GuestFunction func, nint funcPointer, Counter<uint> callCounter, ulong guestSize, bool highCq) public TranslatedFunction(GuestFunction func, IntPtr funcPointer, Counter<uint> callCounter, ulong guestSize, bool highCq)
{ {
_func = func; _func = func;
FuncPointer = funcPointer; FuncPointer = funcPointer;
+54 -16
View File
@@ -57,9 +57,9 @@ namespace ARMeilleure.Translation
FunctionTable.Fill = (ulong)Stubs.SlowDispatchStub; FunctionTable.Fill = (ulong)Stubs.SlowDispatchStub;
} }
public IPtcLoadState LoadDiskCache(PtcCacheInfo cacheInfo, bool enabled) public IPtcLoadState LoadDiskCache(string titleIdText, string displayVersion, bool enabled, string cacheSelector)
{ {
_ptc.Initialize(cacheInfo, enabled, Memory.Type); _ptc.Initialize(titleIdText, displayVersion, enabled, Memory.Type, cacheSelector);
return _ptc; return _ptc;
} }
@@ -119,7 +119,25 @@ namespace ARMeilleure.Translation
NativeInterface.RegisterThread(context, Memory, this); NativeInterface.RegisterThread(context, Memory, this);
if (Optimizations.UseUnmanagedDispatchLoop) if (Optimizations.EnableDebugging)
{
context.DebugPc = address;
do
{
if (Interlocked.CompareExchange(ref context.ShouldStep, 0, 1) == 1)
{
context.DebugPc = Step(context, context.DebugPc);
context.StepHandler();
}
else
{
context.DebugPc = ExecuteSingle(context, context.DebugPc);
}
context.CheckInterrupt();
}
while (context.Running && context.DebugPc != 0);
}
else if (Optimizations.UseUnmanagedDispatchLoop)
{ {
Stubs.DispatchLoop(context.NativeContextPtr, address); Stubs.DispatchLoop(context.NativeContextPtr, address);
} }
@@ -176,7 +194,7 @@ namespace ARMeilleure.Translation
return nextAddr; return nextAddr;
} }
public ulong Step(State.ExecutionContext context, ulong address) private ulong Step(State.ExecutionContext context, ulong address)
{ {
TranslatedFunction func = Translate(address, context.ExecutionMode, highCq: false, singleStep: true); TranslatedFunction func = Translate(address, context.ExecutionMode, highCq: false, singleStep: true);
@@ -187,6 +205,8 @@ namespace ARMeilleure.Translation
return address; return address;
} }
internal TranslatedFunction GetOrTranslate(ulong address, ExecutionMode mode) internal TranslatedFunction GetOrTranslate(ulong address, ExecutionMode mode)
{ {
if (!Functions.TryGetValue(address, out TranslatedFunction func)) if (!Functions.TryGetValue(address, out TranslatedFunction func))
@@ -222,7 +242,7 @@ namespace ARMeilleure.Translation
internal TranslatedFunction Translate(ulong address, ExecutionMode mode, bool highCq, bool singleStep = false, bool pptcTranslation = false) internal TranslatedFunction Translate(ulong address, ExecutionMode mode, bool highCq, bool singleStep = false, bool pptcTranslation = false)
{ {
ArmEmitterContext context = new( var context = new ArmEmitterContext(
Memory, Memory,
CountTable, CountTable,
FunctionTable, FunctionTable,
@@ -230,7 +250,8 @@ namespace ARMeilleure.Translation
address, address,
highCq, highCq,
_ptc.State != PtcState.Disabled, _ptc.State != PtcState.Disabled,
mode: Aarch32Mode.User); mode: Aarch32Mode.User,
isSingleStep: singleStep);
Logger.StartPass(PassName.Decoding); Logger.StartPass(PassName.Decoding);
@@ -265,10 +286,10 @@ namespace ARMeilleure.Translation
Logger.EndPass(PassName.RegisterUsage); Logger.EndPass(PassName.RegisterUsage);
OperandType retType = OperandType.I64; var retType = OperandType.I64;
OperandType[] argTypes = new OperandType[] { OperandType.I64 }; var argTypes = new OperandType[] { OperandType.I64 };
CompilerOptions options = highCq ? CompilerOptions.HighCq : CompilerOptions.None; var options = highCq ? CompilerOptions.HighCq : CompilerOptions.None;
if (context.HasPtc && !singleStep) if (context.HasPtc && !singleStep)
{ {
@@ -284,7 +305,7 @@ namespace ARMeilleure.Translation
_ptc.WriteCompiledFunction(address, funcSize, hash, highCq, compiledFunc); _ptc.WriteCompiledFunction(address, funcSize, hash, highCq, compiledFunc);
} }
GuestFunction func = compiledFunc.MapWithPointer<GuestFunction>(out nint funcPointer); GuestFunction func = compiledFunc.MapWithPointer<GuestFunction>(out IntPtr funcPointer);
Allocators.ResetAll(); Allocators.ResetAll();
@@ -369,9 +390,13 @@ namespace ARMeilleure.Translation
if (block.Exit) if (block.Exit)
{ {
// Left option here as it may be useful if we need to return to managed rather than tail call in // Return to managed rather than tail call.
// future. (eg. for debug) bool useReturns = Optimizations.EnableDebugging;
bool useReturns = false;
if (Optimizations.EnableDebugging)
{
EmitDebugPrecisePcUpdate(context, block.Address);
}
InstEmitFlowHelper.EmitVirtualJump(context, Const(block.Address), isReturn: useReturns); InstEmitFlowHelper.EmitVirtualJump(context, Const(block.Address), isReturn: useReturns);
} }
@@ -395,6 +420,11 @@ namespace ARMeilleure.Translation
} }
} }
if (Optimizations.EnableDebugging)
{
EmitDebugPrecisePcUpdate(context, opCode.Address);
}
Operand lblPredicateSkip = default; Operand lblPredicateSkip = default;
if (context.IsInIfThenBlock && context.CurrentIfThenBlockCond != Condition.Al) if (context.IsInIfThenBlock && context.CurrentIfThenBlockCond != Condition.Al)
@@ -491,6 +521,14 @@ namespace ARMeilleure.Translation
context.MarkLabel(lblExit); context.MarkLabel(lblExit);
} }
internal static void EmitDebugPrecisePcUpdate(EmitterContext context, ulong address)
{
long debugPrecisePcOffs = NativeContext.GetDebugPrecisePcOffset();
Operand debugPrecisePcAddr = context.Add(context.LoadArgument(OperandType.I64, 0), Const(debugPrecisePcOffs));
context.Store(debugPrecisePcAddr, Const(address));
}
public void InvalidateJitCacheRegion(ulong address, ulong size) public void InvalidateJitCacheRegion(ulong address, ulong size)
{ {
ulong[] overlapAddresses = []; ulong[] overlapAddresses = [];
@@ -536,7 +574,7 @@ namespace ARMeilleure.Translation
List<TranslatedFunction> functions = Functions.AsList(); List<TranslatedFunction> functions = Functions.AsList();
foreach (TranslatedFunction func in functions) foreach (var func in functions)
{ {
JitCache.Unmap(func.FuncPointer); JitCache.Unmap(func.FuncPointer);
@@ -545,7 +583,7 @@ namespace ARMeilleure.Translation
Functions.Clear(); Functions.Clear();
while (_oldFuncs.TryDequeue(out KeyValuePair<ulong, TranslatedFunction> kv)) while (_oldFuncs.TryDequeue(out var kv))
{ {
JitCache.Unmap(kv.Value.FuncPointer); JitCache.Unmap(kv.Value.FuncPointer);
@@ -566,7 +604,7 @@ namespace ARMeilleure.Translation
{ {
while (Queue.Count > 0 && Queue.TryDequeue(out RejitRequest request)) while (Queue.Count > 0 && Queue.TryDequeue(out RejitRequest request))
{ {
if (Functions.TryGetValue(request.Address, out TranslatedFunction func) && func.CallCounter != null) if (Functions.TryGetValue(request.Address, out var func) && func.CallCounter != null)
{ {
Volatile.Write(ref func.CallCounter.Value, 0); Volatile.Write(ref func.CallCounter.Value, 0);
} }
+24 -24
View File
@@ -14,7 +14,7 @@ namespace ARMeilleure.Translation
/// </summary> /// </summary>
class TranslatorStubs : IDisposable class TranslatorStubs : IDisposable
{ {
private readonly Lazy<nint> _slowDispatchStub; private readonly Lazy<IntPtr> _slowDispatchStub;
private bool _disposed; private bool _disposed;
@@ -27,7 +27,7 @@ namespace ARMeilleure.Translation
/// Gets the dispatch stub. /// Gets the dispatch stub.
/// </summary> /// </summary>
/// <exception cref="ObjectDisposedException"><see cref="TranslatorStubs"/> instance was disposed</exception> /// <exception cref="ObjectDisposedException"><see cref="TranslatorStubs"/> instance was disposed</exception>
public nint DispatchStub public IntPtr DispatchStub
{ {
get get
{ {
@@ -41,7 +41,7 @@ namespace ARMeilleure.Translation
/// Gets the slow dispatch stub. /// Gets the slow dispatch stub.
/// </summary> /// </summary>
/// <exception cref="ObjectDisposedException"><see cref="TranslatorStubs"/> instance was disposed</exception> /// <exception cref="ObjectDisposedException"><see cref="TranslatorStubs"/> instance was disposed</exception>
public nint SlowDispatchStub public IntPtr SlowDispatchStub
{ {
get get
{ {
@@ -139,9 +139,9 @@ namespace ARMeilleure.Translation
/// Generates a <see cref="DispatchStub"/>. /// Generates a <see cref="DispatchStub"/>.
/// </summary> /// </summary>
/// <returns>Generated <see cref="DispatchStub"/></returns> /// <returns>Generated <see cref="DispatchStub"/></returns>
private nint GenerateDispatchStub() private IntPtr GenerateDispatchStub()
{ {
EmitterContext context = new(); var context = new EmitterContext();
Operand lblFallback = Label(); Operand lblFallback = Label();
Operand lblEnd = Label(); Operand lblEnd = Label();
@@ -160,7 +160,7 @@ namespace ARMeilleure.Translation
for (int i = 0; i < _functionTable.Levels.Length; i++) for (int i = 0; i < _functionTable.Levels.Length; i++)
{ {
ref AddressTableLevel level = ref _functionTable.Levels[i]; ref var level = ref _functionTable.Levels[i];
// level.Mask is not used directly because it is more often bigger than 32-bits, so it will not // level.Mask is not used directly because it is more often bigger than 32-bits, so it will not
// be encoded as an immediate on x86's bitwise and operation. // be encoded as an immediate on x86's bitwise and operation.
@@ -184,11 +184,11 @@ namespace ARMeilleure.Translation
hostAddress = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress); hostAddress = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress);
context.Tailcall(hostAddress, nativeContext); context.Tailcall(hostAddress, nativeContext);
ControlFlowGraph cfg = context.GetControlFlowGraph(); var cfg = context.GetControlFlowGraph();
OperandType retType = OperandType.I64; var retType = OperandType.I64;
OperandType[] argTypes = new[] { OperandType.I64 }; var argTypes = new[] { OperandType.I64 };
GuestFunction func = Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<GuestFunction>(); var func = Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<GuestFunction>();
return Marshal.GetFunctionPointerForDelegate(func); return Marshal.GetFunctionPointerForDelegate(func);
} }
@@ -197,9 +197,9 @@ namespace ARMeilleure.Translation
/// Generates a <see cref="SlowDispatchStub"/>. /// Generates a <see cref="SlowDispatchStub"/>.
/// </summary> /// </summary>
/// <returns>Generated <see cref="SlowDispatchStub"/></returns> /// <returns>Generated <see cref="SlowDispatchStub"/></returns>
private nint GenerateSlowDispatchStub() private IntPtr GenerateSlowDispatchStub()
{ {
EmitterContext context = new(); var context = new EmitterContext();
// Load the target guest address from the native context. // Load the target guest address from the native context.
Operand nativeContext = context.LoadArgument(OperandType.I64, 0); Operand nativeContext = context.LoadArgument(OperandType.I64, 0);
@@ -209,11 +209,11 @@ namespace ARMeilleure.Translation
Operand hostAddress = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress); Operand hostAddress = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress);
context.Tailcall(hostAddress, nativeContext); context.Tailcall(hostAddress, nativeContext);
ControlFlowGraph cfg = context.GetControlFlowGraph(); var cfg = context.GetControlFlowGraph();
OperandType retType = OperandType.I64; var retType = OperandType.I64;
OperandType[] argTypes = new[] { OperandType.I64 }; var argTypes = new[] { OperandType.I64 };
GuestFunction func = Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<GuestFunction>(); var func = Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<GuestFunction>();
return Marshal.GetFunctionPointerForDelegate(func); return Marshal.GetFunctionPointerForDelegate(func);
} }
@@ -250,7 +250,7 @@ namespace ARMeilleure.Translation
/// <returns><see cref="DispatchLoop"/> function</returns> /// <returns><see cref="DispatchLoop"/> function</returns>
private DispatcherFunction GenerateDispatchLoop() private DispatcherFunction GenerateDispatchLoop()
{ {
EmitterContext context = new(); var context = new EmitterContext();
Operand beginLbl = Label(); Operand beginLbl = Label();
Operand endLbl = Label(); Operand endLbl = Label();
@@ -286,9 +286,9 @@ namespace ARMeilleure.Translation
context.Return(); context.Return();
ControlFlowGraph cfg = context.GetControlFlowGraph(); var cfg = context.GetControlFlowGraph();
OperandType retType = OperandType.None; var retType = OperandType.None;
OperandType[] argTypes = new[] { OperandType.I64, OperandType.I64 }; var argTypes = new[] { OperandType.I64, OperandType.I64 };
return Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<DispatcherFunction>(); return Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<DispatcherFunction>();
} }
@@ -299,7 +299,7 @@ namespace ARMeilleure.Translation
/// <returns><see cref="ContextWrapper"/> function</returns> /// <returns><see cref="ContextWrapper"/> function</returns>
private WrapperFunction GenerateContextWrapper() private WrapperFunction GenerateContextWrapper()
{ {
EmitterContext context = new(); var context = new EmitterContext();
Operand nativeContext = context.LoadArgument(OperandType.I64, 0); Operand nativeContext = context.LoadArgument(OperandType.I64, 0);
Operand guestMethod = context.LoadArgument(OperandType.I64, 1); Operand guestMethod = context.LoadArgument(OperandType.I64, 1);
@@ -310,9 +310,9 @@ namespace ARMeilleure.Translation
context.Return(returnValue); context.Return(returnValue);
ControlFlowGraph cfg = context.GetControlFlowGraph(); var cfg = context.GetControlFlowGraph();
OperandType retType = OperandType.I64; var retType = OperandType.I64;
OperandType[] argTypes = new[] { OperandType.I64, OperandType.I64 }; var argTypes = new[] { OperandType.I64, OperandType.I64 };
return Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<WrapperFunction>(); return Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<WrapperFunction>();
} }
@@ -9,7 +9,7 @@ namespace ARMeilleure.Translation
{ {
public static class TranslatorTestMethods public static class TranslatorTestMethods
{ {
public delegate int FpFlagsPInvokeTest(nint managedMethod); public delegate int FpFlagsPInvokeTest(IntPtr managedMethod);
private static bool SetPlatformFtz(EmitterContext context, bool ftz) private static bool SetPlatformFtz(EmitterContext context, bool ftz)
{ {
-12
View File
@@ -1,12 +0,0 @@
.idea/
*.iml
.gradle
local.properties
.DS_Store
build/
captures
.externalNativeBuild
.cxx/
app/src/main/jniLibs/arm64-v8a/**
!app/src/main/jniLibs/arm64-v8a/.gitkeep
-175
View File
@@ -1,175 +0,0 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.plugin.compose'
}
android {
namespace = 'org.kenjinx.android'
compileSdk 37
defaultConfig {
applicationId "org.kenjinx.android"
minSdk 29
targetSdk 37
versionCode 20100
versionName '2.1.0-pr.2'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
ndk {
//noinspection ChromeOsAbiSupport
abiFilters 'arm64-v8a'
}
externalNativeBuild {
cmake {
cppFlags "-std=c++20 -O3",
"-fno-math-errno -fno-trapping-math -fno-signed-zeros -ffinite-math-only"
arguments "-DANDROID_STL=c++_shared",
"-DCMAKE_BUILD_TYPE=Release",
"-DANDROID_ARM_NEON=TRUE",
"-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
}
}
}
buildTypes {
release {
// minifyEnabled false
// proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig = signingConfigs.debug
debuggable false
jniDebuggable false
}
}
def deviceFlavors = [
armv8 : "-march=armv8-a",
armv82 : "-march=armv8.2-a",
armv87 : "-march=armv8.7-a",
sd8eg5 : "-march=armv8.7-a+sve+sve2",
]
flavorDimensions "appid", "device"
productFlavors {
mainline {
dimension "appid"
applicationId "org.kenjinx.android"
manifestPlaceholders = [applicationLabel: "@string/app_name"]
}
optimized {
dimension "appid"
applicationId "com.garena.game.codm"
manifestPlaceholders = [applicationLabel: "@string/app_name_optimized"]
}
}
deviceFlavors.each { name, flags ->
productFlavors.create(name) {
dimension "device"
externalNativeBuild {
cmake {
cppFlags flags
}
}
}
}
androidComponents {
onVariants(selector().withBuildType("debug")) {
packaging.dex.useLegacyPackaging.set(false)
}
beforeVariants(selector().all()) { variant ->
def flavors = variant.productFlavors.collect { it.second }.toSet()
def invalidCombos = [
["optimized", "armv8"],
["optimized", "armv87"],
["optimized", "sd8eg5"]
]
if (invalidCombos.any { combo -> flavors.containsAll(combo) }) {
enable = false
}
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_21
targetCompatibility JavaVersion.VERSION_21
}
buildFeatures {
compose = true
prefab = true
buildConfig = true
}
packagingOptions {
jniLibs {
keepDebugSymbols += '**/libkenjinx.so'
useLegacyPackaging true
}
dex {
useLegacyPackaging true
}
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
externalNativeBuild {
cmake {
path file('src/main/cpp/CMakeLists.txt')
version = '4.1.2'
}
}
sourceSets {
main {
jniLibs.srcDirs = ['src/main/extLibs', 'src/main/jniLibs']
}
}
}
tasks.named("preBuild") {
dependsOn ':libkenjinx:assemble'
}
dependencies {
runtimeOnly project(":libkenjinx")
implementation 'androidx.activity:activity-compose:1.13.0'
implementation 'androidx.appcompat:appcompat:1.8.0'
implementation 'androidx.compose.material3:material3'
implementation 'androidx.compose.material:material-icons-extended:1.7.8'
implementation 'androidx.compose.ui:ui'
implementation 'androidx.compose.ui:ui-graphics'
implementation 'androidx.compose.ui:ui-tooling-preview'
implementation 'androidx.constraintlayout:constraintlayout:2.2.2'
implementation 'androidx.core:core-ktx:1.19.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.11.0'
implementation 'androidx.navigation:navigation-compose:2.9.8'
implementation 'androidx.preference:preference-ktx:1.2.1'
implementation 'br.com.devsrsouza.compose.icons:css-gg:1.1.1'
implementation 'com.anggrayudi:storage:2.2.0'
implementation 'com.github.swordfish90:radialgamepad:2.0.0'
implementation 'com.google.android.material:material:1.14.0'
implementation 'com.google.code.gson:gson:2.14.0'
implementation 'com.halilibo.compose-richtext:richtext-commonmark:0.20.0'
implementation 'com.halilibo.compose-richtext:richtext-ui-material3:0.20.0'
implementation 'com.halilibo.compose-richtext:richtext-ui:0.20.0'
implementation 'io.coil-kt:coil-compose:2.7.0'
implementation 'net.java.dev.jna:jna:5.19.1@aar'
implementation 'net.lingala.zip4j:zip4j:2.11.6'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.11.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.11.0'
implementation platform('androidx.compose:compose-bom:2026.08.00')
implementation platform('org.jetbrains.kotlin:kotlin-bom:2.3.10')
androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.7.0'
androidTestImplementation 'androidx.test.ext:junit:1.3.0'
androidTestImplementation platform('androidx.compose:compose-bom:2026.08.00')
testImplementation 'junit:junit:4.13.2'
debugImplementation 'androidx.compose.ui:ui-test-manifest'
debugImplementation 'androidx.compose.ui:ui-tooling'
}
-37
View File
@@ -1,37 +0,0 @@
-optimizationpasses 5
-optimizations !code/simplification/arithmetic
-optimizations !code/simplification/cast
-optimizations !field/*
-optimizations !class/merging/*
-optimizations !method/inlining/short
-optimizations !method/inlining/unique
-optimizations method/inlining/tailrecursion
-optimizations method/removal/parameter
-optimizations code/merging
-optimizations code/simplification/variable
-allowaccessmodification
-repackageclasses ''
-keepattributes Exceptions,InnerClasses,Signature,*Annotation*
-dontpreverify
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends androidx.fragment.app.Fragment
-dontwarn java.awt.Component
-dontwarn java.awt.GraphicsEnvironment
-dontwarn java.awt.HeadlessException
-dontwarn java.awt.Window
-dontwarn javax.lang.model.element.Modifier
-assumenosideeffects class java.lang.Math {
public static double random();
public static double sin(...);
public static double cos(...);
public static double sqrt(...);
}
-assumenosideeffects public class ** {
public boolean is*();
public boolean get*();
public boolean has*();
}
@@ -1,116 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- Android 11+ Package Visibility: What this app is allowed to see/access -->
<queries>
<!-- If other flavors/starters are involved, make them visible here -->
<package android:name="org.kenjinx.android"/>
<!-- General: Make LAUNCHER activities and ACTION_VIEW files resolvable -->
<intent>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent>
</queries>
<uses-feature
android:name="android.hardware.audio.output"
android:required="true" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission
android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Notifications + special-use Foreground Service (Android 14+) -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!-- Required for startForeground() -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<application
android:name=".KenjinxApplication"
android:allowBackup="true"
android:appCategory="game"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:isGame="true"
android:label="${applicationLabel}"
android:supportsRtl="true"
android:theme="@style/Theme.KenjinxAndroid"
android:largeHeap="true"
android:requestLegacyExternalStorage="true"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:exported="true"
android:screenOrientation="unspecified"
android:resizeableActivity="true"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|uiMode"
android:hardwareAccelerated="true"
android:theme="@style/Theme.KenjinxAndroid">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="org.kenjinx.android.LAUNCH_GAME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<!--
<intent-filter>
<action android:name="org.kenji.android.action.CREATE_SHORTCUT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
-->
<!-- Shortcut Wizard Activity (transparent, freely rotatable) -->
<activity
android:name=".ShortcutWizardActivity"
android:exported="false"
android:theme="@style/Theme.KenjinxAndroid.Transparent"
android:screenOrientation="unspecified"
android:configChanges="orientation|screenSize|keyboardHidden|uiMode" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
<provider
android:name=".providers.DocumentProvider"
android:authorities="${applicationId}.providers"
android:exported="true"
android:grantUriPermissions="true"
android:permission="android.permission.MANAGE_DOCUMENTS">
<intent-filter>
<action android:name="android.content.action.DOCUMENTS_PROVIDER" />
</intent-filter>
</provider>
<service
android:name=".service.EmulationService"
android:exported="false"
android:stopWithTask="true"
android:foregroundServiceType="mediaPlayback" />
</application>
</manifest>
@@ -1,80 +0,0 @@
include(FetchContent)
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.31.5)
# Declares and names the project.
project("kenjinxjni")
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
FetchContent_Declare(
adrenotools
GIT_REPOSITORY https://github.com/bylaws/libadrenotools.git
GIT_TAG 8fae8ce254dfc1344527e05301e43f37dea2df80
)
FetchContent_MakeAvailable(adrenotools)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
add_library( # Sets the name of the library.
kenjinxjni
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
vulkan_wrapper.cpp
kenjinx.cpp)
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
kenjinxjni
# Links the target library to the log library
# included in the NDK.
${log-lib}
-lvulkan
-landroid
adrenotools
)
# Build external libraries if prebuilt files don't exist
set(JNI_PATH ../jniLibs/${CMAKE_ANDROID_ARCH_ABI})
cmake_path(ABSOLUTE_PATH JNI_PATH NORMALIZE)
cmake_path(APPEND JNI_PATH libcrypto.so OUTPUT_VARIABLE LIBCRYPTO_JNI_PATH)
cmake_path(APPEND JNI_PATH libssl.so OUTPUT_VARIABLE LIBSSL_JNI_PATH)
# Add OpenAL
add_subdirectory(libraries/openal)
set_target_properties(OpenAL PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${JNI_PATH}
ARCHIVE_OUTPUT_DIRECTORY ${JNI_PATH}
RUNTIME_OUTPUT_DIRECTORY ${JNI_PATH}
)
@@ -1,254 +0,0 @@
// Write C++ code here.
//
// Do not forget to dynamically load the C++ library into your application.
//
// For instance,
//
// In MainActivity.java:
// static {
// System.loadLibrary("kenjinxjni");
// }
//
// Or, in MainActivity.kt:
// companion object {
// init {
// System.loadLibrary("kenjinxjni")
// }
// }
#include "kenjinx.h"
#include "pthread.h"
#include <chrono>
#include <csignal>
std::chrono::time_point<std::chrono::steady_clock, std::chrono::nanoseconds> _currentTimePoint;
extern "C"
{
JNIEXPORT jlong JNICALL
Java_org_kenjinx_android_NativeHelpers_getNativeWindow(
JNIEnv *env,
jobject instance,
jobject surface) {
auto nativeWindow = ANativeWindow_fromSurface(env, surface);
return nativeWindow == nullptr ? -1 : (jlong) nativeWindow;
}
JNIEXPORT void JNICALL
Java_org_kenjinx_android_NativeHelpers_releaseNativeWindow(
JNIEnv *env,
jobject instance,
jlong window) {
auto nativeWindow = (ANativeWindow *) window;
if (nativeWindow != nullptr)
ANativeWindow_release(nativeWindow);
}
long createSurface(long native_surface, long instance) {
auto nativeWindow = (ANativeWindow *) native_surface;
VkSurfaceKHR surface;
auto vkInstance = (VkInstance) instance;
auto fpCreateAndroidSurfaceKHR =
reinterpret_cast<PFN_vkCreateAndroidSurfaceKHR>(vkGetInstanceProcAddr(vkInstance,
"vkCreateAndroidSurfaceKHR"));
if (fpCreateAndroidSurfaceKHR == nullptr)
LOGE("Could not get function pointer to CreateAndroidSurfaceKHR");
VkAndroidSurfaceCreateInfoKHR info;
info.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
info.pNext = nullptr;
info.flags = 0;
info.window = nativeWindow;
VK_CHECK(fpCreateAndroidSurfaceKHR(vkInstance, &info, nullptr, &surface));
return (long) surface;
}
JNIEXPORT jlong JNICALL
Java_org_kenjinx_android_NativeHelpers_getCreateSurfacePtr(
JNIEnv *env,
jobject instance) {
return (jlong) createSurface;
}
char *getStringPointer(
JNIEnv *env,
jstring jS) {
const char *cparam = env->GetStringUTFChars(jS, nullptr);
auto len = env->GetStringUTFLength(jS);
char *s = new char[len + 1]; //null terminator
strcpy(s, cparam);
env->ReleaseStringUTFChars(jS, cparam);
return s;
}
jstring createString(
JNIEnv *env,
char *ch) {
auto str = env->NewStringUTF(ch);
return str;
}
jstring createStringFromStdString(
JNIEnv *env,
std::string s) {
auto str = env->NewStringUTF(s.c_str());
return str;
}
}
extern "C"
void setRenderingThread() {
auto currentId = pthread_self();
_renderingThreadId = currentId;
_currentTimePoint = std::chrono::high_resolution_clock::now();
}
extern "C"
JNIEXPORT void JNICALL
Java_org_kenjinx_android_MainActivity_initVm(JNIEnv *env, jobject thiz) {
JavaVM *vm = nullptr;
env->GetJavaVM(&vm);
_vm = vm;
_mainActivity = thiz;
_mainActivityClass = env->GetObjectClass(thiz);
}
bool isInitialOrientationFlipped = true;
extern "C"
void setCurrentTransform(long native_window, int transform) {
if (native_window == 0 || native_window == -1)
return;
auto nativeWindow = (ANativeWindow *) native_window;
auto nativeTransform = ANativeWindowTransform::ANATIVEWINDOW_TRANSFORM_IDENTITY;
transform = transform >> 1;
// transform is a valid VkSurfaceTransformFlagBitsKHR
switch (transform) {
case 0x1:
nativeTransform = ANativeWindowTransform::ANATIVEWINDOW_TRANSFORM_IDENTITY;
break;
case 0x2:
nativeTransform = ANativeWindowTransform::ANATIVEWINDOW_TRANSFORM_ROTATE_90;
break;
case 0x4:
nativeTransform = isInitialOrientationFlipped
? ANativeWindowTransform::ANATIVEWINDOW_TRANSFORM_IDENTITY
: ANativeWindowTransform::ANATIVEWINDOW_TRANSFORM_ROTATE_180;
break;
case 0x8:
nativeTransform = ANativeWindowTransform::ANATIVEWINDOW_TRANSFORM_ROTATE_270;
break;
case 0x10:
nativeTransform = ANativeWindowTransform::ANATIVEWINDOW_TRANSFORM_MIRROR_HORIZONTAL;
break;
case 0x20:
nativeTransform = static_cast<ANativeWindowTransform>(
ANativeWindowTransform::ANATIVEWINDOW_TRANSFORM_MIRROR_HORIZONTAL |
ANATIVEWINDOW_TRANSFORM_ROTATE_90);
break;
case 0x40:
nativeTransform = ANativeWindowTransform::ANATIVEWINDOW_TRANSFORM_MIRROR_VERTICAL;
break;
case 0x80:
nativeTransform = static_cast<ANativeWindowTransform>(
ANativeWindowTransform::ANATIVEWINDOW_TRANSFORM_MIRROR_VERTICAL |
ANATIVEWINDOW_TRANSFORM_ROTATE_90);
break;
case 0x100:
nativeTransform = ANativeWindowTransform::ANATIVEWINDOW_TRANSFORM_IDENTITY;
break;
}
nativeWindow->perform(nativeWindow, NATIVE_WINDOW_SET_BUFFERS_TRANSFORM,
static_cast<int32_t>(nativeTransform));
}
extern "C"
JNIEXPORT jlong JNICALL
Java_org_kenjinx_android_NativeHelpers_loadDriver(JNIEnv *env, jobject thiz,
jstring native_lib_path,
jstring private_apps_path,
jstring driver_name) {
auto libPath = getStringPointer(env, native_lib_path);
auto privateAppsPath = getStringPointer(env, private_apps_path);
auto driverName = getStringPointer(env, driver_name);
auto handle = adrenotools_open_libvulkan(
RTLD_NOW,
ADRENOTOOLS_DRIVER_CUSTOM,
nullptr,
libPath,
privateAppsPath,
driverName,
nullptr,
nullptr
);
delete libPath;
delete privateAppsPath;
delete driverName;
return (jlong) handle;
}
extern "C"
void debug_break(int code) {
if (code >= 3)
int r = 0;
}
extern "C"
JNIEXPORT void JNICALL
Java_org_kenjinx_android_NativeHelpers_setTurboMode(JNIEnv *env, jobject thiz, jboolean enable) {
adrenotools_set_turbo(enable);
}
extern "C"
JNIEXPORT jint JNICALL
Java_org_kenjinx_android_NativeHelpers_getMaxSwapInterval(JNIEnv *env, jobject thiz,
jlong native_window) {
auto nativeWindow = (ANativeWindow *) native_window;
return nativeWindow->maxSwapInterval;
}
extern "C"
JNIEXPORT jint JNICALL
Java_org_kenjinx_android_NativeHelpers_getMinSwapInterval(JNIEnv *env, jobject thiz,
jlong native_window) {
auto nativeWindow = (ANativeWindow *) native_window;
return nativeWindow->minSwapInterval;
}
extern "C"
JNIEXPORT jint JNICALL
Java_org_kenjinx_android_NativeHelpers_setSwapInterval(JNIEnv *env, jobject thiz,
jlong native_window, jint swap_interval) {
auto nativeWindow = (ANativeWindow *) native_window;
return nativeWindow->setSwapInterval(nativeWindow, swap_interval);
}
extern "C"
JNIEXPORT jstring JNICALL
Java_org_kenjinx_android_NativeHelpers_getStringJava(JNIEnv *env, jobject thiz, jlong ptr) {
return createString(env, (char*)ptr);
}
extern "C"
JNIEXPORT void JNICALL
Java_org_kenjinx_android_NativeHelpers_setIsInitialOrientationFlipped(JNIEnv *env, jobject thiz,
jboolean is_flipped) {
isInitialOrientationFlipped = is_flipped;
}
@@ -1,60 +0,0 @@
//
// Created by Emmanuel Hansen on 6/19/2023.
//
#ifndef KENJINXNATIVE_KENJINX_H
#define KENJINXNATIVE_KENJINX_H
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <dlfcn.h>
#include <exception>
#include <fcntl.h>
#include <jni.h>
#include <string>
#include <android/log.h>
#include <android/native_window.h>
#include <android/native_window_jni.h>
#include "vulkan_wrapper.h"
#include <vulkan/vulkan_android.h>
#include "adrenotools/driver.h"
#include "native_window.h"
// Android log function wrappers
static const char* TAG = "Kenjinx";
#define LOGI(...) \
((void)__android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__))
#define LOGW(...) \
((void)__android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__))
#define LOGE(...) \
((void)__android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__))
// A macro to pass call to Vulkan and check for return value for success
#define CALL_VK(func) \
if (VK_SUCCESS != (func)) { \
__android_log_print(ANDROID_LOG_ERROR, "Tutorial ", \
"Vulkan error. File[%s], line[%d]", __FILE__, \
__LINE__); \
assert(false); \
}
// A macro to check value is VK_SUCCESS
// Used also for non-vulkan functions but return VK_SUCCESS
#define VK_CHECK(x) CALL_VK(x)
#define LoadLib(a) dlopen(a, RTLD_NOW)
void *_kenjinxNative = nullptr;
// Kenjinx imported functions
bool (*initialize)(char *) = nullptr;
long _renderingThreadId = 0;
JavaVM *_vm = nullptr;
jobject _mainActivity = nullptr;
jclass _mainActivityClass = nullptr;
#endif //KENJINXNATIVE_KENJINX_H
@@ -1,305 +0,0 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
// Copyright © 2021 The Android Open Source Project
#pragma once
/* A collection of various types from AOSP that allow us to access private APIs for Native Window which we utilize for emulating the guest SF more accurately */
/**
* @url https://cs.android.com/android/platform/superproject/+/android11-release:frameworks/native/libs/nativebase/include/nativebase/nativebase.h;l=29;drc=cb496acbe593326e8d5d563847067d02b2df40ec
*/
#define ANDROID_NATIVE_UNSIGNED_CAST(x) static_cast<unsigned int>(x)
/**
* @url https://cs.android.com/android/platform/superproject/+/android11-release:frameworks/native/libs/nativebase/include/nativebase/nativebase.h;l=34-38;drc=cb496acbe593326e8d5d563847067d02b2df40ec
*/
#define ANDROID_NATIVE_MAKE_CONSTANT(a, b, c, d) \
((ANDROID_NATIVE_UNSIGNED_CAST(a) << 24) | \
(ANDROID_NATIVE_UNSIGNED_CAST(b) << 16) | \
(ANDROID_NATIVE_UNSIGNED_CAST(c) << 8) | \
(ANDROID_NATIVE_UNSIGNED_CAST(d)))
/**
* @url https://cs.android.com/android/platform/superproject/+/android11-release:frameworks/native/libs/nativewindow/include/system/window.h;l=60;drc=401cda638e7d17f6697b5a65c9a5ad79d056202d
*/
#define ANDROID_NATIVE_WINDOW_MAGIC ANDROID_NATIVE_MAKE_CONSTANT('_','w','n','d')
constexpr int AndroidNativeWindowMagic{ANDROID_NATIVE_WINDOW_MAGIC};
#undef ANDROID_NATIVE_WINDOW_MAGIC
#undef ANDROID_NATIVE_MAKE_CONSTANT
#undef ANDROID_NATIVE_UNSIGNED_CAST
/**
* @url https://cs.android.com/android/platform/superproject/+/android11-release:frameworks/native/libs/nativewindow/include/system/window.h;l=325-331;drc=401cda638e7d17f6697b5a65c9a5ad79d056202d
*/
constexpr int64_t NativeWindowTimestampAuto{-9223372036854775807LL - 1};
/**
* @url https://cs.android.com/android/platform/superproject/+/android11-release:frameworks/native/libs/nativewindow/include/system/window.h;l=198-259;drc=401cda638e7d17f6697b5a65c9a5ad79d056202d
*/
enum {
NATIVE_WINDOW_CONNECT = 1, /* deprecated */
NATIVE_WINDOW_DISCONNECT = 2, /* deprecated */
NATIVE_WINDOW_SET_CROP = 3, /* private */
NATIVE_WINDOW_SET_BUFFER_COUNT = 4,
NATIVE_WINDOW_SET_BUFFERS_TRANSFORM = 6,
NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP = 7,
NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS = 8,
NATIVE_WINDOW_SET_SCALING_MODE = 10, /* private */
NATIVE_WINDOW_LOCK = 11, /* private */
NATIVE_WINDOW_UNLOCK_AND_POST = 12, /* private */
NATIVE_WINDOW_API_CONNECT = 13, /* private */
NATIVE_WINDOW_API_DISCONNECT = 14, /* private */
NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS = 15, /* private */
NATIVE_WINDOW_SET_POST_TRANSFORM_CROP = 16, /* deprecated, unimplemented */
NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM = 17, /* private */
NATIVE_WINDOW_SET_SIDEBAND_STREAM = 18,
NATIVE_WINDOW_SET_BUFFERS_DATASPACE = 19,
NATIVE_WINDOW_SET_SURFACE_DAMAGE = 20, /* private */
NATIVE_WINDOW_SET_SHARED_BUFFER_MODE = 21,
NATIVE_WINDOW_SET_AUTO_REFRESH = 22,
NATIVE_WINDOW_GET_REFRESH_CYCLE_DURATION = 23,
NATIVE_WINDOW_GET_NEXT_FRAME_ID = 24,
NATIVE_WINDOW_ENABLE_FRAME_TIMESTAMPS = 25,
NATIVE_WINDOW_GET_COMPOSITOR_TIMING = 26,
NATIVE_WINDOW_GET_FRAME_TIMESTAMPS = 27,
NATIVE_WINDOW_GET_WIDE_COLOR_SUPPORT = 28,
NATIVE_WINDOW_GET_HDR_SUPPORT = 29,
NATIVE_WINDOW_GET_CONSUMER_USAGE64 = 31,
NATIVE_WINDOW_SET_BUFFERS_SMPTE2086_METADATA = 32,
NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA = 33,
NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA = 34,
NATIVE_WINDOW_SET_AUTO_PREROTATION = 35,
NATIVE_WINDOW_GET_LAST_DEQUEUE_START = 36, /* private */
NATIVE_WINDOW_SET_DEQUEUE_TIMEOUT = 37, /* private */
NATIVE_WINDOW_GET_LAST_DEQUEUE_DURATION = 38, /* private */
NATIVE_WINDOW_GET_LAST_QUEUE_DURATION = 39, /* private */
NATIVE_WINDOW_SET_FRAME_RATE = 40,
NATIVE_WINDOW_SET_CANCEL_INTERCEPTOR = 41, /* private */
NATIVE_WINDOW_SET_DEQUEUE_INTERCEPTOR = 42, /* private */
NATIVE_WINDOW_SET_PERFORM_INTERCEPTOR = 43, /* private */
NATIVE_WINDOW_SET_QUEUE_INTERCEPTOR = 44, /* private */
NATIVE_WINDOW_ALLOCATE_BUFFERS = 45, /* private */
NATIVE_WINDOW_GET_LAST_QUEUED_BUFFER = 46, /* private */
NATIVE_WINDOW_SET_QUERY_INTERCEPTOR = 47, /* private */
NATIVE_WINDOW_GET_LAST_QUEUED_BUFFER2 = 50, /* private */
};
/**
* @url https://cs.android.com/android/platform/superproject/+/android11-release:frameworks/native/libs/nativebase/include/nativebase/nativebase.h;l=43-56;drc=cb496acbe593326e8d5d563847067d02b2df40ec
*/
struct android_native_base_t {
int magic;
int version;
void *reserved[4];
void (*incRef)(android_native_base_t *);
void (*decRef)(android_native_base_t *);
};
/**
* @url https://cs.android.com/android/platform/superproject/+/android11-release:frameworks/native/libs/nativewindow/include/system/window.h;l=341-560;drc=401cda638e7d17f6697b5a65c9a5ad79d056202d
*/
struct ANativeWindow {
struct android_native_base_t common;
/* flags describing some attributes of this surface or its updater */
const uint32_t flags;
/* min swap interval supported by this updated */
const int minSwapInterval;
/* max swap interval supported by this updated */
const int maxSwapInterval;
/* horizontal and vertical resolution in DPI */
const float xdpi;
const float ydpi;
/* Some storage reserved for the OEM's driver. */
intptr_t oem[4];
/*
* Set the swap interval for this surface.
*
* Returns 0 on success or -errno on error.
*/
int (*setSwapInterval)(struct ANativeWindow *window,
int interval);
/*
* Hook called by EGL to acquire a buffer. After this call, the buffer
* is not locked, so its content cannot be modified. This call may block if
* no buffers are available.
*
* The window holds a reference to the buffer between dequeueBuffer and
* either queueBuffer or cancelBuffer, so clients only need their own
* reference if they might use the buffer after queueing or canceling it.
* Holding a reference to a buffer after queueing or canceling it is only
* allowed if a specific buffer count has been set.
*
* Returns 0 on success or -errno on error.
*
* XXX: This function is deprecated. It will continue to work for some
* time for binary compatibility, but the new dequeueBuffer function that
* outputs a fence file descriptor should be used in its place.
*/
int (*dequeueBuffer_DEPRECATED)(struct ANativeWindow *window,
struct ANativeWindowBuffer **buffer);
/*
* hook called by EGL to lock a buffer. This MUST be called before modifying
* the content of a buffer. The buffer must have been acquired with
* dequeueBuffer first.
*
* Returns 0 on success or -errno on error.
*
* XXX: This function is deprecated. It will continue to work for some
* time for binary compatibility, but it is essentially a no-op, and calls
* to it should be removed.
*/
int (*lockBuffer_DEPRECATED)(struct ANativeWindow *window,
struct ANativeWindowBuffer *buffer);
/*
* Hook called by EGL when modifications to the render buffer are done.
* This unlocks and post the buffer.
*
* The window holds a reference to the buffer between dequeueBuffer and
* either queueBuffer or cancelBuffer, so clients only need their own
* reference if they might use the buffer after queueing or canceling it.
* Holding a reference to a buffer after queueing or canceling it is only
* allowed if a specific buffer count has been set.
*
* Buffers MUST be queued in the same order than they were dequeued.
*
* Returns 0 on success or -errno on error.
*
* XXX: This function is deprecated. It will continue to work for some
* time for binary compatibility, but the new queueBuffer function that
* takes a fence file descriptor should be used in its place (pass a value
* of -1 for the fence file descriptor if there is no valid one to pass).
*/
int (*queueBuffer_DEPRECATED)(struct ANativeWindow *window,
struct ANativeWindowBuffer *buffer);
/*
* hook used to retrieve information about the native window.
*
* Returns 0 on success or -errno on error.
*/
int (*query)(const struct ANativeWindow *window,
int what, int *value);
/*
* hook used to perform various operations on the surface.
* (*perform)() is a generic mechanism to add functionality to
* ANativeWindow while keeping backward binary compatibility.
*
* DO NOT CALL THIS HOOK DIRECTLY. Instead, use the helper functions
* defined below.
*
* (*perform)() returns -ENOENT if the 'what' parameter is not supported
* by the surface's implementation.
*
* See above for a list of valid operations, such as
* NATIVE_WINDOW_SET_USAGE or NATIVE_WINDOW_CONNECT
*/
int (*perform)(struct ANativeWindow *window,
int operation, ...);
/*
* Hook used to cancel a buffer that has been dequeued.
* No synchronization is performed between dequeue() and cancel(), so
* either external synchronization is needed, or these functions must be
* called from the same thread.
*
* The window holds a reference to the buffer between dequeueBuffer and
* either queueBuffer or cancelBuffer, so clients only need their own
* reference if they might use the buffer after queueing or canceling it.
* Holding a reference to a buffer after queueing or canceling it is only
* allowed if a specific buffer count has been set.
*
* XXX: This function is deprecated. It will continue to work for some
* time for binary compatibility, but the new cancelBuffer function that
* takes a fence file descriptor should be used in its place (pass a value
* of -1 for the fence file descriptor if there is no valid one to pass).
*/
int (*cancelBuffer_DEPRECATED)(struct ANativeWindow *window,
struct ANativeWindowBuffer *buffer);
/*
* Hook called by EGL to acquire a buffer. This call may block if no
* buffers are available.
*
* The window holds a reference to the buffer between dequeueBuffer and
* either queueBuffer or cancelBuffer, so clients only need their own
* reference if they might use the buffer after queueing or canceling it.
* Holding a reference to a buffer after queueing or canceling it is only
* allowed if a specific buffer count has been set.
*
* The libsync fence file descriptor returned in the int pointed to by the
* fenceFd argument will refer to the fence that must signal before the
* dequeued buffer may be written to. A value of -1 indicates that the
* caller may access the buffer immediately without waiting on a fence. If
* a valid file descriptor is returned (i.e. any value except -1) then the
* caller is responsible for closing the file descriptor.
*
* Returns 0 on success or -errno on error.
*/
int (*dequeueBuffer)(struct ANativeWindow *window,
struct ANativeWindowBuffer **buffer, int *fenceFd);
/*
* Hook called by EGL when modifications to the render buffer are done.
* This unlocks and post the buffer.
*
* The window holds a reference to the buffer between dequeueBuffer and
* either queueBuffer or cancelBuffer, so clients only need their own
* reference if they might use the buffer after queueing or canceling it.
* Holding a reference to a buffer after queueing or canceling it is only
* allowed if a specific buffer count has been set.
*
* The fenceFd argument specifies a libsync fence file descriptor for a
* fence that must signal before the buffer can be accessed. If the buffer
* can be accessed immediately then a value of -1 should be used. The
* caller must not use the file descriptor after it is passed to
* queueBuffer, and the ANativeWindow implementation is responsible for
* closing it.
*
* Returns 0 on success or -errno on error.
*/
int (*queueBuffer)(struct ANativeWindow *window,
struct ANativeWindowBuffer *buffer, int fenceFd);
/*
* Hook used to cancel a buffer that has been dequeued.
* No synchronization is performed between dequeue() and cancel(), so
* either external synchronization is needed, or these functions must be
* called from the same thread.
*
* The window holds a reference to the buffer between dequeueBuffer and
* either queueBuffer or cancelBuffer, so clients only need their own
* reference if they might use the buffer after queueing or canceling it.
* Holding a reference to a buffer after queueing or canceling it is only
* allowed if a specific buffer count has been set.
*
* The fenceFd argument specifies a libsync fence file decsriptor for a
* fence that must signal before the buffer can be accessed. If the buffer
* can be accessed immediately then a value of -1 should be used.
*
* Note that if the client has not waited on the fence that was returned
* from dequeueBuffer, that same fence should be passed to cancelBuffer to
* ensure that future uses of the buffer are preceded by a wait on that
* fence. The caller must not use the file descriptor after it is passed
* to cancelBuffer, and the ANativeWindow implementation is responsible for
* closing it.
*
* Returns 0 on success or -errno on error.
*/
int (*cancelBuffer)(struct ANativeWindow *window,
struct ANativeWindowBuffer *buffer, int fenceFd);
};
@@ -1,404 +0,0 @@
// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This file is generated.
#include "vulkan_wrapper.h"
#include <dlfcn.h>
int InitVulkan(void) {
void* libvulkan = dlopen("libvulkan.so", RTLD_NOW | RTLD_LOCAL);
if (!libvulkan)
return 0;
// Vulkan supported, set function addresses
vkCreateInstance = reinterpret_cast<PFN_vkCreateInstance>(dlsym(libvulkan, "vkCreateInstance"));
vkDestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(dlsym(libvulkan, "vkDestroyInstance"));
vkEnumeratePhysicalDevices = reinterpret_cast<PFN_vkEnumeratePhysicalDevices>(dlsym(libvulkan, "vkEnumeratePhysicalDevices"));
vkGetPhysicalDeviceFeatures = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures>(dlsym(libvulkan, "vkGetPhysicalDeviceFeatures"));
vkGetPhysicalDeviceFormatProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceFormatProperties>(dlsym(libvulkan, "vkGetPhysicalDeviceFormatProperties"));
vkGetPhysicalDeviceImageFormatProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceImageFormatProperties>(dlsym(libvulkan, "vkGetPhysicalDeviceImageFormatProperties"));
vkGetPhysicalDeviceProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties>(dlsym(libvulkan, "vkGetPhysicalDeviceProperties"));
vkGetPhysicalDeviceQueueFamilyProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceQueueFamilyProperties>(dlsym(libvulkan, "vkGetPhysicalDeviceQueueFamilyProperties"));
vkGetPhysicalDeviceMemoryProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceMemoryProperties>(dlsym(libvulkan, "vkGetPhysicalDeviceMemoryProperties"));
vkGetInstanceProcAddr = reinterpret_cast<PFN_vkGetInstanceProcAddr>(dlsym(libvulkan, "vkGetInstanceProcAddr"));
vkGetDeviceProcAddr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(dlsym(libvulkan, "vkGetDeviceProcAddr"));
vkCreateDevice = reinterpret_cast<PFN_vkCreateDevice>(dlsym(libvulkan, "vkCreateDevice"));
vkDestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(dlsym(libvulkan, "vkDestroyDevice"));
vkEnumerateInstanceExtensionProperties = reinterpret_cast<PFN_vkEnumerateInstanceExtensionProperties>(dlsym(libvulkan, "vkEnumerateInstanceExtensionProperties"));
vkEnumerateDeviceExtensionProperties = reinterpret_cast<PFN_vkEnumerateDeviceExtensionProperties>(dlsym(libvulkan, "vkEnumerateDeviceExtensionProperties"));
vkEnumerateInstanceLayerProperties = reinterpret_cast<PFN_vkEnumerateInstanceLayerProperties>(dlsym(libvulkan, "vkEnumerateInstanceLayerProperties"));
vkEnumerateDeviceLayerProperties = reinterpret_cast<PFN_vkEnumerateDeviceLayerProperties>(dlsym(libvulkan, "vkEnumerateDeviceLayerProperties"));
vkGetDeviceQueue = reinterpret_cast<PFN_vkGetDeviceQueue>(dlsym(libvulkan, "vkGetDeviceQueue"));
vkQueueSubmit = reinterpret_cast<PFN_vkQueueSubmit>(dlsym(libvulkan, "vkQueueSubmit"));
vkQueueWaitIdle = reinterpret_cast<PFN_vkQueueWaitIdle>(dlsym(libvulkan, "vkQueueWaitIdle"));
vkDeviceWaitIdle = reinterpret_cast<PFN_vkDeviceWaitIdle>(dlsym(libvulkan, "vkDeviceWaitIdle"));
vkAllocateMemory = reinterpret_cast<PFN_vkAllocateMemory>(dlsym(libvulkan, "vkAllocateMemory"));
vkFreeMemory = reinterpret_cast<PFN_vkFreeMemory>(dlsym(libvulkan, "vkFreeMemory"));
vkMapMemory = reinterpret_cast<PFN_vkMapMemory>(dlsym(libvulkan, "vkMapMemory"));
vkUnmapMemory = reinterpret_cast<PFN_vkUnmapMemory>(dlsym(libvulkan, "vkUnmapMemory"));
vkFlushMappedMemoryRanges = reinterpret_cast<PFN_vkFlushMappedMemoryRanges>(dlsym(libvulkan, "vkFlushMappedMemoryRanges"));
vkInvalidateMappedMemoryRanges = reinterpret_cast<PFN_vkInvalidateMappedMemoryRanges>(dlsym(libvulkan, "vkInvalidateMappedMemoryRanges"));
vkGetDeviceMemoryCommitment = reinterpret_cast<PFN_vkGetDeviceMemoryCommitment>(dlsym(libvulkan, "vkGetDeviceMemoryCommitment"));
vkBindBufferMemory = reinterpret_cast<PFN_vkBindBufferMemory>(dlsym(libvulkan, "vkBindBufferMemory"));
vkBindImageMemory = reinterpret_cast<PFN_vkBindImageMemory>(dlsym(libvulkan, "vkBindImageMemory"));
vkGetBufferMemoryRequirements = reinterpret_cast<PFN_vkGetBufferMemoryRequirements>(dlsym(libvulkan, "vkGetBufferMemoryRequirements"));
vkGetImageMemoryRequirements = reinterpret_cast<PFN_vkGetImageMemoryRequirements>(dlsym(libvulkan, "vkGetImageMemoryRequirements"));
vkGetImageSparseMemoryRequirements = reinterpret_cast<PFN_vkGetImageSparseMemoryRequirements>(dlsym(libvulkan, "vkGetImageSparseMemoryRequirements"));
vkGetPhysicalDeviceSparseImageFormatProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceSparseImageFormatProperties>(dlsym(libvulkan, "vkGetPhysicalDeviceSparseImageFormatProperties"));
vkQueueBindSparse = reinterpret_cast<PFN_vkQueueBindSparse>(dlsym(libvulkan, "vkQueueBindSparse"));
vkCreateFence = reinterpret_cast<PFN_vkCreateFence>(dlsym(libvulkan, "vkCreateFence"));
vkDestroyFence = reinterpret_cast<PFN_vkDestroyFence>(dlsym(libvulkan, "vkDestroyFence"));
vkResetFences = reinterpret_cast<PFN_vkResetFences>(dlsym(libvulkan, "vkResetFences"));
vkGetFenceStatus = reinterpret_cast<PFN_vkGetFenceStatus>(dlsym(libvulkan, "vkGetFenceStatus"));
vkWaitForFences = reinterpret_cast<PFN_vkWaitForFences>(dlsym(libvulkan, "vkWaitForFences"));
vkCreateSemaphore = reinterpret_cast<PFN_vkCreateSemaphore>(dlsym(libvulkan, "vkCreateSemaphore"));
vkDestroySemaphore = reinterpret_cast<PFN_vkDestroySemaphore>(dlsym(libvulkan, "vkDestroySemaphore"));
vkCreateEvent = reinterpret_cast<PFN_vkCreateEvent>(dlsym(libvulkan, "vkCreateEvent"));
vkDestroyEvent = reinterpret_cast<PFN_vkDestroyEvent>(dlsym(libvulkan, "vkDestroyEvent"));
vkGetEventStatus = reinterpret_cast<PFN_vkGetEventStatus>(dlsym(libvulkan, "vkGetEventStatus"));
vkSetEvent = reinterpret_cast<PFN_vkSetEvent>(dlsym(libvulkan, "vkSetEvent"));
vkResetEvent = reinterpret_cast<PFN_vkResetEvent>(dlsym(libvulkan, "vkResetEvent"));
vkCreateQueryPool = reinterpret_cast<PFN_vkCreateQueryPool>(dlsym(libvulkan, "vkCreateQueryPool"));
vkDestroyQueryPool = reinterpret_cast<PFN_vkDestroyQueryPool>(dlsym(libvulkan, "vkDestroyQueryPool"));
vkGetQueryPoolResults = reinterpret_cast<PFN_vkGetQueryPoolResults>(dlsym(libvulkan, "vkGetQueryPoolResults"));
vkCreateBuffer = reinterpret_cast<PFN_vkCreateBuffer>(dlsym(libvulkan, "vkCreateBuffer"));
vkDestroyBuffer = reinterpret_cast<PFN_vkDestroyBuffer>(dlsym(libvulkan, "vkDestroyBuffer"));
vkCreateBufferView = reinterpret_cast<PFN_vkCreateBufferView>(dlsym(libvulkan, "vkCreateBufferView"));
vkDestroyBufferView = reinterpret_cast<PFN_vkDestroyBufferView>(dlsym(libvulkan, "vkDestroyBufferView"));
vkCreateImage = reinterpret_cast<PFN_vkCreateImage>(dlsym(libvulkan, "vkCreateImage"));
vkDestroyImage = reinterpret_cast<PFN_vkDestroyImage>(dlsym(libvulkan, "vkDestroyImage"));
vkGetImageSubresourceLayout = reinterpret_cast<PFN_vkGetImageSubresourceLayout>(dlsym(libvulkan, "vkGetImageSubresourceLayout"));
vkCreateImageView = reinterpret_cast<PFN_vkCreateImageView>(dlsym(libvulkan, "vkCreateImageView"));
vkDestroyImageView = reinterpret_cast<PFN_vkDestroyImageView>(dlsym(libvulkan, "vkDestroyImageView"));
vkCreateShaderModule = reinterpret_cast<PFN_vkCreateShaderModule>(dlsym(libvulkan, "vkCreateShaderModule"));
vkDestroyShaderModule = reinterpret_cast<PFN_vkDestroyShaderModule>(dlsym(libvulkan, "vkDestroyShaderModule"));
vkCreatePipelineCache = reinterpret_cast<PFN_vkCreatePipelineCache>(dlsym(libvulkan, "vkCreatePipelineCache"));
vkDestroyPipelineCache = reinterpret_cast<PFN_vkDestroyPipelineCache>(dlsym(libvulkan, "vkDestroyPipelineCache"));
vkGetPipelineCacheData = reinterpret_cast<PFN_vkGetPipelineCacheData>(dlsym(libvulkan, "vkGetPipelineCacheData"));
vkMergePipelineCaches = reinterpret_cast<PFN_vkMergePipelineCaches>(dlsym(libvulkan, "vkMergePipelineCaches"));
vkCreateGraphicsPipelines = reinterpret_cast<PFN_vkCreateGraphicsPipelines>(dlsym(libvulkan, "vkCreateGraphicsPipelines"));
vkCreateComputePipelines = reinterpret_cast<PFN_vkCreateComputePipelines>(dlsym(libvulkan, "vkCreateComputePipelines"));
vkDestroyPipeline = reinterpret_cast<PFN_vkDestroyPipeline>(dlsym(libvulkan, "vkDestroyPipeline"));
vkCreatePipelineLayout = reinterpret_cast<PFN_vkCreatePipelineLayout>(dlsym(libvulkan, "vkCreatePipelineLayout"));
vkDestroyPipelineLayout = reinterpret_cast<PFN_vkDestroyPipelineLayout>(dlsym(libvulkan, "vkDestroyPipelineLayout"));
vkCreateSampler = reinterpret_cast<PFN_vkCreateSampler>(dlsym(libvulkan, "vkCreateSampler"));
vkDestroySampler = reinterpret_cast<PFN_vkDestroySampler>(dlsym(libvulkan, "vkDestroySampler"));
vkCreateDescriptorSetLayout = reinterpret_cast<PFN_vkCreateDescriptorSetLayout>(dlsym(libvulkan, "vkCreateDescriptorSetLayout"));
vkDestroyDescriptorSetLayout = reinterpret_cast<PFN_vkDestroyDescriptorSetLayout>(dlsym(libvulkan, "vkDestroyDescriptorSetLayout"));
vkCreateDescriptorPool = reinterpret_cast<PFN_vkCreateDescriptorPool>(dlsym(libvulkan, "vkCreateDescriptorPool"));
vkDestroyDescriptorPool = reinterpret_cast<PFN_vkDestroyDescriptorPool>(dlsym(libvulkan, "vkDestroyDescriptorPool"));
vkResetDescriptorPool = reinterpret_cast<PFN_vkResetDescriptorPool>(dlsym(libvulkan, "vkResetDescriptorPool"));
vkAllocateDescriptorSets = reinterpret_cast<PFN_vkAllocateDescriptorSets>(dlsym(libvulkan, "vkAllocateDescriptorSets"));
vkFreeDescriptorSets = reinterpret_cast<PFN_vkFreeDescriptorSets>(dlsym(libvulkan, "vkFreeDescriptorSets"));
vkUpdateDescriptorSets = reinterpret_cast<PFN_vkUpdateDescriptorSets>(dlsym(libvulkan, "vkUpdateDescriptorSets"));
vkCreateFramebuffer = reinterpret_cast<PFN_vkCreateFramebuffer>(dlsym(libvulkan, "vkCreateFramebuffer"));
vkDestroyFramebuffer = reinterpret_cast<PFN_vkDestroyFramebuffer>(dlsym(libvulkan, "vkDestroyFramebuffer"));
vkCreateRenderPass = reinterpret_cast<PFN_vkCreateRenderPass>(dlsym(libvulkan, "vkCreateRenderPass"));
vkDestroyRenderPass = reinterpret_cast<PFN_vkDestroyRenderPass>(dlsym(libvulkan, "vkDestroyRenderPass"));
vkGetRenderAreaGranularity = reinterpret_cast<PFN_vkGetRenderAreaGranularity>(dlsym(libvulkan, "vkGetRenderAreaGranularity"));
vkCreateCommandPool = reinterpret_cast<PFN_vkCreateCommandPool>(dlsym(libvulkan, "vkCreateCommandPool"));
vkDestroyCommandPool = reinterpret_cast<PFN_vkDestroyCommandPool>(dlsym(libvulkan, "vkDestroyCommandPool"));
vkResetCommandPool = reinterpret_cast<PFN_vkResetCommandPool>(dlsym(libvulkan, "vkResetCommandPool"));
vkAllocateCommandBuffers = reinterpret_cast<PFN_vkAllocateCommandBuffers>(dlsym(libvulkan, "vkAllocateCommandBuffers"));
vkFreeCommandBuffers = reinterpret_cast<PFN_vkFreeCommandBuffers>(dlsym(libvulkan, "vkFreeCommandBuffers"));
vkBeginCommandBuffer = reinterpret_cast<PFN_vkBeginCommandBuffer>(dlsym(libvulkan, "vkBeginCommandBuffer"));
vkEndCommandBuffer = reinterpret_cast<PFN_vkEndCommandBuffer>(dlsym(libvulkan, "vkEndCommandBuffer"));
vkResetCommandBuffer = reinterpret_cast<PFN_vkResetCommandBuffer>(dlsym(libvulkan, "vkResetCommandBuffer"));
vkCmdBindPipeline = reinterpret_cast<PFN_vkCmdBindPipeline>(dlsym(libvulkan, "vkCmdBindPipeline"));
vkCmdSetViewport = reinterpret_cast<PFN_vkCmdSetViewport>(dlsym(libvulkan, "vkCmdSetViewport"));
vkCmdSetScissor = reinterpret_cast<PFN_vkCmdSetScissor>(dlsym(libvulkan, "vkCmdSetScissor"));
vkCmdSetLineWidth = reinterpret_cast<PFN_vkCmdSetLineWidth>(dlsym(libvulkan, "vkCmdSetLineWidth"));
vkCmdSetDepthBias = reinterpret_cast<PFN_vkCmdSetDepthBias>(dlsym(libvulkan, "vkCmdSetDepthBias"));
vkCmdSetBlendConstants = reinterpret_cast<PFN_vkCmdSetBlendConstants>(dlsym(libvulkan, "vkCmdSetBlendConstants"));
vkCmdSetDepthBounds = reinterpret_cast<PFN_vkCmdSetDepthBounds>(dlsym(libvulkan, "vkCmdSetDepthBounds"));
vkCmdSetStencilCompareMask = reinterpret_cast<PFN_vkCmdSetStencilCompareMask>(dlsym(libvulkan, "vkCmdSetStencilCompareMask"));
vkCmdSetStencilWriteMask = reinterpret_cast<PFN_vkCmdSetStencilWriteMask>(dlsym(libvulkan, "vkCmdSetStencilWriteMask"));
vkCmdSetStencilReference = reinterpret_cast<PFN_vkCmdSetStencilReference>(dlsym(libvulkan, "vkCmdSetStencilReference"));
vkCmdBindDescriptorSets = reinterpret_cast<PFN_vkCmdBindDescriptorSets>(dlsym(libvulkan, "vkCmdBindDescriptorSets"));
vkCmdBindIndexBuffer = reinterpret_cast<PFN_vkCmdBindIndexBuffer>(dlsym(libvulkan, "vkCmdBindIndexBuffer"));
vkCmdBindVertexBuffers = reinterpret_cast<PFN_vkCmdBindVertexBuffers>(dlsym(libvulkan, "vkCmdBindVertexBuffers"));
vkCmdDraw = reinterpret_cast<PFN_vkCmdDraw>(dlsym(libvulkan, "vkCmdDraw"));
vkCmdDrawIndexed = reinterpret_cast<PFN_vkCmdDrawIndexed>(dlsym(libvulkan, "vkCmdDrawIndexed"));
vkCmdDrawIndirect = reinterpret_cast<PFN_vkCmdDrawIndirect>(dlsym(libvulkan, "vkCmdDrawIndirect"));
vkCmdDrawIndexedIndirect = reinterpret_cast<PFN_vkCmdDrawIndexedIndirect>(dlsym(libvulkan, "vkCmdDrawIndexedIndirect"));
vkCmdDispatch = reinterpret_cast<PFN_vkCmdDispatch>(dlsym(libvulkan, "vkCmdDispatch"));
vkCmdDispatchIndirect = reinterpret_cast<PFN_vkCmdDispatchIndirect>(dlsym(libvulkan, "vkCmdDispatchIndirect"));
vkCmdCopyBuffer = reinterpret_cast<PFN_vkCmdCopyBuffer>(dlsym(libvulkan, "vkCmdCopyBuffer"));
vkCmdCopyImage = reinterpret_cast<PFN_vkCmdCopyImage>(dlsym(libvulkan, "vkCmdCopyImage"));
vkCmdBlitImage = reinterpret_cast<PFN_vkCmdBlitImage>(dlsym(libvulkan, "vkCmdBlitImage"));
vkCmdCopyBufferToImage = reinterpret_cast<PFN_vkCmdCopyBufferToImage>(dlsym(libvulkan, "vkCmdCopyBufferToImage"));
vkCmdCopyImageToBuffer = reinterpret_cast<PFN_vkCmdCopyImageToBuffer>(dlsym(libvulkan, "vkCmdCopyImageToBuffer"));
vkCmdUpdateBuffer = reinterpret_cast<PFN_vkCmdUpdateBuffer>(dlsym(libvulkan, "vkCmdUpdateBuffer"));
vkCmdFillBuffer = reinterpret_cast<PFN_vkCmdFillBuffer>(dlsym(libvulkan, "vkCmdFillBuffer"));
vkCmdClearColorImage = reinterpret_cast<PFN_vkCmdClearColorImage>(dlsym(libvulkan, "vkCmdClearColorImage"));
vkCmdClearDepthStencilImage = reinterpret_cast<PFN_vkCmdClearDepthStencilImage>(dlsym(libvulkan, "vkCmdClearDepthStencilImage"));
vkCmdClearAttachments = reinterpret_cast<PFN_vkCmdClearAttachments>(dlsym(libvulkan, "vkCmdClearAttachments"));
vkCmdResolveImage = reinterpret_cast<PFN_vkCmdResolveImage>(dlsym(libvulkan, "vkCmdResolveImage"));
vkCmdSetEvent = reinterpret_cast<PFN_vkCmdSetEvent>(dlsym(libvulkan, "vkCmdSetEvent"));
vkCmdResetEvent = reinterpret_cast<PFN_vkCmdResetEvent>(dlsym(libvulkan, "vkCmdResetEvent"));
vkCmdWaitEvents = reinterpret_cast<PFN_vkCmdWaitEvents>(dlsym(libvulkan, "vkCmdWaitEvents"));
vkCmdPipelineBarrier = reinterpret_cast<PFN_vkCmdPipelineBarrier>(dlsym(libvulkan, "vkCmdPipelineBarrier"));
vkCmdBeginQuery = reinterpret_cast<PFN_vkCmdBeginQuery>(dlsym(libvulkan, "vkCmdBeginQuery"));
vkCmdEndQuery = reinterpret_cast<PFN_vkCmdEndQuery>(dlsym(libvulkan, "vkCmdEndQuery"));
vkCmdResetQueryPool = reinterpret_cast<PFN_vkCmdResetQueryPool>(dlsym(libvulkan, "vkCmdResetQueryPool"));
vkCmdWriteTimestamp = reinterpret_cast<PFN_vkCmdWriteTimestamp>(dlsym(libvulkan, "vkCmdWriteTimestamp"));
vkCmdCopyQueryPoolResults = reinterpret_cast<PFN_vkCmdCopyQueryPoolResults>(dlsym(libvulkan, "vkCmdCopyQueryPoolResults"));
vkCmdPushConstants = reinterpret_cast<PFN_vkCmdPushConstants>(dlsym(libvulkan, "vkCmdPushConstants"));
vkCmdBeginRenderPass = reinterpret_cast<PFN_vkCmdBeginRenderPass>(dlsym(libvulkan, "vkCmdBeginRenderPass"));
vkCmdNextSubpass = reinterpret_cast<PFN_vkCmdNextSubpass>(dlsym(libvulkan, "vkCmdNextSubpass"));
vkCmdEndRenderPass = reinterpret_cast<PFN_vkCmdEndRenderPass>(dlsym(libvulkan, "vkCmdEndRenderPass"));
vkCmdExecuteCommands = reinterpret_cast<PFN_vkCmdExecuteCommands>(dlsym(libvulkan, "vkCmdExecuteCommands"));
vkDestroySurfaceKHR = reinterpret_cast<PFN_vkDestroySurfaceKHR>(dlsym(libvulkan, "vkDestroySurfaceKHR"));
vkGetPhysicalDeviceSurfaceSupportKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceSupportKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceSurfaceSupportKHR"));
vkGetPhysicalDeviceSurfaceCapabilitiesKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR"));
vkGetPhysicalDeviceSurfaceFormatsKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceFormatsKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceSurfaceFormatsKHR"));
vkGetPhysicalDeviceSurfacePresentModesKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfacePresentModesKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceSurfacePresentModesKHR"));
vkCreateSwapchainKHR = reinterpret_cast<PFN_vkCreateSwapchainKHR>(dlsym(libvulkan, "vkCreateSwapchainKHR"));
vkDestroySwapchainKHR = reinterpret_cast<PFN_vkDestroySwapchainKHR>(dlsym(libvulkan, "vkDestroySwapchainKHR"));
vkGetSwapchainImagesKHR = reinterpret_cast<PFN_vkGetSwapchainImagesKHR>(dlsym(libvulkan, "vkGetSwapchainImagesKHR"));
vkAcquireNextImageKHR = reinterpret_cast<PFN_vkAcquireNextImageKHR>(dlsym(libvulkan, "vkAcquireNextImageKHR"));
vkQueuePresentKHR = reinterpret_cast<PFN_vkQueuePresentKHR>(dlsym(libvulkan, "vkQueuePresentKHR"));
vkGetPhysicalDeviceDisplayPropertiesKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayPropertiesKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceDisplayPropertiesKHR"));
vkGetPhysicalDeviceDisplayPlanePropertiesKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR"));
vkGetDisplayPlaneSupportedDisplaysKHR = reinterpret_cast<PFN_vkGetDisplayPlaneSupportedDisplaysKHR>(dlsym(libvulkan, "vkGetDisplayPlaneSupportedDisplaysKHR"));
vkGetDisplayModePropertiesKHR = reinterpret_cast<PFN_vkGetDisplayModePropertiesKHR>(dlsym(libvulkan, "vkGetDisplayModePropertiesKHR"));
vkCreateDisplayModeKHR = reinterpret_cast<PFN_vkCreateDisplayModeKHR>(dlsym(libvulkan, "vkCreateDisplayModeKHR"));
vkGetDisplayPlaneCapabilitiesKHR = reinterpret_cast<PFN_vkGetDisplayPlaneCapabilitiesKHR>(dlsym(libvulkan, "vkGetDisplayPlaneCapabilitiesKHR"));
vkCreateDisplayPlaneSurfaceKHR = reinterpret_cast<PFN_vkCreateDisplayPlaneSurfaceKHR>(dlsym(libvulkan, "vkCreateDisplayPlaneSurfaceKHR"));
vkCreateSharedSwapchainsKHR = reinterpret_cast<PFN_vkCreateSharedSwapchainsKHR>(dlsym(libvulkan, "vkCreateSharedSwapchainsKHR"));
#ifdef VK_USE_PLATFORM_XLIB_KHR
vkCreateXlibSurfaceKHR = reinterpret_cast<PFN_vkCreateXlibSurfaceKHR>(dlsym(libvulkan, "vkCreateXlibSurfaceKHR"));
vkGetPhysicalDeviceXlibPresentationSupportKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceXlibPresentationSupportKHR"));
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
vkCreateXcbSurfaceKHR = reinterpret_cast<PFN_vkCreateXcbSurfaceKHR>(dlsym(libvulkan, "vkCreateXcbSurfaceKHR"));
vkGetPhysicalDeviceXcbPresentationSupportKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceXcbPresentationSupportKHR"));
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
vkCreateWaylandSurfaceKHR = reinterpret_cast<PFN_vkCreateWaylandSurfaceKHR>(dlsym(libvulkan, "vkCreateWaylandSurfaceKHR"));
vkGetPhysicalDeviceWaylandPresentationSupportKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceWaylandPresentationSupportKHR"));
#endif
#ifdef VK_USE_PLATFORM_MIR_KHR
vkCreateMirSurfaceKHR = reinterpret_cast<PFN_vkCreateMirSurfaceKHR>(dlsym(libvulkan, "vkCreateMirSurfaceKHR"));
vkGetPhysicalDeviceMirPresentationSupportKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceMirPresentationSupportKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceMirPresentationSupportKHR"));
#endif
#ifdef VK_USE_PLATFORM_ANDROID_KHR
vkCreateAndroidSurfaceKHR = reinterpret_cast<PFN_vkCreateAndroidSurfaceKHR>(dlsym(libvulkan, "vkCreateAndroidSurfaceKHR"));
#endif
#ifdef VK_USE_PLATFORM_WIN32_KHR
vkCreateWin32SurfaceKHR = reinterpret_cast<PFN_vkCreateWin32SurfaceKHR>(dlsym(libvulkan, "vkCreateWin32SurfaceKHR"));
vkGetPhysicalDeviceWin32PresentationSupportKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR>(dlsym(libvulkan, "vkGetPhysicalDeviceWin32PresentationSupportKHR"));
#endif
#ifdef USE_DEBUG_EXTENTIONS
vkCreateDebugReportCallbackEXT = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(dlsym(libvulkan, "vkCreateDebugReportCallbackEXT"));
vkDestroyDebugReportCallbackEXT = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(dlsym(libvulkan, "vkDestroyDebugReportCallbackEXT"));
vkDebugReportMessageEXT = reinterpret_cast<PFN_vkDebugReportMessageEXT>(dlsym(libvulkan, "vkDebugReportMessageEXT"));
#endif
return 1;
}
// No Vulkan support, do not set function addresses
PFN_vkCreateInstance vkCreateInstance;
PFN_vkDestroyInstance vkDestroyInstance;
PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures;
PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties;
PFN_vkGetPhysicalDeviceImageFormatProperties vkGetPhysicalDeviceImageFormatProperties;
PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties;
PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties;
PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties;
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
PFN_vkCreateDevice vkCreateDevice;
PFN_vkDestroyDevice vkDestroyDevice;
PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties;
PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties;
PFN_vkEnumerateDeviceLayerProperties vkEnumerateDeviceLayerProperties;
PFN_vkGetDeviceQueue vkGetDeviceQueue;
PFN_vkQueueSubmit vkQueueSubmit;
PFN_vkQueueWaitIdle vkQueueWaitIdle;
PFN_vkDeviceWaitIdle vkDeviceWaitIdle;
PFN_vkAllocateMemory vkAllocateMemory;
PFN_vkFreeMemory vkFreeMemory;
PFN_vkMapMemory vkMapMemory;
PFN_vkUnmapMemory vkUnmapMemory;
PFN_vkFlushMappedMemoryRanges vkFlushMappedMemoryRanges;
PFN_vkInvalidateMappedMemoryRanges vkInvalidateMappedMemoryRanges;
PFN_vkGetDeviceMemoryCommitment vkGetDeviceMemoryCommitment;
PFN_vkBindBufferMemory vkBindBufferMemory;
PFN_vkBindImageMemory vkBindImageMemory;
PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements;
PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements;
PFN_vkGetImageSparseMemoryRequirements vkGetImageSparseMemoryRequirements;
PFN_vkGetPhysicalDeviceSparseImageFormatProperties vkGetPhysicalDeviceSparseImageFormatProperties;
PFN_vkQueueBindSparse vkQueueBindSparse;
PFN_vkCreateFence vkCreateFence;
PFN_vkDestroyFence vkDestroyFence;
PFN_vkResetFences vkResetFences;
PFN_vkGetFenceStatus vkGetFenceStatus;
PFN_vkWaitForFences vkWaitForFences;
PFN_vkCreateSemaphore vkCreateSemaphore;
PFN_vkDestroySemaphore vkDestroySemaphore;
PFN_vkCreateEvent vkCreateEvent;
PFN_vkDestroyEvent vkDestroyEvent;
PFN_vkGetEventStatus vkGetEventStatus;
PFN_vkSetEvent vkSetEvent;
PFN_vkResetEvent vkResetEvent;
PFN_vkCreateQueryPool vkCreateQueryPool;
PFN_vkDestroyQueryPool vkDestroyQueryPool;
PFN_vkGetQueryPoolResults vkGetQueryPoolResults;
PFN_vkCreateBuffer vkCreateBuffer;
PFN_vkDestroyBuffer vkDestroyBuffer;
PFN_vkCreateBufferView vkCreateBufferView;
PFN_vkDestroyBufferView vkDestroyBufferView;
PFN_vkCreateImage vkCreateImage;
PFN_vkDestroyImage vkDestroyImage;
PFN_vkGetImageSubresourceLayout vkGetImageSubresourceLayout;
PFN_vkCreateImageView vkCreateImageView;
PFN_vkDestroyImageView vkDestroyImageView;
PFN_vkCreateShaderModule vkCreateShaderModule;
PFN_vkDestroyShaderModule vkDestroyShaderModule;
PFN_vkCreatePipelineCache vkCreatePipelineCache;
PFN_vkDestroyPipelineCache vkDestroyPipelineCache;
PFN_vkGetPipelineCacheData vkGetPipelineCacheData;
PFN_vkMergePipelineCaches vkMergePipelineCaches;
PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines;
PFN_vkCreateComputePipelines vkCreateComputePipelines;
PFN_vkDestroyPipeline vkDestroyPipeline;
PFN_vkCreatePipelineLayout vkCreatePipelineLayout;
PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout;
PFN_vkCreateSampler vkCreateSampler;
PFN_vkDestroySampler vkDestroySampler;
PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout;
PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout;
PFN_vkCreateDescriptorPool vkCreateDescriptorPool;
PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool;
PFN_vkResetDescriptorPool vkResetDescriptorPool;
PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets;
PFN_vkFreeDescriptorSets vkFreeDescriptorSets;
PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets;
PFN_vkCreateFramebuffer vkCreateFramebuffer;
PFN_vkDestroyFramebuffer vkDestroyFramebuffer;
PFN_vkCreateRenderPass vkCreateRenderPass;
PFN_vkDestroyRenderPass vkDestroyRenderPass;
PFN_vkGetRenderAreaGranularity vkGetRenderAreaGranularity;
PFN_vkCreateCommandPool vkCreateCommandPool;
PFN_vkDestroyCommandPool vkDestroyCommandPool;
PFN_vkResetCommandPool vkResetCommandPool;
PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers;
PFN_vkFreeCommandBuffers vkFreeCommandBuffers;
PFN_vkBeginCommandBuffer vkBeginCommandBuffer;
PFN_vkEndCommandBuffer vkEndCommandBuffer;
PFN_vkResetCommandBuffer vkResetCommandBuffer;
PFN_vkCmdBindPipeline vkCmdBindPipeline;
PFN_vkCmdSetViewport vkCmdSetViewport;
PFN_vkCmdSetScissor vkCmdSetScissor;
PFN_vkCmdSetLineWidth vkCmdSetLineWidth;
PFN_vkCmdSetDepthBias vkCmdSetDepthBias;
PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants;
PFN_vkCmdSetDepthBounds vkCmdSetDepthBounds;
PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask;
PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask;
PFN_vkCmdSetStencilReference vkCmdSetStencilReference;
PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets;
PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer;
PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers;
PFN_vkCmdDraw vkCmdDraw;
PFN_vkCmdDrawIndexed vkCmdDrawIndexed;
PFN_vkCmdDrawIndirect vkCmdDrawIndirect;
PFN_vkCmdDrawIndexedIndirect vkCmdDrawIndexedIndirect;
PFN_vkCmdDispatch vkCmdDispatch;
PFN_vkCmdDispatchIndirect vkCmdDispatchIndirect;
PFN_vkCmdCopyBuffer vkCmdCopyBuffer;
PFN_vkCmdCopyImage vkCmdCopyImage;
PFN_vkCmdBlitImage vkCmdBlitImage;
PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage;
PFN_vkCmdCopyImageToBuffer vkCmdCopyImageToBuffer;
PFN_vkCmdUpdateBuffer vkCmdUpdateBuffer;
PFN_vkCmdFillBuffer vkCmdFillBuffer;
PFN_vkCmdClearColorImage vkCmdClearColorImage;
PFN_vkCmdClearDepthStencilImage vkCmdClearDepthStencilImage;
PFN_vkCmdClearAttachments vkCmdClearAttachments;
PFN_vkCmdResolveImage vkCmdResolveImage;
PFN_vkCmdSetEvent vkCmdSetEvent;
PFN_vkCmdResetEvent vkCmdResetEvent;
PFN_vkCmdWaitEvents vkCmdWaitEvents;
PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier;
PFN_vkCmdBeginQuery vkCmdBeginQuery;
PFN_vkCmdEndQuery vkCmdEndQuery;
PFN_vkCmdResetQueryPool vkCmdResetQueryPool;
PFN_vkCmdWriteTimestamp vkCmdWriteTimestamp;
PFN_vkCmdCopyQueryPoolResults vkCmdCopyQueryPoolResults;
PFN_vkCmdPushConstants vkCmdPushConstants;
PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass;
PFN_vkCmdNextSubpass vkCmdNextSubpass;
PFN_vkCmdEndRenderPass vkCmdEndRenderPass;
PFN_vkCmdExecuteCommands vkCmdExecuteCommands;
PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR;
PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR;
PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
PFN_vkQueuePresentKHR vkQueuePresentKHR;
PFN_vkGetPhysicalDeviceDisplayPropertiesKHR vkGetPhysicalDeviceDisplayPropertiesKHR;
PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR vkGetPhysicalDeviceDisplayPlanePropertiesKHR;
PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR;
PFN_vkGetDisplayModePropertiesKHR vkGetDisplayModePropertiesKHR;
PFN_vkCreateDisplayModeKHR vkCreateDisplayModeKHR;
PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR;
PFN_vkCreateDisplayPlaneSurfaceKHR vkCreateDisplayPlaneSurfaceKHR;
PFN_vkCreateSharedSwapchainsKHR vkCreateSharedSwapchainsKHR;
#ifdef VK_USE_PLATFORM_XLIB_KHR
PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR;
PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR vkGetPhysicalDeviceXlibPresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR;
PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR vkGetPhysicalDeviceXcbPresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR;
PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_MIR_KHR
PFN_vkCreateMirSurfaceKHR vkCreateMirSurfaceKHR;
PFN_vkGetPhysicalDeviceMirPresentationSupportKHR vkGetPhysicalDeviceMirPresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_ANDROID_KHR
PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR;
#endif
#ifdef VK_USE_PLATFORM_WIN32_KHR
PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;
PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR;
#endif
PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT;
PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT;
PFN_vkDebugReportMessageEXT vkDebugReportMessageEXT;
@@ -1,236 +0,0 @@
// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This file is generated.
#ifndef VULKAN_WRAPPER_H
#define VULKAN_WRAPPER_H
#define VK_NO_PROTOTYPES 1
#include <vulkan/vulkan.h>
/* Initialize the Vulkan function pointer variables declared in this header.
* Returns 0 if vulkan is not available, non-zero if it is available.
*/
int InitVulkan(void);
// VK_core
extern PFN_vkCreateInstance vkCreateInstance;
extern PFN_vkDestroyInstance vkDestroyInstance;
extern PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
extern PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures;
extern PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties;
extern PFN_vkGetPhysicalDeviceImageFormatProperties vkGetPhysicalDeviceImageFormatProperties;
extern PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties;
extern PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties;
extern PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties;
extern PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
extern PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
extern PFN_vkCreateDevice vkCreateDevice;
extern PFN_vkDestroyDevice vkDestroyDevice;
extern PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
extern PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties;
extern PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties;
extern PFN_vkEnumerateDeviceLayerProperties vkEnumerateDeviceLayerProperties;
extern PFN_vkGetDeviceQueue vkGetDeviceQueue;
extern PFN_vkQueueSubmit vkQueueSubmit;
extern PFN_vkQueueWaitIdle vkQueueWaitIdle;
extern PFN_vkDeviceWaitIdle vkDeviceWaitIdle;
extern PFN_vkAllocateMemory vkAllocateMemory;
extern PFN_vkFreeMemory vkFreeMemory;
extern PFN_vkMapMemory vkMapMemory;
extern PFN_vkUnmapMemory vkUnmapMemory;
extern PFN_vkFlushMappedMemoryRanges vkFlushMappedMemoryRanges;
extern PFN_vkInvalidateMappedMemoryRanges vkInvalidateMappedMemoryRanges;
extern PFN_vkGetDeviceMemoryCommitment vkGetDeviceMemoryCommitment;
extern PFN_vkBindBufferMemory vkBindBufferMemory;
extern PFN_vkBindImageMemory vkBindImageMemory;
extern PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements;
extern PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements;
extern PFN_vkGetImageSparseMemoryRequirements vkGetImageSparseMemoryRequirements;
extern PFN_vkGetPhysicalDeviceSparseImageFormatProperties vkGetPhysicalDeviceSparseImageFormatProperties;
extern PFN_vkQueueBindSparse vkQueueBindSparse;
extern PFN_vkCreateFence vkCreateFence;
extern PFN_vkDestroyFence vkDestroyFence;
extern PFN_vkResetFences vkResetFences;
extern PFN_vkGetFenceStatus vkGetFenceStatus;
extern PFN_vkWaitForFences vkWaitForFences;
extern PFN_vkCreateSemaphore vkCreateSemaphore;
extern PFN_vkDestroySemaphore vkDestroySemaphore;
extern PFN_vkCreateEvent vkCreateEvent;
extern PFN_vkDestroyEvent vkDestroyEvent;
extern PFN_vkGetEventStatus vkGetEventStatus;
extern PFN_vkSetEvent vkSetEvent;
extern PFN_vkResetEvent vkResetEvent;
extern PFN_vkCreateQueryPool vkCreateQueryPool;
extern PFN_vkDestroyQueryPool vkDestroyQueryPool;
extern PFN_vkGetQueryPoolResults vkGetQueryPoolResults;
extern PFN_vkCreateBuffer vkCreateBuffer;
extern PFN_vkDestroyBuffer vkDestroyBuffer;
extern PFN_vkCreateBufferView vkCreateBufferView;
extern PFN_vkDestroyBufferView vkDestroyBufferView;
extern PFN_vkCreateImage vkCreateImage;
extern PFN_vkDestroyImage vkDestroyImage;
extern PFN_vkGetImageSubresourceLayout vkGetImageSubresourceLayout;
extern PFN_vkCreateImageView vkCreateImageView;
extern PFN_vkDestroyImageView vkDestroyImageView;
extern PFN_vkCreateShaderModule vkCreateShaderModule;
extern PFN_vkDestroyShaderModule vkDestroyShaderModule;
extern PFN_vkCreatePipelineCache vkCreatePipelineCache;
extern PFN_vkDestroyPipelineCache vkDestroyPipelineCache;
extern PFN_vkGetPipelineCacheData vkGetPipelineCacheData;
extern PFN_vkMergePipelineCaches vkMergePipelineCaches;
extern PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines;
extern PFN_vkCreateComputePipelines vkCreateComputePipelines;
extern PFN_vkDestroyPipeline vkDestroyPipeline;
extern PFN_vkCreatePipelineLayout vkCreatePipelineLayout;
extern PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout;
extern PFN_vkCreateSampler vkCreateSampler;
extern PFN_vkDestroySampler vkDestroySampler;
extern PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout;
extern PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout;
extern PFN_vkCreateDescriptorPool vkCreateDescriptorPool;
extern PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool;
extern PFN_vkResetDescriptorPool vkResetDescriptorPool;
extern PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets;
extern PFN_vkFreeDescriptorSets vkFreeDescriptorSets;
extern PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets;
extern PFN_vkCreateFramebuffer vkCreateFramebuffer;
extern PFN_vkDestroyFramebuffer vkDestroyFramebuffer;
extern PFN_vkCreateRenderPass vkCreateRenderPass;
extern PFN_vkDestroyRenderPass vkDestroyRenderPass;
extern PFN_vkGetRenderAreaGranularity vkGetRenderAreaGranularity;
extern PFN_vkCreateCommandPool vkCreateCommandPool;
extern PFN_vkDestroyCommandPool vkDestroyCommandPool;
extern PFN_vkResetCommandPool vkResetCommandPool;
extern PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers;
extern PFN_vkFreeCommandBuffers vkFreeCommandBuffers;
extern PFN_vkBeginCommandBuffer vkBeginCommandBuffer;
extern PFN_vkEndCommandBuffer vkEndCommandBuffer;
extern PFN_vkResetCommandBuffer vkResetCommandBuffer;
extern PFN_vkCmdBindPipeline vkCmdBindPipeline;
extern PFN_vkCmdSetViewport vkCmdSetViewport;
extern PFN_vkCmdSetScissor vkCmdSetScissor;
extern PFN_vkCmdSetLineWidth vkCmdSetLineWidth;
extern PFN_vkCmdSetDepthBias vkCmdSetDepthBias;
extern PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants;
extern PFN_vkCmdSetDepthBounds vkCmdSetDepthBounds;
extern PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask;
extern PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask;
extern PFN_vkCmdSetStencilReference vkCmdSetStencilReference;
extern PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets;
extern PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer;
extern PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers;
extern PFN_vkCmdDraw vkCmdDraw;
extern PFN_vkCmdDrawIndexed vkCmdDrawIndexed;
extern PFN_vkCmdDrawIndirect vkCmdDrawIndirect;
extern PFN_vkCmdDrawIndexedIndirect vkCmdDrawIndexedIndirect;
extern PFN_vkCmdDispatch vkCmdDispatch;
extern PFN_vkCmdDispatchIndirect vkCmdDispatchIndirect;
extern PFN_vkCmdCopyBuffer vkCmdCopyBuffer;
extern PFN_vkCmdCopyImage vkCmdCopyImage;
extern PFN_vkCmdBlitImage vkCmdBlitImage;
extern PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage;
extern PFN_vkCmdCopyImageToBuffer vkCmdCopyImageToBuffer;
extern PFN_vkCmdUpdateBuffer vkCmdUpdateBuffer;
extern PFN_vkCmdFillBuffer vkCmdFillBuffer;
extern PFN_vkCmdClearColorImage vkCmdClearColorImage;
extern PFN_vkCmdClearDepthStencilImage vkCmdClearDepthStencilImage;
extern PFN_vkCmdClearAttachments vkCmdClearAttachments;
extern PFN_vkCmdResolveImage vkCmdResolveImage;
extern PFN_vkCmdSetEvent vkCmdSetEvent;
extern PFN_vkCmdResetEvent vkCmdResetEvent;
extern PFN_vkCmdWaitEvents vkCmdWaitEvents;
extern PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier;
extern PFN_vkCmdBeginQuery vkCmdBeginQuery;
extern PFN_vkCmdEndQuery vkCmdEndQuery;
extern PFN_vkCmdResetQueryPool vkCmdResetQueryPool;
extern PFN_vkCmdWriteTimestamp vkCmdWriteTimestamp;
extern PFN_vkCmdCopyQueryPoolResults vkCmdCopyQueryPoolResults;
extern PFN_vkCmdPushConstants vkCmdPushConstants;
extern PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass;
extern PFN_vkCmdNextSubpass vkCmdNextSubpass;
extern PFN_vkCmdEndRenderPass vkCmdEndRenderPass;
extern PFN_vkCmdExecuteCommands vkCmdExecuteCommands;
// VK_KHR_surface
extern PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
extern PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
extern PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
extern PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
extern PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR;
// VK_KHR_swapchain
extern PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR;
extern PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
extern PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
extern PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
extern PFN_vkQueuePresentKHR vkQueuePresentKHR;
// VK_KHR_display
extern PFN_vkGetPhysicalDeviceDisplayPropertiesKHR vkGetPhysicalDeviceDisplayPropertiesKHR;
extern PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR vkGetPhysicalDeviceDisplayPlanePropertiesKHR;
extern PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR;
extern PFN_vkGetDisplayModePropertiesKHR vkGetDisplayModePropertiesKHR;
extern PFN_vkCreateDisplayModeKHR vkCreateDisplayModeKHR;
extern PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR;
extern PFN_vkCreateDisplayPlaneSurfaceKHR vkCreateDisplayPlaneSurfaceKHR;
// VK_KHR_display_swapchain
extern PFN_vkCreateSharedSwapchainsKHR vkCreateSharedSwapchainsKHR;
#ifdef VK_USE_PLATFORM_XLIB_KHR
// VK_KHR_xlib_surface
extern PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR;
extern PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR vkGetPhysicalDeviceXlibPresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
// VK_KHR_xcb_surface
extern PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR;
extern PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR vkGetPhysicalDeviceXcbPresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
// VK_KHR_wayland_surface
extern PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR;
extern PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_MIR_KHR
// VK_KHR_mir_surface
extern PFN_vkCreateMirSurfaceKHR vkCreateMirSurfaceKHR;
extern PFN_vkGetPhysicalDeviceMirPresentationSupportKHR vkGetPhysicalDeviceMirPresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_ANDROID_KHR
// VK_KHR_android_surface
extern PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR;
#endif
#ifdef VK_USE_PLATFORM_WIN32_KHR
// VK_KHR_win32_surface
extern PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;
extern PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR;
#endif
#ifdef USE_DEBUG_EXTENTIONS
#include <vulkan/vk_sdk_platform.h>
// VK_EXT_debug_report
extern PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT;
extern PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT;
extern PFN_vkDebugReportMessageEXT vkDebugReportMessageEXT;
#endif
#endif // VULKAN_WRAPPER_H
Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

@@ -1,7 +0,0 @@
package org.kenjinx.android
enum class BackendThreading {
Auto,
Off,
On
}
@@ -1,9 +0,0 @@
package org.kenjinx.android
import androidx.activity.ComponentActivity
abstract class BaseActivity : ComponentActivity() {
companion object {
val crashHandler = CrashHandler()
}
}

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