Compare commits

..

133 Commits

Author SHA1 Message Date
016262514d cpu: Hotfix missing ToNearest rounding mode cases 2023-07-16 20:39:08 +01:00
326749498b [Ryujinx.HLE] Address dotnet-format issues (#5380)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0052 warnings

* Address or silence dotnet format IDE1006 warnings

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA2208 warnings

* Address or silence dotnet format CA1806 and a few CA1854 warnings

* Address dotnet format CA2211 warnings

* Address dotnet format CA1822 warnings

* Address or silence dotnet format CA1069 warnings

* Make dotnet format succeed in style mode

* Address or silence dotnet format CA2211 warnings

* Address review comments

* Address dotnet format CA2208 warnings properly

* Make ProcessResult readonly

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Add previously silenced warnings back

I have no clue how these disappeared

* Revert formatting changes for while and for-loops

* Format if-blocks correctly

* Run dotnet format style after rebase

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Run dotnet format analyzers after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Disable 'prefer switch expression' rule

* Add comments to disabled warnings

* Fix a few disabled warnings

* Fix naming rule violation, Convert shader properties to auto-property and convert values to const

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Fix and silence a few dotnet-format warnings again

* Run dotnet format after rebase

* Use using declaration instead of block syntax

* Address IDE0251 warnings

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Fix naming rule violations

* Fix typo

* Add trailing commas, use targeted new and use array initializer

* Fix build issues

* Fix remaining build issues

* Remove SuppressMessage for CA1069 where possible

* Address dotnet format issues

* Address formatting issues

Co-authored-by: Ac_K <acoustik666@gmail.com>

* Add GetHashCode implementation for RenderingSurfaceInfo

* Explicitly silence CA1822 for every affected method in Syscall

* Address formatting issues in Demangler.cs

* Address review feedback

Co-authored-by: Ac_K <acoustik666@gmail.com>

* Revert marking service methods as static

* Next dotnet format pass

* Address review feedback

---------

Co-authored-by: Ac_K <acoustik666@gmail.com>
2023-07-16 19:31:14 +02:00
fec8291c17 infra: do not assign developers team for now
Hopefully fix PR triage for real...
2023-07-14 11:32:14 +02:00
c5d9e67cb2 Fix some Vulkan validation errors (#5452)
* Fix some validation errors and silence the annoying pipeline barrier error

* Remove bogus decref/incref on index buffer state

* Make unsafe blit opt-in rather than opt-out

* Remove Vulkan debugger messages blacklist

* Adjust GetImageUsage to not set the storage bit for multisample textures if not supported
2023-07-14 09:08:52 +02:00
e5261228d7 infra: Fix team name in reviewer.yml 2023-07-12 19:22:09 +02:00
e61c09bc85 infra: Fix PR triage once and for all (#5442)
Switch to a custom made python script that query GitHub API to grab latest state of the PR after label assign.
2023-07-12 18:31:08 +02:00
ac2444f908 Move ShaderBinaries into individual .spv files (#5280)
* Move ShaderBinaries into individual spv files

* Rename binaries directory, remove variables and add helper method instead

* Update .csproj file

* Move ShaderBinaries into individual spv files

* Rename binaries directory, remove variables and add helper method instead

* Split shader binaries into folders, use string.Join to create filepath

* Move files back to general binaries folder

* Remove ShaderSource suffix from file names

---------

Co-authored-by: Egor Alekseychik <e.alekseychik@syberry.com>
Co-authored-by: Gabriel A <gab.dark.100@gmail.com>
2023-07-11 14:41:18 -03:00
9c6071a645 Move support buffer update out of the backends (#5411)
* Move support buffer update out of the backends

* Fix render scale init and remove redundant state from SupportBufferUpdater

* Stop passing texture scale to the backends

* XML docs for SupportBufferUpdater
2023-07-11 14:07:41 -03:00
fa32ef9275 MacOS: Allow barriers inside a render pass for non-Apple GPUs and don't treat as TBDR (#5440)
* MoltenVK: Allow barriers inside a render pass on non-Apple GPUs

* Don't treat all non-Apple GPUs using MoltenVK as TBDR
2023-07-11 03:10:23 +02:00
7805d27e67 MacOS: Fix rendering on AMD GPUs (#5446)
* MacOS: Fix rendering on AMD GPUs

* Only disable MultiViewPort on MoltenVK for AMD GPUs
2023-07-11 03:00:19 +02:00
6c515e1822 [Ryujinx.Ava] Address dotnet-format issues (#5361)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0052 warnings

* Silence dotnet format IDE0059 warnings

* Address or silence dotnet format IDE1006 warnings

* Address dotnet format CA1816 warnings

* Address dotnet format CA1822 warnings

* Address or silence dotnet format CA1069 warnings

* Make dotnet format succeed in style mode

* Address dotnet format CA1401 warnings

* Address remaining dotnet format analyzer warnings

* Address review comments

* dotnet-format fixes after rebase

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Another rebase, another dotnet format run

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Remove a few unused parameters

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Fix and silence a few dotnet-format warnings again

* Address IDE0260 warnings

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* dotnet format pass with new editorconfig

* Fix naming style issues

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Revert one suggestion

* Second dotnet format pass and fix build issues

* Final pass of dotnet format

* Add trailing commas

* Fix formatting issues

* Keep unnecessary assignment in IconColorPicker.cs

* Use using declarations and extend resource lifetimes

* Fix rebase issues

* Adjust comment spacing

* Fix typo

* Fix naming issues

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Revert unintentional change

* Remove unused file

* Remove static keyword from ViewModels

Binding of static members doesn't work and is silently ignored.

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-07-07 23:03:27 +02:00
8a363b5df2 Revert "sdl: set SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS to 0 (#5433)" (#5439)
This reverts commit 2b5abac809.
2023-07-06 18:08:14 +02:00
2b5abac809 sdl: set SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS to 0 (#5433)
Nintendo controllers notoriously have the A/B and X/Y buttons swapped, compared to the standard.
In order to combat this, when setting the default controller layout, Ryujinx checks whether the controller name contains "Nintendo", and swaps the mapping accordingly.
However, the reason the mapping is inverted in the first place is because SDL has `SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS` set to 1 by default. By setting it to 0, the mapping will be based on the buttons' position instead.
So, by doing it (and removing the `isNintendoStyle` variable), we get the following advantages:
- The mapping will be the same on all controllers, removing the need to adjust custom mappings depending on what controller is used
- Users who already set `SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS` to 0 globally for other games/applications (like me) won't have a wrong default mapping
- Checking whether the controller name contains "Nintendo" is ugly

Disadvantages:
- Breaks the controller configuration for existing users who are using a Nintendo controller
2023-07-06 17:11:26 +02:00
c19c8bbade Headless: Add support for fullscreen option (#5339)
* Headless: Added support for fullscreen option

* Headless: cleanup of fullscreen support

* Headless: fullscreen support : implemented proposed changes

* Headless: fullscreen support: cleanup

* Headless: fullscreen support: fix for OpenGL scaling

* Headless: fullscreen support: cleanup

* Headless: fullscreen support: cleanup

* Headless: fullscreen support: add. macOS fullscreen fix

* Headless: fullscreen support: cleanup

* Headless: fullscreen support: cleanup

* Headless: fullscreen support: cleanup
2023-07-06 12:10:15 +02:00
1c7a90ef35 Stop identifying shader textures with handle and cbuf, use binding instead (#5266)
* Stop identifying shader textures with handle and cbuf, use binding instead

* Remove now unused code

* Consider image operations as having accurate type information too

I don't know why that was not the case before

* Fix missing unscale on InsertCoordNormalization, stop calling SetUsageFlagsForTextureQuery when not needed

* Shader cache version bump

* Change get texture methods to return descriptors created from ResourceManager state

 This is required to ensure that reserved textures and images will not be bound as a guest texture/image

* Fix BindlessElimination.SetHandle inserting coords at the wrong place
2023-07-03 14:29:27 -03:00
3b46bb73f7 [Ryujinx.Graphics.Gpu] Address dotnet-format issues (#5367)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0052 warnings

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA1069 warnings

* Address or silence dotnet format CA2211 warnings

* Address remaining dotnet format analyzer warnings

* Address review comments

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Another rebase, another dotnet format run

* Run dotnet format style after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Disable 'prefer switch expression' rule

* Add comments to disabled warnings

* Remove a few unused parameters

* Replace MmeShadowScratch with Array256<uint>

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Fix and silence a few dotnet-format warnings again

* Run dotnet format after rebase

* Address IDE0251 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First pass of dotnet format

* Add unsafe dotnet format changes

* Fix typos

* Add trailing commas

* Disable formatting for FormatTable

* Address review feedback
2023-07-02 02:47:54 +02:00
2457cfc911 Fix naming issue in ControllerWindow (#5424) 2023-07-02 02:26:32 +02:00
515fc32b21 [Ryujinx.Audio] Address dotnet-format issues (#5362)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0052 warnings

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA2208 warnings

* Address or silence dotnet format CA2211 warnings

* Address review comments

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Run dotnet format whitespace after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Remove a few unused parameters

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Fix and silence a few dotnet-format warnings again

* Address IDE0251 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Fix naming rule violations, remove redundant code and fix build issues

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Add trailing commas

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Address review feedback

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-07-02 01:27:18 +02:00
0684b00b3c [Ryujinx] Address dotnet-format issues (#5395)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA2208 warnings

* Address or silence dotnet format CA1806 and a few CA1854 warnings

* Address dotnet format CA1822 warnings

* Make dotnet format succeed in style mode

* Address dotnet format CA2208 warnings properly

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Another rebase, another dotnet format run

* Run dotnet format whitespace after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Fix build issues

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Second dotnet format pass

* Update src/Ryujinx/Modules/Updater/Updater.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Add trailing commas and improve formatting

* Fix formatting and naming issues

* Rename nvStutterWorkaround to nvidiaStutterWorkaround

* Use using declarations and extend resource lifetimes

* Fix GTK issues

* Add formatting for generated files

* Add trailing commas

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-07-02 00:25:07 +02:00
02b5c7ea89 [Ryujinx.Horizon] Address dotnet-format issues (#5381)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0052 warnings

* Address dotnet format CA1822 warnings

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Revert formatting changes for while and for-loops

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Remove a few unused parameters

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Address IDE0251 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Add trailing commas and fix formatting issues

* Convert if-else chain to switch block

* Address review feedback
2023-07-01 12:42:10 +02:00
801b71a128 [Ryujinx.Graphics.Vulkan] Address dotnet-format issues (#5378)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0059 warnings

* Address dotnet format CA1816 warnings

* Fix new dotnet-format issues after rebase

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Another rebase, another dotnet format run

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Run dotnet format analyzers after rebase

* Run dotnet format style after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Disable 'prefer switch expression' rule

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Run dotnet format after rebase

* Address IDE0251 warnings

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Fix naming rule violations

* Remove redundant code

* Rename generics

* Address review feedback

* Remove SetOrigin
2023-07-01 12:31:42 +02:00
12c5f6ee89 Indexing at 0 should be used instead of the "Enumerable" extension method "First" (#5354) 2023-07-01 06:29:37 +00:00
79a1314ee4 [Ryujinx.Cpu] Address dotnet-format issues (#5365)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0052 warnings

* Silence dotnet format IDE0059 warnings

* Address or silence dotnet format IDE1006 warnings

* Address dotnet format CA1816 warnings

* Address most dotnet format whitespace warnings

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Remove a few unused parameters

* Adjust namespaces

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Fix and silence a few dotnet-format warnings again

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Address review feedback

* Remove redundant unsafe modifiers

* Fix build issues

* Add GC.SuppressFinalize() call

* Add trailing commas and fix naming rule violations

* Remove unused members and assignments
2023-07-01 02:18:52 +00:00
e9848339dd [Ryujinx.Tests] Address dotnet-format issues (#5389)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Fix new dotnet-format issues after rebase

* Address review comments

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* cpu tests: Disable CA2211 for CodeBaseAddress and DataBaseAddress

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* First dotnet format pass

* Fix naming rule violations

* Remove naming rule violation exceptions

* Fix comment style

* Use targeted new

* Remove redundant code

* Remove comment alignment

* Remove naming rule exceptions

* Add trailing commas

* Use nameof expression

* Reformat to add remaining trailing commas

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-07-01 02:14:34 +00:00
6e28a4dd13 [Ryujinx.Ui.Common] Address dotnet-format issues (#5392)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Silence dotnet format IDE0060 warnings

* Address dotnet format CA1401 warnings

* dotnet-format fixes after rebase

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Another rebase, another dotnet format run

* Run dotnet format style after rebase

* Add comments to disabled warnings

* Remove a few unused parameters

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Address IDE0251 warnings

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Small optimizations

* Remove alignment

* Apply formatting

* Fix build issues

* Final pass for dotnet format

* Add trailing commas

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Add trailing commas

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-29 02:39:22 +02:00
7c989f88bd [Ryujinx.Graphics.GAL] Address dotnet-format issues (#5366)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0052 warnings

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA1069 warnings

* Address remaining dotnet format analyzer warnings

* Address review comments

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Revert formatting changes for while and for-loops

* Another rebase, another dotnet format run

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Run dotnet format analyzers after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Disable 'prefer switch expression' rule

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Address IDE0251 warnings

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Address review feedback

* Add trailing commas

* Remove SuppressMessage for IDE0066

* Make explicit Equals implementation implicit
2023-06-28 20:20:10 +02:00
16fa983704 macOS: Fix warning in some shell scripts (#5398)
* macOS: Fix warning in some shell scripts

In a way to continue the cleaning of the project, there are some warnings which can be easily fixed.

* Try to fix CI

* Fix APP_ARGUMENTS

* Addresses feedback
2023-06-28 19:09:48 +02:00
40daca5684 [Ryujinx.Headless.SDL2] Address dotnet-format issues (#5379)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Address or silence dotnet format CA1806 and a few CA1854 warnings

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Add trailing commas

* Fix naming and formatting issues
2023-06-28 19:03:27 +02:00
981e0c082d [Spv.Generator] Address dotnet-format issues (#5394)
* dotnet format style --severity info

Some changes were manually reverted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0052 warnings

* Address or silence dotnet format IDE1006 warnings

* Address or silence dotnet format CA1069 warnings

* Address review comments

* Address most dotnet format whitespace warnings

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Address IDE0251 warnings

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Rename Operand.cs to IOperand.cs

* Update src/Spv.Generator/Module.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Remove NotNullWhen attribute and use conditional access to avoid NRE

* Fix duplicated enum values

* Remove unread member

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-28 18:54:20 +02:00
cebfa54467 [Ryujinx.Graphics.Texture] Address dotnet-format issues (#5375)
* dotnet format style --severity info

Some changes were manually reverted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0059 warnings

* Address or silence dotnet format CA2208 warnings

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Address IDE0251 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Address review feedback

* Update src/Ryujinx.Graphics.Texture/Astc/AstcDecoder.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-28 18:46:18 +02:00
fc20d9b925 [Ryujinx.Common] Address dotnet-format issues (#5358)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0059 warnings

* Address or silence dotnet format IDE1006 warnings

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA2211 warnings

* Silence CA1806 and CA1834 issues

* Fix formatting for switch expressions

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Revert formatting changes for while and for-loops

* Format if-blocks correctly

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Run dotnet format analyzers after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Remove a few unused parameters

* Replace MmeShadowScratch with Array256<uint>

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Run dotnet format after rebase

* Address IDE0251 warnings

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Second dotnet format pass

* Fix build issues

* Fix StructArrayHelpers.cs

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Fix return statements

* Fix naming rule violations

* Update src/Ryujinx.Common/Utilities/StreamUtils.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Add trailing commas

* Address review feedback

* Address review feedback

* Rename remaining type parameters to TKey and TValue

* Fix manual formatting for logging levels

* Fix spacing before comments

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-28 18:41:38 +02:00
0a75b73fa4 [Ryujinx.Memory] Address dotnet-format issues (#5386)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Silence dotnet format IDE0059 warnings

* Address or silence dotnet format IDE1006 warnings

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA1069 warnings

* Address remaining dotnet format analyzer warnings

* Address review comments

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Another rebase, another dotnet format run

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Address review feedback

* Assign Decommit to ReplacePlaceholder

* Run final dotnet format pass

* Organize imports again

* Add trailing commas

* Add missing newline
2023-06-28 18:34:00 +02:00
46b7c905f5 [Ryujinx.Input] Address dotnet-format issues (#5384)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA1806 and a few CA1854 warnings

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Remove redundant code, convert to auto-properties and fix naming rule violations

* Remove bogus change

* Address review feedback
2023-06-28 18:23:00 +02:00
40f2bd37e3 [Ryujinx.Graphics.OpenGL] Address dotnet-format issues (#5372)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Address or silence dotnet format IDE1006 warnings

* Fix IDE0090 after rebase

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Another rebase, another dotnet format run

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Address review feedback
2023-06-28 18:10:55 +02:00
9288ffd26d Cpu: Implement VCVT (between floating-point and fixed-point) instruction (#5343)
* cpu: Implement VCVT (between floating-point and fixed-point) instruction

Rebase, fix and superseed of https://github.com/Ryujinx/Ryujinx/pull/2915

(Since I only have little CPU knowledge, I hope I have done everything good)

* Update Ptc.cs

* Fix wrong cast

* Rename tests

* Addresses feedback

Co-Authored-By: gdkchan <5624669+gdkchan@users.noreply.github.com>

* Remove extra empty line

---------

Co-authored-by: gdkchan <5624669+gdkchan@users.noreply.github.com>
2023-06-28 17:36:30 +02:00
2cdc82cb91 nuget: bump Microsoft.NET.Test.Sdk from 17.6.2 to 17.6.3 (#5406)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.6.2 to 17.6.3.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.6.2...v17.6.3)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-28 09:36:22 +02:00
6aa8d71588 [Ryujinx.Graphics.Nvdec.Vp9] Address dotnet-format issues (#5371)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Address or silence dotnet format IDE1006 warnings

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Address IDE0251 warnings

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Fix empty lines before return

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Add trailing commas, remove redundant code and remove static modifier from Surface.HighBd

* Fix naming rule violations

* Fix naming rule violations

* Fix empty line before return

* Fix comment style

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Remove comment alignment

* Address review feedback

* Separate comments by 2 spaces and fix other formatting issues

* Make HighBd an auto-property

* Replace if-chain with if-else-chain

* Fix new naming rule violations

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-28 09:26:39 +02:00
9becbd7d72 [Ryujinx.Graphics.Shader] Address dotnet-format issues (#5373)
* dotnet format style --severity info

Some changes were manually reverted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0052 warnings

* Silence dotnet format IDE0059 warnings

* Address or silence dotnet format CA1069 warnings

* Address or silence dotnet format CA2211 warnings

* Address review comments

* Fix formatting for switch expressions

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Disable 'prefer switch expression' rule

* Add comments to disabled warnings

* Fix naming rule violation, Convert shader properties to auto-property and convert values to const

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Run dotnet format after rebase

* Address IDE0251 warnings

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

* Run dotnet format after rebase

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Fix naming rule violations

* Add trailing commas

* Remove unused members and most unnecessary value assignments

* Remove more unnecessary assignments

* Remove NRE suppressor
2023-06-28 08:59:13 +02:00
e055217292 [Ryujinx.Horizon.Kernel.Generators] Address dotnet-format issues (#5376)
* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Run dotnet format pass

* Remove left-over files and adjust namespaces

* Fix alignment
2023-06-27 23:27:48 +00:00
fbaf62c230 Apply new naming rule to all projects except Vp9 (#5407) 2023-06-28 01:18:19 +02:00
b186ec9fc5 [Ryujinx.Graphics.Video] Address dotnet-format issues (#5377)
* Address most dotnet format whitespace warnings

* dotnet format whitespace after rebase
2023-06-27 16:45:33 +02:00
0191e2396a [Ryujinx.Graphics.Host1x] Address dotnet-format issues (#5368)
* dotnet format style --severity info

Some changes were manually reverted.

* Address most dotnet format whitespace warnings

* Add comments to disabled warnings

* dotnet format whitespace after rebase
2023-06-27 16:35:48 +02:00
e96299eef5 [Ryujinx.Horizon.Generators] Address dotnet-format issues (#5383)
* dotnet format style --severity info

Some changes were manually reverted.

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* dotnet format whitespace after rebase
2023-06-26 07:35:19 +02:00
ff53dcf560 [ARMeilleure] Address dotnet-format issues (#5357)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0052 warnings

* Address or silence dotnet format IDE1006 warnings

* Address or silence dotnet format CA2208 warnings

* Address dotnet format CA1822 warnings

* Address or silence dotnet format CA1069 warnings

* Silence CA1806 and CA1834 issues

* Address dotnet format CA1401 warnings

* Fix new dotnet-format issues after rebase

* Address review comments

* Address dotnet format CA2208 warnings properly

* Fix formatting for switch expressions

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Add previously silenced warnings back

I have no clue how these disappeared

* Revert formatting changes for OpCodeTable.cs

* Enable formatting for a few cases again

* Format if-blocks correctly

* Enable formatting for a few more cases again

* Fix inline comment alignment

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Disable 'prefer switch expression' rule

* Add comments to disabled warnings

* Remove a few unused parameters

* Adjust namespaces

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Fix and silence a few dotnet-format warnings again

* Address IDE0251 warnings

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Remove unnecessary formatting exclusion

* Add unsafe dotnet format changes

* Change visibility of JitSupportDarwin to internal
2023-06-26 07:25:06 +02:00
2de78a2d55 [Ryujinx.Input.SDL2] Address dotnet-format issues (#5385)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0052 warnings

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA1806 and a few CA1854 warnings

* Address most dotnet format whitespace warnings

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Add trailing commas, log errors instead of throwing and remove redundant code
2023-06-26 01:55:25 +00:00
b29ded1d60 [Ryujinx.SDL2.Common] Address dotnet-format issues (#5387)
* dotnet format style --severity info

Some changes were manually reverted.

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA1806 and a few CA1854 warnings

* Address most dotnet format whitespace warnings

* dotnet format whitespace after rebase
2023-06-26 01:51:16 +00:00
9860bfb2cd misc: memory: Migrate from OutOfMemoryException to SystemException entirely (#5399)
Fix a regression with address space allocation while providing more
information about the context of the exception.
2023-06-26 01:37:12 +00:00
f6ada8d169 [Ryujinx.Graphics.Device] Address dotnet-format issues (#5363)
* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Address most dotnet format whitespace warnings

* dotnet format whitespace after rebase
2023-06-25 23:58:44 +02:00
42d31f646d [Ryujinx.Audio.Backends.SDL2] Address dotnet-format issues (#5364)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Address dotnet format CA1816 warnings

* Address most dotnet format whitespace warnings

* Run dotnet format style after rebase

* Run dotnet format analyzers after rebase

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Update src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceDriver.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-25 22:50:59 +02:00
07fc3ded68 [Ryujinx.Graphics.Nvdec] Address dotnet-format issues (#5369)
* dotnet format style --severity info

Some changes were manually reverted.

* Restore a few unused methods and variables

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Add previously silenced warnings back

I have no clue how these disappeared

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Address IDE0251 warnings

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass
2023-06-25 21:44:42 +02:00
fd01259d2b [Ryujinx.ShaderTools] Address dotnet-format issues (#5388)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format whitespace after rebase
2023-06-25 21:37:33 +02:00
7ffe7f8442 [Ryujinx.Graphics.Nvdec.FFmpeg] Address dotnet-format issues (#5370)
* dotnet format style --severity info

Some changes were manually reverted.

* Address or silence dotnet format CA1806 and a few CA1854 warnings

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Address IDE0251 warnings

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass
2023-06-25 19:03:48 +02:00
2b2ce68f07 [Ryujinx.Tests.Memory] Address dotnet-format issues (#5390)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Address dotnet format CA1822 warnings

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Final dotnet format pass and fix naming rule violations

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Remove unused constant

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-25 18:37:53 +02:00
bc53d00463 [Ryujinx.Graphics.Vic] Address dotnet-format issues (#5374)
* dotnet format style --severity info

Some changes were manually reverted.

* Restore a few unused methods and variables

* Address review comments

* Address most dotnet format whitespace warnings

* Add comments to disabled warnings

* Address IDE0251 warnings

* dotnet format whitespace after rebase

* Remove SuppressMessage attribute for removed rule
2023-06-25 18:37:09 +02:00
bddb2a1483 [Ryujinx.Tests.Unicorn] Address dotnet-format issues (#5391)
* dotnet format style --severity info

Some changes were manually reverted.

* Restore a few unused methods and variables

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Final dotnet format pass and fix naming rule violations
2023-06-25 18:03:08 +02:00
e3bacfa774 Set COMPlus_DefaultStackSize to 2M in macOS (#5349)
* Set COMPlus_DefaultStackSize to 2M in macOS

* Remove the custom thread stack size on Ryujinx.Ava
2023-06-25 14:49:53 +02:00
7c2f07d124 [Ryujinx.Horizon.Common] Address dotnet-format issues (#5382)
* dotnet format style --severity info

Some changes were manually reverted.

* Address most dotnet format whitespace warnings

* Address IDE0251 warnings

* dotnet format whitespace after rebase
2023-06-25 13:40:37 +02:00
ede5b3c324 [Ryujinx.Audio.Backends.SoundIo] Address dotnet-format issues (#5360)
* dotnet format style --severity info

Some changes were manually reverted.

* Address dotnet format CA1816 warnings

* Address dotnet format CA1401 warnings

* Address most dotnet format whitespace warnings

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Address review feedback
2023-06-25 02:15:56 +02:00
df5be5812f [Ryujinx.Audio.Backends.OpenAL] Address dotnet-format issues (#5359)
* dotnet format style --severity info

Some changes were manually reverted.

* Restore a few unused methods and variables

* Address dotnet format CA1816 warnings

* Address most dotnet format whitespace warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase
2023-06-25 01:29:40 +02:00
bc392e55df Empty "case" clauses that fall through to the "default" should be omitted (#5353)
* Empty "case" clauses that fall through to the "default" should be omitted

* default throw exception

* format
2023-06-24 12:06:58 +00:00
fffc3ed193 Mutable fields should not be "public static" (#5352) 2023-06-24 12:01:59 +00:00
7d160e98fd MemoryManagement: Change return types for Commit/Decommit to void (#5325)
* Replace return type with void for Commit/Decommit

* Small cleanup
2023-06-24 02:46:04 +02:00
bf96bc84a8 "Where" should be used before "OrderBy" (#5346) 2023-06-23 00:51:44 +00:00
91e4caaa69 "StartsWith" and "EndsWith" overloads that take a "char" should be used instead of the ones that take a "string" (#5347) 2023-06-23 02:15:14 +02:00
efbd29463d "Find" method should be used instead of the "FirstOrDefault" extension (#5344) 2023-06-23 01:42:23 +02:00
7608cb37ab "Exists" method should be used instead of the "Any" extension (#5345) 2023-06-23 01:37:25 +02:00
d604e98227 Fix regression introduced by 1.1.1733 on Intel GPUs (#5311)
* Fix regression introduced by 1.1733 on Intel iGPUs

* Should have actually figured the variable, oops.

* maybe something goes wrong here? honestly lost

* Shader cache bump
2023-06-22 21:35:06 +02:00
58907e2c29 GetHashCode should not reference mutable fields (#5331) 2023-06-22 18:36:07 +02:00
649d372f7d misc: Implement address space size workarounds (#5191)
* misc: Implement address space size workarounds

This adds code to support userland with less than 39 bits of address
space available by testing reserving multiple sizes and reducing
guess address space when needed.

This is required for ARM64 support when the kernel is
configured to use 63..39 bits for kernel space.(meaning only 38 bits is available to userland)

* Address comments

* Fix 32 bits address space support and address more comments
2023-06-20 17:33:54 +02:00
f9a538bb0f Ensure shader local and shared memory sizes are not zero (#5321) 2023-06-17 16:28:27 -03:00
f92921a6d1 Implement Load/Store Local/Shared and Atomic shared using new instructions (#5241)
* Implement Load/Store Local/Shared and Atomic shared using new instructions

* Remove now unused code

* Fix base offset register overwrite

* Fix missing storage buffer set index when generating GLSL for Vulkan

* Shader cache version bump

* Remove more unused code

* Some PR feedback
2023-06-15 17:31:53 -03:00
32d21ddf17 Inheritance list should not be redundant (#5230) 2023-06-15 03:54:27 +00:00
82f90704a0 Blocks should be synchronized on read-only fields (#5212)
* Blocks should be synchronized on read-only fields

* more readonlys

* fix alignment

* more

* Update ISelfController.cs

* simplify new

* simplify new
2023-06-15 00:34:55 +00:00
f978d3726a nuget: bump System.Management from 7.0.1 to 7.0.2 (#5302)
Bumps [System.Management](https://github.com/dotnet/runtime) from 7.0.1 to 7.0.2.
- [Release notes](https://github.com/dotnet/runtime/releases)
- [Commits](https://github.com/dotnet/runtime/compare/v7.0.1...v7.0.2)

---
updated-dependencies:
- dependency-name: System.Management
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-14 18:21:17 +02:00
6f28c4abad test: Make tests runnable on system without 4KiB page size (#5184)
* ARMeilleure: Do not hardcode 4KiB page size in JitCache

* test: Do not hardcode page size to 4KiB for Ryujinx.Tests.Memory.Tests

Fix running tests on Asahi Linux with 16KiB pages.

* test: Do not hardcode page size to 4KiB for Ryujinx.Tests.Cpu

Fix running tests on Asahi Linux.

Test runner still crash when trying to run all test suite.

* test: Do not hardcode page size to 4KiB for Ryujinx.Tests.Cpu

Fix somecrashes on Asahi Linux.

* test: Ignore Vshl test on ARM64 due to unicorn crashes

* test: Workaround hardcoded size on some tests

Change mapping of code and data in case of non 4KiB configuration.

* test: Make CpuTestT32Flow depends on code address

Fix failure with different page size.

* test: Disable CpuTestThumb.TestRandomTestCases when page size isn't 4KiB

The test data needs to be reevaluated to take different page size into account.

* Address gdkchan's comments
2023-06-14 18:02:41 +02:00
105c9712c1 Fix Arm32 double to int/uint conversion on Arm64 (#5292)
* Fix Arm32 double to int/uint conversion on Arm64

* PPTC version bump
2023-06-14 00:57:02 -03:00
4d804ed45e Mod Loader: Stop loading mods from folders that don't exactly match titleId (#5298)
* Stop loading mods from folders that don't exactly match titleId

* What the worst that can happen?
2023-06-13 20:47:33 +02:00
4a27d29412 infra: Sync paths-ignore with release job and attempt to fix review assign 2023-06-13 11:51:22 +02:00
5bd2c58ad6 UI: Correctly set 'shell/open/command; registry key for file associations (#5244)
* Correctly set 'shell/open/command; registry key for file associations

* File association fixes
* 'using' statements instead of blocks
* Idempotent unregistration
* Single "hey shell, we changed file associations" notification at the
  end instead of 1 for every operation, speeds things up greatly.

* Adapt and fix Linux specific function as well

---------

Co-authored-by: TSR Berry <20988865+TSRBerry@users.noreply.github.com>
2023-06-13 00:36:40 +00:00
cf4c78b9c8 Make LM skip instead of crashing for invalid messages (#5290) 2023-06-13 00:12:06 +00:00
52aa4b6c22 Fix action version (#5299) 2023-06-12 21:57:07 +02:00
5a02433080 infra: Fix PR triage workflow glob patterns (#5297)
* Use glob patterns to match file paths

* Update ignored paths for releases

* Adjust build.yml as well

* Add names to auto-assign steps

* Fix developer team name

* Allow build workflows to run if workflows changed
2023-06-12 18:42:27 +00:00
915a0f7173 hle: Stub IHidbusServer.GetBusHandle (#5284) 2023-06-12 17:33:13 +02:00
0cc266ff19 infra: Add PR triage action (#5293)
This is a bare minimal triage action that handle big categories.

In the future we could also label all services correctly but
I didn't felt this was required for a first iteration.
2023-06-12 12:29:41 +02:00
9a1b74799d Ava: Fix OpenGL on Linux again (#5216)
* ava: Fix OpenGL on Linux again

This shouldn't be working like that, but for some reason it does.

* Apply the correct fix

* gtk: Add warning messages for caught exceptions

* ava: Handle disposing the same way as GTK does

* Address review feedback
2023-06-11 18:31:22 +02:00
638f3761f3 Show/Hide UI Hotkey fix on Avalonia (#5133)
* fix show/hide ui for ava

* revert style

* unbound by default

* revert
2023-06-11 15:34:56 +02:00
193ca3c9a2 Implement fast path for AES crypto instructions on Arm64 (#5281)
* Implement fast path for AES crypto instructions on Arm64

* PPTC version bump

* Use AES HW feature check
2023-06-11 00:51:35 +00:00
eb0bb36bbf Implement transform feedback emulation for hardware without native support (#5080)
* Implement transform feedback emulation for hardware without native support

* Stop doing some useless buffer updates and account for non-zero base instance

* Reduce redundant updates even more

* Update descriptor init logic to account for ResourceLayout

* Fix transform feedback and storage buffers not being updated in some cases

* Shader cache version bump

* PR feedback

* SetInstancedDrawVertexCount must be always called after UpdateState

* Minor typo
2023-06-10 18:31:38 -03:00
0e95a8271a Non-flags enums should not be used in bitwise operations (#5214) 2023-06-09 19:44:22 +02:00
76b474e97b Update ShaderConfig.cs (#5226) 2023-06-09 14:53:20 +00:00
27ee86f33b Exclude macOS from checking for changed files (#5270) 2023-06-09 15:35:24 +02:00
f7ec310231 Check if existing oldConfigPath is a Symlink (#5271) 2023-06-09 15:31:19 +02:00
e94d24f508 Prefer a 'TryGetValue' call over a Dictionary indexer access guarded by a 'ContainsKey' (#5231)
* Prefer a 'TryGetValue' call over a Dictionary indexer access guarded by a 'ContainsKey' check to avoid double lookup

* fix
2023-06-09 13:05:32 +02:00
2bf4555591 Swkbd Applet Fixes (#5236)
* Swkbd Applet Fixes

* Forgot a full stop

* Update src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Update src/Ryujinx/Ui/Applet/SwkbdAppletDialog.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-09 12:11:53 +02:00
86de288142 Removing shift by 0 (#5249)
* Integral numbers should not be shifted by zero or more than their number of bits-1

* more
2023-06-09 11:23:44 +02:00
f35aa8e9d6 nuget: bump Microsoft.NET.Test.Sdk from 17.6.1 to 17.6.2 (#5250)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.6.1 to 17.6.2.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.6.1...v17.6.2)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-09 11:02:56 +02:00
0e8e735a6d nuget: bump System.IdentityModel.Tokens.Jwt from 6.30.1 to 6.31.0 (#5265)
Bumps [System.IdentityModel.Tokens.Jwt](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet) from 6.30.1 to 6.31.0.
- [Release notes](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/releases)
- [Changelog](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/compare/6.30.1...6.31.0)

---
updated-dependencies:
- dependency-name: System.IdentityModel.Tokens.Jwt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-09 10:40:25 +02:00
0003a7c118 Vulkan: Use aspect flags for identity views for bindings (#5267) 2023-06-08 20:23:36 -03:00
2cdcfe46d8 Remove barrier on Intel if control flow is potentially divergent (#5044)
* Remove barrier on Intel if control flow is potentially divergent

* Shader cache version bump
2023-06-08 17:43:16 -03:00
fe30c03cac Implement soft float64 conversion on shaders when host has no support (#5159)
* Implement soft float64 conversion on shaders when host has no support

* Shader cache version bump

* Fix rebase error
2023-06-08 17:09:14 -03:00
5813b2e354 Updater: Ignore files introduced by the user in base directory (#5092)
* Updater: Ignore files introduced by the user in base directory

* Replicate logic in Avalonia version.

* Address requested changes

* Updater: Ignore files introduced by the user in base directory

* Replicate logic in Avalonia version.

* Address requested changes

* Address requested changes

* Address requested changes

* Comment cleanup

* Address feedback

* Forgot comment, tehe
2023-06-05 14:19:17 +02:00
af1906ea04 Fix wrong unaligned SB state when fetching compute shaders (#5223) 2023-06-05 14:01:33 +02:00
68848000f7 Texture: Fix 3D texture size when totalBlocksOfGobsInZ > 1 (#5228)
* Texture: Fix 3D texture size when totalBlocksOfGobsInZ > 0

When there is a remainder when dividing depth by gobs in z, it is used to remove the unused part of the 3D texture's size. This was done to calculate correct sizes for single slice views of 3D textures.

However, this case can also apply to 3D textures with many slices, and more than one total block of gobs in z. In this case it's meant to trim off the end of the level size. Most textures won't encounter this as their size will be aligned, but UE4 games tend to use 3D textures with funny unaligned sizes.

The size offset should have been applied to the level size instead of the slice size, and it should only affect the slice size if it ends up larger.

Hopefully should fix issues with UE4 games without breaking other stuff, I don't have much time to test.

* Whoops
2023-06-05 13:33:09 +02:00
d98da47a0f Better application grid flex (#5218) 2023-06-05 00:48:11 +00:00
306f7e93a0 Dont Error on Invalid Enum Values (#5169)
* Dont Error on Invalid Enum

* Use TryParse

* Log warning
2023-06-05 01:19:46 +02:00
8954ff3af2 Replacing ZbcColorArray with Array4<uint> (#5210)
* Related "if/else if" statements should not have the same condition

* replacing ZbcColorArray with Array4<uint>

* fix alignment
2023-06-04 20:30:04 +00:00
d2f3adbf69 Texture: Fix layout conversion when gobs in z is used with depth = 1 (#5220)
* Texture: Fix layout conversion when gobs in z is used with depth = 1

The size calculator methods deliberately reduce the gob size of textures if they are deemed too small for it. This is required to get correct sizes when iterating mip levels of a texture.

Rendering to a slice of a 3D texture can produce a 3D texture with depth 1, but a gob size matching a much larger texture. We _can't_ "correct" this gob size, as it is intended as a slice of a larger 3D texture. Ignoring it causes layout conversion to break on read and flush.

This caused an issue in Tears of the Kingdom where the compressed 3D texture used for the gloom would always break on OpenGL, and seemingly randomly break on Vulkan. In the first case, the data is forcibly flushed to decompress the BC4 texture on the CPU to upload it as 3D, which was broken due to the incorrect layout. In the second, the data may be randomly flushed if it falls out of the cache, but it will appear correct if it's able to form copy dependencies.

This change only allows gob sizes to be reduced once per mip level. For the purpose of aligned size, it can still be reduced infinitely as our texture cache isn't properly able to handle a view being _misaligned_.

The SizeCalculator has also been changed to reduce the size of rendered depth slices to only include the exact range a single depth slice will cover. (before, the size was way too small with gobs in z reduced to 1, and too large when using the correct value)

Gobs in Y logic remains untouched, we don't support Y slices of textures so it's fine as is.

This is probably worth testing in a few games as it also affects texture size and view logic.

* Improve wording

* Maybe a bit better
2023-06-04 20:25:57 +00:00
d511c845b7 Check KeyboardMode in GUI (#4343)
* Update SoftwareKeyboard to send KeyboardMode to UI

* Update GTK UI to check text against KeyboardMode

* Update Ava UI to check text against KeyboardMode

* Restructure input validation

* true when text is not empty

* Add English validation text for SoftwareKeyboardMode

* Add Chinese validation text for SoftwareKeyboardMode

* Update base on feedback

---------

Co-authored-by: TSR Berry <20988865+TSRBerry@users.noreply.github.com>
2023-06-04 05:30:24 +02:00
21c9ac6240 Implement shader storage buffer operations using new Load/Store instructions (#4993)
* Implement storage buffer operations using new Load/Store instruction

* Extend GenerateMultiTargetStorageOp to also match access with constant offset, and log and comments

* Remove now unused code

* Catch more complex cases of global memory usage

* Shader cache version bump

* Extend global access elimination to work with more shared memory cases

* Change alignment requirement from 16 bytes to 8 bytes, handle cases where we need more than 16 storage buffers

* Tweak preferencing to catch more cases

* Enable CB0 elimination even when host storage buffer alignment is > 16 (for Intel)

* Fix storage buffer bindings

* Simplify some code

* Shader cache version bump

* Fix typo

* Extend global memory elimination to handle shared memory with multiple possible offsets and local memory
2023-06-03 20:12:18 -03:00
81c9052847 ava: Fix Input Touch (#5204) 2023-06-03 16:03:42 +01:00
9367e3c35d ava: Fix Open Applet menu enabled (#5206)
Currently, the `Open Applet` menu is still enabled when a guest is running, which is wrong. This is not fixed by refreshing the property binding on `IsEnabled`.
2023-06-03 11:03:34 +02:00
52cf141874 Armeilleure: Fix support for Windows on ARM64 (#5202)
* Armeilleure: Fix support for Windows on ARM64

Tested on Windows DevKit 2023.

* Address gdkchan's comments
2023-06-03 10:23:51 +02:00
8a352df3c6 Allow BGRA images on Vulkan (#5203) 2023-06-03 03:43:00 +00:00
c545c59851 ava: Fix exit dialog while guest is running. (#5207)
* ava: Fix exit dialog while guest is running.

There is currently an issue while a game runs, the content dialog creation method check if `IsGameRunning` is true to show the popup.
But the condition here is wrong (`window` is null) so it throw a NullException silently in `Dispatcher.UIThread`.
This is now fixed by using the right casting.

* improve condition

* Fix spacing
2023-06-03 03:37:00 +00:00
96ea4e8c8e nuget: bump Microsoft.NET.Test.Sdk from 17.6.0 to 17.6.1 (#5192)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.6.0 to 17.6.1.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.6.0...v17.6.1)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-01 21:03:00 +02:00
b8f48bcf64 UI: Fix empty homebrew icon (#5189)
* UI: Fix empty homebrew icon

We currently don't check the icon size when we read it from the homebrew data. That could cause issues at UI side since the buffer isn't null but empty. Extra check have been added UI side too.
(I cleaned up some files during my research too)

Fixes #5188

* Remove additional check

* Remove unused using
2023-06-01 18:24:00 +02:00
6966211e07 Give Library header DockPanel explicit height (#5160) 2023-06-01 17:40:44 +02:00
57524a4c8a Add issue template for missing shader instructions (#5048)
* Add issue template for missing shader instructions

* fixup! Add issue template for missing shader instructions

* Update .github/ISSUE_TEMPLATE/missing_shader_instruction.yml

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-01 17:32:38 +02:00
f4539c49d8 [Logger] Add print with stacktrace method (#5129)
* Add print with stacktrace method

* Adjust logging namespaces

* Add static keyword to DynamicObjectFormatter
2023-06-01 13:47:53 +00:00
12c62fdbc2 nuget: bump DynamicData from 7.13.8 to 7.14.2 (#5148)
Bumps [DynamicData](https://github.com/reactiveui/DynamicData) from 7.13.8 to 7.14.2.
- [Release notes](https://github.com/reactiveui/DynamicData/releases)
- [Changelog](https://github.com/reactivemarbles/DynamicData/blob/main/ReleaseNotes.md)
- [Commits](https://github.com/reactiveui/DynamicData/compare/7.13.8...7.14.2)

---
updated-dependencies:
- dependency-name: DynamicData
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-01 13:35:04 +00:00
e3c6be5e29 Only run one workflow for a PR at a time (#5137) 2023-06-01 09:42:49 +02:00
4741a05df9 Vulkan: Include DepthMode in ProgramPipelineState (#5185) 2023-06-01 09:05:39 +02:00
c6676007bf GPU: Dispose Renderer after running deferred actions (#5144)
* GAL: Dispose Renderer after running deferred actions

Deferred actions from disposing physical memory instances always dispose the resources in their caches. The renderer can't be disposed before these resources get disposed, otherwise the dispose actions will not actually run, and the ThreadedRenderer may get stuck trying to enqueue too many commands when there is nothing consuming them.

This should fix most instances of the emulator freezing on close.

* Wait for main render commands to finish, but keep RenderThread alive til dispose

* Address some feedback.

* No parameterize needed

* Set thread name as part of constructor

* Port to Ava and SDL2
2023-05-31 21:43:20 +00:00
92b0b7d753 Avalonia UI: Fix letter "x" in Ryujinx logo being cut off (#5176)
Also make the pronunciation center-aligned
2023-05-31 21:03:11 +00:00
232237bf28 Skip draws with zero vertex count (#5149) 2023-05-31 17:51:11 -03:00
c27e453fd3 Share ResourceManager vertex vertex A and B shaders (#5181) 2023-05-31 17:17:50 -03:00
0e037d0213 macOS Headless Fixes (#5167)
* Default hypervisor to disabled

* Include MVK on macOS

* Properly sign headless builds on macOS

* Force Vulkan on macOS

* Suggestions
2023-05-31 09:08:50 +02:00
0dca1fbe12 Add Context Menu Option to Run Application (#5154) 2023-05-30 19:51:03 +01:00
35d91a0e58 Linux: Automatically increase vm.max_map_count if it's too low (#4702)
* memory: Check results of pinvoke calls

* Increase vm.max_map_count when running Ryujinx

* Add SupportedOSPlatform attribute for WindowsApiException

* Revert increasing vm.max_map_count via script

* Add LinuxHelper to detect and increase vm.max_map_count

With GUI dialogs, this should be a bit more user-friendly.

* Supply arguments as a list to RunPkExec

* Add error logging in case RunPkExec() fails

* Prevent Gtk from crashing
2023-05-30 01:48:37 +02:00
a73a5d7e85 nuget: bump Microsoft.NET.Test.Sdk from 17.5.0 to 17.6.0 (#4986)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.5.0 to 17.6.0.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.5.0...v17.6.0)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-29 01:14:07 +02:00
832a5e8852 Make sure blend is disabled if render target has integer format (#5122)
* Make sure blend is disabled if render target has integer format

* Change approach to avoid permanently mutating state
2023-05-29 00:38:04 +02:00
96d1f0da2d Workaround for MoltenVK barrier issues (#5118) 2023-05-29 00:24:35 +02:00
597388ecda Fix incorrect vertex attribute format change (#5112)
* Fix incorrect vertex attribute format change

* Only change vertex format if the host supports the new format
2023-05-29 00:17:07 +02:00
2865 changed files with 35763 additions and 35545 deletions

View File

@ -0,0 +1,19 @@
name: Missing Shader Instruction
description: Shader Instruction is missing in Ryujinx.
title: "[GPU]"
labels: [gpu, not-implemented]
body:
- type: textarea
id: instruction
attributes:
label: Shader instruction
description: What shader instruction is missing?
validations:
required: true
- type: textarea
id: required
attributes:
label: Required by
description: Add links to the [compatibility list page(s)](https://github.com/Ryujinx/Ryujinx-Games-List/issues) of the game(s) that require this instruction.
validations:
required: true

33
.github/labeler.yml vendored Normal file
View File

@ -0,0 +1,33 @@
audio: 'src/Ryujinx.Audio*/**'
cpu:
- 'src/ARMeilleure/**'
- 'src/Ryujinx.Cpu/**'
- 'src/Ryujinx.Memory/**'
gpu:
- 'src/Ryujinx.Graphics.*/**'
- 'src/Spv.Generator/**'
- 'src/Ryujinx.ShaderTools/**'
'graphics-backend:opengl': 'src/Ryujinx.Graphics.OpenGL/**'
'graphics-backend:vulkan':
- 'src/Ryujinx.Graphics.Vulkan/**'
- 'src/Spv.Generator/**'
gui:
- 'src/Ryujinx/**'
- 'src/Ryujinx.Ui.Common/**'
- 'src/Ryujinx.Ui.LocaleGenerator/**'
- 'src/Ryujinx.Ava/**'
horizon:
- 'src/Ryujinx.HLE/**'
- 'src/Ryujinx.Horizon*/**'
kernel: 'src/Ryujinx.HLE/HOS/Kernel/**'
infra:
- '.github/**'
- 'distribution/**'
- 'Directory.Packages.props'

32
.github/reviewers.yml vendored Normal file
View File

@ -0,0 +1,32 @@
audio:
- marysaka
cpu:
- gdkchan
- riperiperi
- marysaka
- LDj3SNuD
gpu:
- gdkchan
- riperiperi
- marysaka
gui:
- Ack77
- emmauss
- TSRBerry
- marysaka
horizon:
- gdkchan
- Ack77
- marysaka
- TSRBerry
infra:
- marysaka
- TSRBerry
default:
- marysaka

79
.github/update_reviewers.py vendored Normal file
View File

@ -0,0 +1,79 @@
from pathlib import Path
from typing import List, Set
from github import Github
from github.Repository import Repository
from github.GithubException import GithubException
import sys
import yaml
def add_reviewers(
reviewers: Set[str], team_reviewers: Set[str], new_entries: List[str]
):
for reviewer in new_entries:
if reviewer.startswith("@"):
team_reviewers.add(reviewer[1:])
else:
reviewers.add(reviewer)
def update_reviewers(config, repo: Repository, pr_id: int) -> int:
pull_request = repo.get_pull(pr_id)
if not pull_request:
sys.stderr.writable(f"Unknown PR #{pr_id}\n")
return 1
pull_request_author = pull_request.user.login
reviewers = set()
team_reviewers = set()
for label in pull_request.labels:
if label.name in config:
add_reviewers(reviewers, team_reviewers, config[label.name])
if "default" in config:
add_reviewers(reviewers, team_reviewers, config["default"])
if pull_request_author in reviewers:
reviewers.remove(pull_request_author)
try:
reviewers = list(reviewers)
team_reviewers = list(team_reviewers)
print(
f"Attempting to assign reviewers ({reviewers}) and team_reviewers ({team_reviewers})"
)
pull_request.create_review_request(reviewers, team_reviewers)
return 0
except GithubException as e:
sys.stderr.write(f"Cannot assign review request for PR #{pr_id}: {e}\n")
return 1
if __name__ == "__main__":
if len(sys.argv) != 5:
sys.stderr.write("usage: <token> <repo_path> <pr_id> <config_path>\n")
sys.exit(1)
token = sys.argv[1]
repo_path = sys.argv[2]
pr_id = int(sys.argv[3])
config_path = Path(sys.argv[4])
g = Github(token)
repo = g.get_repo(repo_path)
if not repo:
sys.stderr.write("Repository not found!\n")
sys.exit(1)
if not config_path.exists():
sys.stderr.write(f'Config "{config_path}" not found!\n')
sys.exit(1)
with open(config_path, "r") as f:
config = yaml.safe_load(f)
sys.exit(update_reviewers(config, repo, pr_id))

View File

@ -3,21 +3,19 @@ name: Build job
on: on:
workflow_dispatch: workflow_dispatch:
inputs: {} inputs: {}
#push:
# branches: [ master ]
# paths-ignore:
# - '.github/*'
# - '.github/ISSUE_TEMPLATE/**'
# - '*.yml'
# - 'README.md'
pull_request: pull_request:
branches: [ master ] branches: [ master ]
paths-ignore: paths-ignore:
- '.github/*' - '.github/**'
- '.github/ISSUE_TEMPLATE/**'
- '*.yml' - '*.yml'
- '*.json'
- '*.config'
- 'README.md' - 'README.md'
concurrency:
group: pr-checks-${{ github.event.number }}
cancel-in-progress: true
env: env:
POWERSHELL_TELEMETRY_OPTOUT: 1 POWERSHELL_TELEMETRY_OPTOUT: 1
DOTNET_CLI_TELEMETRY_OPTOUT: 1 DOTNET_CLI_TELEMETRY_OPTOUT: 1

34
.github/workflows/pr_triage.yml vendored Normal file
View File

@ -0,0 +1,34 @@
name: "Pull Request Triage"
on:
pull_request_target:
types: [opened, ready_for_review]
jobs:
triage:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
# Grab sources to get update_reviewers.py and reviewers.yml
- name: Fetch sources
uses: actions/checkout@v3
with:
# Ensure we pin the source origin as pull_request_target run under forks.
fetch-depth: 0
repository: Ryujinx/Ryujinx
ref: master
- name: Update labels based on changes
uses: actions/labeler@v4
with:
sync-labels: true
dot: true
- name: Assign reviewers
run: |
pip3 install PyGithub
python3 .github/update_reviewers.py ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${{ github.event.pull_request.number }} .github/reviewers.yml
shell: bash

View File

@ -6,9 +6,10 @@ on:
push: push:
branches: [ master ] branches: [ master ]
paths-ignore: paths-ignore:
- '.github/*' - '.github/**'
- '.github/ISSUE_TEMPLATE/**'
- '*.yml' - '*.yml'
- '*.json'
- '*.config'
- 'README.md' - 'README.md'
concurrency: release concurrency: release

View File

@ -13,7 +13,7 @@
<PackageVersion Include="CommandLineParser" Version="2.9.1" /> <PackageVersion Include="CommandLineParser" Version="2.9.1" />
<PackageVersion Include="Concentus" Version="1.1.7" /> <PackageVersion Include="Concentus" Version="1.1.7" />
<PackageVersion Include="DiscordRichPresence" Version="1.1.3.18" /> <PackageVersion Include="DiscordRichPresence" Version="1.1.3.18" />
<PackageVersion Include="DynamicData" Version="7.13.8" /> <PackageVersion Include="DynamicData" Version="7.14.2" />
<PackageVersion Include="FluentAvaloniaUI" Version="1.4.5" /> <PackageVersion Include="FluentAvaloniaUI" Version="1.4.5" />
<PackageVersion Include="GtkSharp.Dependencies" Version="1.1.1" /> <PackageVersion Include="GtkSharp.Dependencies" Version="1.1.1" />
<PackageVersion Include="GtkSharp.Dependencies.osx" Version="0.0.5" /> <PackageVersion Include="GtkSharp.Dependencies.osx" Version="0.0.5" />
@ -21,7 +21,7 @@
<PackageVersion Include="LibHac" Version="0.18.0" /> <PackageVersion Include="LibHac" Version="0.18.0" />
<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.5.0" /> <PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.5.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.5.0" /> <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.3" />
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" /> <PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" />
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" /> <PackageVersion Include="MsgPack.Cli" Version="1.0.1" />
<PackageVersion Include="NUnit" Version="3.13.3" /> <PackageVersion Include="NUnit" Version="3.13.3" />
@ -44,9 +44,9 @@
<PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" /> <PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" />
<PackageVersion Include="SPB" Version="0.0.4-build28" /> <PackageVersion Include="SPB" Version="0.0.4-build28" />
<PackageVersion Include="System.Drawing.Common" Version="7.0.0" /> <PackageVersion Include="System.Drawing.Common" Version="7.0.0" />
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="6.30.1" /> <PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="6.31.0" />
<PackageVersion Include="System.IO.Hashing" Version="7.0.0" /> <PackageVersion Include="System.IO.Hashing" Version="7.0.0" />
<PackageVersion Include="System.Management" Version="7.0.1" /> <PackageVersion Include="System.Management" Version="7.0.2" />
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" /> <PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
<PackageVersion Include="XamlNameReferenceGenerator" Version="1.6.1" /> <PackageVersion Include="XamlNameReferenceGenerator" Version="1.6.1" />
</ItemGroup> </ItemGroup>

View File

@ -17,4 +17,4 @@ if command -v gamemoderun > /dev/null 2>&1; then
COMMAND="$COMMAND gamemoderun" COMMAND="$COMMAND gamemoderun"
fi fi
$COMMAND "$SCRIPT_DIR/$RYUJINX_BIN" "$@" $COMMAND "$SCRIPT_DIR/$RYUJINX_BIN" "$@"

View File

@ -39,10 +39,15 @@
<key>CSResourcesFileMapped</key> <key>CSResourcesFileMapped</key>
<true/> <true/>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string>Copyright © 2018 - 2022 Ryujinx Team and Contributors.</string> <string>Copyright © 2018 - 2023 Ryujinx Team and Contributors.</string>
<key>LSApplicationCategoryType</key> <key>LSApplicationCategoryType</key>
<string>public.app-category.games</string> <string>public.app-category.games</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>
<string>11.0</string> <string>11.0</string>
<key>LSEnvironment</key>
<dict>
<key>COMPlus_DefaultStackSize</key>
<string>200000</string>
</dict>
</dict> </dict>
</plist> </plist>

View File

@ -35,12 +35,12 @@ EXECUTABLE_SUB_PATH=Contents/MacOS/Ryujinx
rm -rf "$TEMP_DIRECTORY" rm -rf "$TEMP_DIRECTORY"
mkdir -p "$TEMP_DIRECTORY" mkdir -p "$TEMP_DIRECTORY"
DOTNET_COMMON_ARGS="-p:DebugType=embedded -p:Version=$VERSION -p:SourceRevisionId=$SOURCE_REVISION_ID --self-contained true $EXTRA_ARGS" DOTNET_COMMON_ARGS=(-p:DebugType=embedded -p:Version="$VERSION" -p:SourceRevisionId="$SOURCE_REVISION_ID" --self-contained true $EXTRA_ARGS)
dotnet restore dotnet restore
dotnet build -c $CONFIGURATION src/Ryujinx.Ava dotnet build -c "$CONFIGURATION" src/Ryujinx.Ava
dotnet publish -c $CONFIGURATION -r osx-arm64 -o "$TEMP_DIRECTORY/publish_arm64" $DOTNET_COMMON_ARGS src/Ryujinx.Ava dotnet publish -c "$CONFIGURATION" -r osx-arm64 -o "$TEMP_DIRECTORY/publish_arm64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Ava
dotnet publish -c $CONFIGURATION -r osx-x64 -o "$TEMP_DIRECTORY/publish_x64" $DOTNET_COMMON_ARGS src/Ryujinx.Ava dotnet publish -c "$CONFIGURATION" -r osx-x64 -o "$TEMP_DIRECTORY/publish_x64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Ava
# Get rid of the support library for ARMeilleure for x64 (that's only for arm64) # Get rid of the support library for ARMeilleure for x64 (that's only for arm64)
rm -rf "$TEMP_DIRECTORY/publish_x64/libarmeilleure-jitsupport.dylib" rm -rf "$TEMP_DIRECTORY/publish_x64/libarmeilleure-jitsupport.dylib"
@ -104,10 +104,10 @@ fi
echo "Creating archive" echo "Creating archive"
pushd "$OUTPUT_DIRECTORY" pushd "$OUTPUT_DIRECTORY"
tar --exclude "Ryujinx.app/Contents/MacOS/Ryujinx" -cvf $RELEASE_TAR_FILE_NAME Ryujinx.app 1> /dev/null tar --exclude "Ryujinx.app/Contents/MacOS/Ryujinx" -cvf "$RELEASE_TAR_FILE_NAME" Ryujinx.app 1> /dev/null
python3 "$BASE_DIR/distribution/misc/add_tar_exec.py" $RELEASE_TAR_FILE_NAME "Ryujinx.app/Contents/MacOS/Ryujinx" "Ryujinx.app/Contents/MacOS/Ryujinx" python3 "$BASE_DIR/distribution/misc/add_tar_exec.py" "$RELEASE_TAR_FILE_NAME" "Ryujinx.app/Contents/MacOS/Ryujinx" "Ryujinx.app/Contents/MacOS/Ryujinx"
gzip -9 < $RELEASE_TAR_FILE_NAME > $RELEASE_TAR_FILE_NAME.gz gzip -9 < "$RELEASE_TAR_FILE_NAME" > "$RELEASE_TAR_FILE_NAME.gz"
rm $RELEASE_TAR_FILE_NAME rm "$RELEASE_TAR_FILE_NAME"
popd popd
echo "Done" echo "Done"

View File

@ -5,7 +5,7 @@ set -e
INSTALL_DIRECTORY=$1 INSTALL_DIRECTORY=$1
NEW_APP_DIRECTORY=$2 NEW_APP_DIRECTORY=$2
APP_PID=$3 APP_PID=$3
APP_ARGUMENTS="${@:4}" APP_ARGUMENTS=("${@:4}")
error_handler() { error_handler() {
local lineno="$1" local lineno="$1"
@ -33,7 +33,7 @@ trap 'error_handler ${LINENO}' ERR
attempt=0 attempt=0
while true; do while true; do
if lsof -p $APP_PID +r 1 &>/dev/null || ps -p "$APP_PID" &>/dev/null; then if lsof -p "$APP_PID" +r 1 &>/dev/null || ps -p "$APP_PID" &>/dev/null; then
if [ "$attempt" -eq 4 ]; then if [ "$attempt" -eq 4 ]; then
exit 1 exit 1
fi fi
@ -53,5 +53,5 @@ mv "$NEW_APP_DIRECTORY" "$INSTALL_DIRECTORY"
if [ "$#" -le 3 ]; then if [ "$#" -le 3 ]; then
open -a "$INSTALL_DIRECTORY" open -a "$INSTALL_DIRECTORY"
else else
open -a "$INSTALL_DIRECTORY" --args "$APP_ARGUMENTS" open -a "$INSTALL_DIRECTORY" --args "${APP_ARGUMENTS[@]}"
fi fi

View File

@ -23,10 +23,7 @@ namespace ARMeilleure
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ArenaAllocator GetAllocator(ref ArenaAllocator alloc, uint pageSize, uint pageCount) private static ArenaAllocator GetAllocator(ref ArenaAllocator alloc, uint pageSize, uint pageCount)
{ {
if (alloc == null) alloc ??= new ArenaAllocator(pageSize, pageCount);
{
alloc = new ArenaAllocator(pageSize, pageCount);
}
return alloc; return alloc;
} }

View File

@ -221,7 +221,7 @@ namespace ARMeilleure.CodeGen.Arm64
2 => Multiplier.x4, 2 => Multiplier.x4,
3 => Multiplier.x8, 3 => Multiplier.x8,
4 => Multiplier.x16, 4 => Multiplier.x16,
_ => Multiplier.x1 _ => Multiplier.x1,
}; };
baseOp = indexOnSrc2 ? src1 : src2; baseOp = indexOnSrc2 ? src1 : src2;

View File

@ -5,22 +5,22 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
enum ArmCondition enum ArmCondition
{ {
Eq = 0, Eq = 0,
Ne = 1, Ne = 1,
GeUn = 2, GeUn = 2,
LtUn = 3, LtUn = 3,
Mi = 4, Mi = 4,
Pl = 5, Pl = 5,
Vs = 6, Vs = 6,
Vc = 7, Vc = 7,
GtUn = 8, GtUn = 8,
LeUn = 9, LeUn = 9,
Ge = 10, Ge = 10,
Lt = 11, Lt = 11,
Gt = 12, Gt = 12,
Le = 13, Le = 13,
Al = 14, Al = 14,
Nv = 15 Nv = 15,
} }
static class ComparisonArm64Extensions static class ComparisonArm64Extensions
@ -29,6 +29,7 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
return comp switch return comp switch
{ {
#pragma warning disable IDE0055 // Disable formatting
Comparison.Equal => ArmCondition.Eq, Comparison.Equal => ArmCondition.Eq,
Comparison.NotEqual => ArmCondition.Ne, Comparison.NotEqual => ArmCondition.Ne,
Comparison.Greater => ArmCondition.Gt, Comparison.Greater => ArmCondition.Gt,
@ -39,8 +40,9 @@ namespace ARMeilleure.CodeGen.Arm64
Comparison.Less => ArmCondition.Lt, Comparison.Less => ArmCondition.Lt,
Comparison.GreaterOrEqualUI => ArmCondition.GeUn, Comparison.GreaterOrEqualUI => ArmCondition.GeUn,
Comparison.LessUI => ArmCondition.LtUn, Comparison.LessUI => ArmCondition.LtUn,
#pragma warning restore IDE0055
_ => throw new ArgumentException(null, nameof(comp)) _ => throw new ArgumentException(null, nameof(comp)),
}; };
} }
} }

View File

@ -9,6 +9,6 @@ namespace ARMeilleure.CodeGen.Arm64
Sxtb = 4, Sxtb = 4,
Sxth = 5, Sxth = 5,
Sxtw = 6, Sxtw = 6,
Sxtx = 7 Sxtx = 7,
} }
} }

View File

@ -6,6 +6,6 @@ namespace ARMeilleure.CodeGen.Arm64
Lsl = 0, Lsl = 0,
Lsr = 1, Lsr = 1,
Asr = 2, Asr = 2,
Ror = 3 Ror = 3,
} }
} }

View File

@ -188,7 +188,7 @@ namespace ARMeilleure.CodeGen.Arm64
uint rmode = topHalf ? 1u << 19 : 0u; uint rmode = topHalf ? 1u << 19 : 0u;
uint ftype = rd.Type == OperandType.FP64 || rn.Type == OperandType.FP64 ? 1u << 22 : 0u; uint ftype = rd.Type == OperandType.FP64 || rn.Type == OperandType.FP64 ? 1u << 22 : 0u;
uint sf = rd.Type == OperandType.I64 || rn.Type == OperandType.I64 ? SfFlag : 0u; uint sf = rd.Type == OperandType.I64 || rn.Type == OperandType.I64 ? SfFlag : 0u;
WriteUInt32(0x1e260000u | (opcode << 16) | rmode | ftype | sf | EncodeReg(rd) | (EncodeReg(rn) << 5)); WriteUInt32(0x1e260000u | (opcode << 16) | rmode | ftype | sf | EncodeReg(rd) | (EncodeReg(rn) << 5));
} }
@ -992,7 +992,7 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
OperandType.FP32 => 0, OperandType.FP32 => 0,
OperandType.FP64 => 1, OperandType.FP64 => 1,
_ => 2 _ => 2,
}; };
instruction = vecInst | ((uint)opc << 30); instruction = vecInst | ((uint)opc << 30);
@ -1124,10 +1124,11 @@ namespace ARMeilleure.CodeGen.Arm64
OperandType.FP32 => 2, OperandType.FP32 => 2,
OperandType.FP64 => 3, OperandType.FP64 => 3,
OperandType.V128 => 4, OperandType.V128 => 4,
_ => throw new ArgumentException($"Invalid type {type}.") _ => throw new ArgumentException($"Invalid type {type}."),
}; };
} }
#pragma warning disable IDE0051 // Remove unused private member
private void WriteInt16(short value) private void WriteInt16(short value)
{ {
WriteUInt16((ushort)value); WriteUInt16((ushort)value);
@ -1142,6 +1143,7 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
_stream.WriteByte(value); _stream.WriteByte(value);
} }
#pragma warning restore IDE0051
private void WriteUInt16(ushort value) private void WriteUInt16(ushort value)
{ {

View File

@ -93,4 +93,4 @@ namespace ARMeilleure.CodeGen.Arm64
return 0; return 0;
} }
} }
} }

View File

@ -88,4 +88,4 @@ namespace ARMeilleure.CodeGen.Arm64
return true; return true;
} }
} }
} }

View File

@ -14,7 +14,7 @@ namespace ARMeilleure.CodeGen.Arm64
private const int CbnzInstLength = 4; private const int CbnzInstLength = 4;
private const int LdrLitInstLength = 4; private const int LdrLitInstLength = 4;
private Stream _stream; private readonly Stream _stream;
public int StreamOffset => (int)_stream.Length; public int StreamOffset => (int)_stream.Length;
@ -32,7 +32,7 @@ namespace ARMeilleure.CodeGen.Arm64
private readonly Dictionary<BasicBlock, long> _visitedBlocks; private readonly Dictionary<BasicBlock, long> _visitedBlocks;
private readonly Dictionary<BasicBlock, List<(ArmCondition Condition, long BranchPos)>> _pendingBranches; private readonly Dictionary<BasicBlock, List<(ArmCondition Condition, long BranchPos)>> _pendingBranches;
private struct ConstantPoolEntry private readonly struct ConstantPoolEntry
{ {
public readonly int Offset; public readonly int Offset;
public readonly Symbol Symbol; public readonly Symbol Symbol;
@ -58,7 +58,7 @@ namespace ARMeilleure.CodeGen.Arm64
private readonly bool _relocatable; private readonly bool _relocatable;
public CodeGenContext(AllocationResult allocResult, int maxCallArgs, int blocksCount, bool relocatable) public CodeGenContext(AllocationResult allocResult, int maxCallArgs, bool relocatable)
{ {
_stream = MemoryStreamManager.Shared.GetStream(); _stream = MemoryStreamManager.Shared.GetStream();
@ -93,10 +93,10 @@ namespace ARMeilleure.CodeGen.Arm64
if (_pendingBranches.TryGetValue(block, out var list)) if (_pendingBranches.TryGetValue(block, out var list))
{ {
foreach (var tuple in list) foreach ((ArmCondition condition, long branchPos) in list)
{ {
_stream.Seek(tuple.BranchPos, SeekOrigin.Begin); _stream.Seek(branchPos, SeekOrigin.Begin);
WriteBranch(tuple.Condition, target); WriteBranch(condition, target);
} }
_stream.Seek(target, SeekOrigin.Begin); _stream.Seek(target, SeekOrigin.Begin);
@ -284,4 +284,4 @@ namespace ARMeilleure.CodeGen.Arm64
_stream.WriteByte((byte)(value >> 56)); _stream.WriteByte((byte)(value >> 56));
} }
} }
} }

View File

@ -10,7 +10,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Numerics; using System.Numerics;
using static ARMeilleure.IntermediateRepresentation.Operand; using static ARMeilleure.IntermediateRepresentation.Operand;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
@ -31,15 +30,16 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
Byte, Byte,
Hword, Hword,
Auto Auto,
} }
private static Action<CodeGenContext, Operation>[] _instTable; private static readonly Action<CodeGenContext, Operation>[] _instTable;
static CodeGenerator() static CodeGenerator()
{ {
_instTable = new Action<CodeGenContext, Operation>[EnumUtils.GetCount(typeof(Instruction))]; _instTable = new Action<CodeGenContext, Operation>[EnumUtils.GetCount(typeof(Instruction))];
#pragma warning disable IDE0055 // Disable formatting
Add(Instruction.Add, GenerateAdd); Add(Instruction.Add, GenerateAdd);
Add(Instruction.BitwiseAnd, GenerateBitwiseAnd); Add(Instruction.BitwiseAnd, GenerateBitwiseAnd);
Add(Instruction.BitwiseExclusiveOr, GenerateBitwiseExclusiveOr); Add(Instruction.BitwiseExclusiveOr, GenerateBitwiseExclusiveOr);
@ -48,7 +48,7 @@ namespace ARMeilleure.CodeGen.Arm64
Add(Instruction.BranchIf, GenerateBranchIf); Add(Instruction.BranchIf, GenerateBranchIf);
Add(Instruction.ByteSwap, GenerateByteSwap); Add(Instruction.ByteSwap, GenerateByteSwap);
Add(Instruction.Call, GenerateCall); Add(Instruction.Call, GenerateCall);
//Add(Instruction.Clobber, GenerateClobber); // Add(Instruction.Clobber, GenerateClobber);
Add(Instruction.Compare, GenerateCompare); Add(Instruction.Compare, GenerateCompare);
Add(Instruction.CompareAndSwap, GenerateCompareAndSwap); Add(Instruction.CompareAndSwap, GenerateCompareAndSwap);
Add(Instruction.CompareAndSwap16, GenerateCompareAndSwap16); Add(Instruction.CompareAndSwap16, GenerateCompareAndSwap16);
@ -100,6 +100,7 @@ namespace ARMeilleure.CodeGen.Arm64
Add(Instruction.ZeroExtend16, GenerateZeroExtend16); Add(Instruction.ZeroExtend16, GenerateZeroExtend16);
Add(Instruction.ZeroExtend32, GenerateZeroExtend32); Add(Instruction.ZeroExtend32, GenerateZeroExtend32);
Add(Instruction.ZeroExtend8, GenerateZeroExtend8); Add(Instruction.ZeroExtend8, GenerateZeroExtend8);
#pragma warning restore IDE0055
static void Add(Instruction inst, Action<CodeGenContext, Operation> func) static void Add(Instruction inst, Action<CodeGenContext, Operation> func)
{ {
@ -131,7 +132,7 @@ namespace ARMeilleure.CodeGen.Arm64
StackAllocator stackAlloc = new(); StackAllocator stackAlloc = new();
PreAllocator.RunPass(cctx, stackAlloc, out int maxCallArgs); PreAllocator.RunPass(cctx, out int maxCallArgs);
Logger.EndPass(PassName.PreAllocation, cfg); Logger.EndPass(PassName.PreAllocation, cfg);
@ -168,11 +169,9 @@ namespace ARMeilleure.CodeGen.Arm64
Logger.StartPass(PassName.CodeGeneration); Logger.StartPass(PassName.CodeGeneration);
//Console.Error.WriteLine(IRDumper.GetDump(cfg));
bool relocatable = (cctx.Options & CompilerOptions.Relocatable) != 0; bool relocatable = (cctx.Options & CompilerOptions.Relocatable) != 0;
CodeGenContext context = new(allocResult, maxCallArgs, cfg.Blocks.Count, relocatable); CodeGenContext context = new(allocResult, maxCallArgs, relocatable);
UnwindInfo unwindInfo = WritePrologue(context); UnwindInfo unwindInfo = WritePrologue(context);
@ -294,7 +293,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateBitwiseNot(CodeGenContext context, Operation operation) private static void GenerateBitwiseNot(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
ValidateUnOp(dest, source); ValidateUnOp(dest, source);
@ -332,7 +331,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateByteSwap(CodeGenContext context, Operation operation) private static void GenerateByteSwap(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
ValidateUnOp(dest, source); ValidateUnOp(dest, source);
@ -366,15 +365,15 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
if (operation.SourcesCount == 5) // CompareAndSwap128 has 5 sources, compared to CompareAndSwap64/32's 3. if (operation.SourcesCount == 5) // CompareAndSwap128 has 5 sources, compared to CompareAndSwap64/32's 3.
{ {
Operand actualLow = operation.GetDestination(0); Operand actualLow = operation.GetDestination(0);
Operand actualHigh = operation.GetDestination(1); Operand actualHigh = operation.GetDestination(1);
Operand temp0 = operation.GetDestination(2); Operand temp0 = operation.GetDestination(2);
Operand temp1 = operation.GetDestination(3); Operand temp1 = operation.GetDestination(3);
Operand address = operation.GetSource(0); Operand address = operation.GetSource(0);
Operand expectedLow = operation.GetSource(1); Operand expectedLow = operation.GetSource(1);
Operand expectedHigh = operation.GetSource(2); Operand expectedHigh = operation.GetSource(2);
Operand desiredLow = operation.GetSource(3); Operand desiredLow = operation.GetSource(3);
Operand desiredHigh = operation.GetSource(4); Operand desiredHigh = operation.GetSource(4);
GenerateAtomicDcas( GenerateAtomicDcas(
context, context,
@ -390,11 +389,11 @@ namespace ARMeilleure.CodeGen.Arm64
} }
else else
{ {
Operand actual = operation.GetDestination(0); Operand actual = operation.GetDestination(0);
Operand result = operation.GetDestination(1); Operand result = operation.GetDestination(1);
Operand address = operation.GetSource(0); Operand address = operation.GetSource(0);
Operand expected = operation.GetSource(1); Operand expected = operation.GetSource(1);
Operand desired = operation.GetSource(2); Operand desired = operation.GetSource(2);
GenerateAtomicCas(context, address, expected, desired, actual, result, AccessSize.Auto); GenerateAtomicCas(context, address, expected, desired, actual, result, AccessSize.Auto);
} }
@ -402,22 +401,22 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateCompareAndSwap16(CodeGenContext context, Operation operation) private static void GenerateCompareAndSwap16(CodeGenContext context, Operation operation)
{ {
Operand actual = operation.GetDestination(0); Operand actual = operation.GetDestination(0);
Operand result = operation.GetDestination(1); Operand result = operation.GetDestination(1);
Operand address = operation.GetSource(0); Operand address = operation.GetSource(0);
Operand expected = operation.GetSource(1); Operand expected = operation.GetSource(1);
Operand desired = operation.GetSource(2); Operand desired = operation.GetSource(2);
GenerateAtomicCas(context, address, expected, desired, actual, result, AccessSize.Hword); GenerateAtomicCas(context, address, expected, desired, actual, result, AccessSize.Hword);
} }
private static void GenerateCompareAndSwap8(CodeGenContext context, Operation operation) private static void GenerateCompareAndSwap8(CodeGenContext context, Operation operation)
{ {
Operand actual = operation.GetDestination(0); Operand actual = operation.GetDestination(0);
Operand result = operation.GetDestination(1); Operand result = operation.GetDestination(1);
Operand address = operation.GetSource(0); Operand address = operation.GetSource(0);
Operand expected = operation.GetSource(1); Operand expected = operation.GetSource(1);
Operand desired = operation.GetSource(2); Operand desired = operation.GetSource(2);
GenerateAtomicCas(context, address, expected, desired, actual, result, AccessSize.Byte); GenerateAtomicCas(context, address, expected, desired, actual, result, AccessSize.Byte);
} }
@ -446,13 +445,13 @@ namespace ARMeilleure.CodeGen.Arm64
Debug.Assert(dest.Type.IsInteger()); Debug.Assert(dest.Type.IsInteger());
Debug.Assert(src1.Type == OperandType.I32); Debug.Assert(src1.Type == OperandType.I32);
context.Assembler.Cmp (src1, Const(src1.Type, 0)); context.Assembler.Cmp(src1, Const(src1.Type, 0));
context.Assembler.Csel(dest, src2, src3, ArmCondition.Ne); context.Assembler.Csel(dest, src2, src3, ArmCondition.Ne);
} }
private static void GenerateConvertI64ToI32(CodeGenContext context, Operation operation) private static void GenerateConvertI64ToI32(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type == OperandType.I32 && source.Type == OperandType.I64); Debug.Assert(dest.Type == OperandType.I32 && source.Type == OperandType.I64);
@ -462,7 +461,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateConvertToFP(CodeGenContext context, Operation operation) private static void GenerateConvertToFP(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64); Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64);
@ -481,7 +480,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateConvertToFPUI(CodeGenContext context, Operation operation) private static void GenerateConvertToFPUI(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64); Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64);
@ -493,7 +492,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateCopy(CodeGenContext context, Operation operation) private static void GenerateCopy(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
EnsureSameType(dest, source); EnsureSameType(dest, source);
@ -525,7 +524,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateCountLeadingZeros(CodeGenContext context, Operation operation) private static void GenerateCountLeadingZeros(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
EnsureSameType(dest, source); EnsureSameType(dest, source);
@ -537,9 +536,9 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateDivide(CodeGenContext context, Operation operation) private static void GenerateDivide(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand dividend = operation.GetSource(0); Operand dividend = operation.GetSource(0);
Operand divisor = operation.GetSource(1); Operand divisor = operation.GetSource(1);
ValidateBinOp(dest, dividend, divisor); ValidateBinOp(dest, dividend, divisor);
@ -555,9 +554,9 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateDivideUI(CodeGenContext context, Operation operation) private static void GenerateDivideUI(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand dividend = operation.GetSource(0); Operand dividend = operation.GetSource(0);
Operand divisor = operation.GetSource(1); Operand divisor = operation.GetSource(1);
ValidateBinOp(dest, dividend, divisor); ValidateBinOp(dest, dividend, divisor);
@ -566,7 +565,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateLoad(CodeGenContext context, Operation operation) private static void GenerateLoad(CodeGenContext context, Operation operation)
{ {
Operand value = operation.Destination; Operand value = operation.Destination;
Operand address = operation.GetSource(0); Operand address = operation.GetSource(0);
context.Assembler.Ldr(value, address); context.Assembler.Ldr(value, address);
@ -574,7 +573,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateLoad16(CodeGenContext context, Operation operation) private static void GenerateLoad16(CodeGenContext context, Operation operation)
{ {
Operand value = operation.Destination; Operand value = operation.Destination;
Operand address = operation.GetSource(0); Operand address = operation.GetSource(0);
Debug.Assert(value.Type.IsInteger()); Debug.Assert(value.Type.IsInteger());
@ -584,7 +583,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateLoad8(CodeGenContext context, Operation operation) private static void GenerateLoad8(CodeGenContext context, Operation operation)
{ {
Operand value = operation.Destination; Operand value = operation.Destination;
Operand address = operation.GetSource(0); Operand address = operation.GetSource(0);
Debug.Assert(value.Type.IsInteger()); Debug.Assert(value.Type.IsInteger());
@ -643,7 +642,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateNegate(CodeGenContext context, Operation operation) private static void GenerateNegate(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
ValidateUnOp(dest, source); ValidateUnOp(dest, source);
@ -730,7 +729,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateSignExtend16(CodeGenContext context, Operation operation) private static void GenerateSignExtend16(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
@ -740,7 +739,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateSignExtend32(CodeGenContext context, Operation operation) private static void GenerateSignExtend32(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
@ -750,7 +749,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateSignExtend8(CodeGenContext context, Operation operation) private static void GenerateSignExtend8(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
@ -760,7 +759,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateFill(CodeGenContext context, Operation operation) private static void GenerateFill(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand offset = operation.GetSource(0); Operand offset = operation.GetSource(0);
Debug.Assert(offset.Kind == OperandKind.Constant); Debug.Assert(offset.Kind == OperandKind.Constant);
@ -801,7 +800,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateStackAlloc(CodeGenContext context, Operation operation) private static void GenerateStackAlloc(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand offset = operation.GetSource(0); Operand offset = operation.GetSource(0);
Debug.Assert(offset.Kind == OperandKind.Constant); Debug.Assert(offset.Kind == OperandKind.Constant);
@ -813,7 +812,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateStore(CodeGenContext context, Operation operation) private static void GenerateStore(CodeGenContext context, Operation operation)
{ {
Operand value = operation.GetSource(1); Operand value = operation.GetSource(1);
Operand address = operation.GetSource(0); Operand address = operation.GetSource(0);
context.Assembler.Str(value, address); context.Assembler.Str(value, address);
@ -821,7 +820,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateStore16(CodeGenContext context, Operation operation) private static void GenerateStore16(CodeGenContext context, Operation operation)
{ {
Operand value = operation.GetSource(1); Operand value = operation.GetSource(1);
Operand address = operation.GetSource(0); Operand address = operation.GetSource(0);
Debug.Assert(value.Type.IsInteger()); Debug.Assert(value.Type.IsInteger());
@ -831,7 +830,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateStore8(CodeGenContext context, Operation operation) private static void GenerateStore8(CodeGenContext context, Operation operation)
{ {
Operand value = operation.GetSource(1); Operand value = operation.GetSource(1);
Operand address = operation.GetSource(0); Operand address = operation.GetSource(0);
Debug.Assert(value.Type.IsInteger()); Debug.Assert(value.Type.IsInteger());
@ -878,7 +877,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateVectorCreateScalar(CodeGenContext context, Operation operation) private static void GenerateVectorCreateScalar(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
if (dest != default) if (dest != default)
@ -1024,7 +1023,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateVectorZeroUpper64(CodeGenContext context, Operation operation) private static void GenerateVectorZeroUpper64(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type == OperandType.V128 && source.Type == OperandType.V128); Debug.Assert(dest.Type == OperandType.V128 && source.Type == OperandType.V128);
@ -1034,7 +1033,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateVectorZeroUpper96(CodeGenContext context, Operation operation) private static void GenerateVectorZeroUpper96(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type == OperandType.V128 && source.Type == OperandType.V128); Debug.Assert(dest.Type == OperandType.V128 && source.Type == OperandType.V128);
@ -1044,7 +1043,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateZeroExtend16(CodeGenContext context, Operation operation) private static void GenerateZeroExtend16(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
@ -1054,7 +1053,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateZeroExtend32(CodeGenContext context, Operation operation) private static void GenerateZeroExtend32(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
@ -1070,7 +1069,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void GenerateZeroExtend8(CodeGenContext context, Operation operation) private static void GenerateZeroExtend8(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
@ -1080,7 +1079,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static UnwindInfo WritePrologue(CodeGenContext context) private static UnwindInfo WritePrologue(CodeGenContext context)
{ {
List<UnwindPushEntry> pushEntries = new List<UnwindPushEntry>(); List<UnwindPushEntry> pushEntries = new();
Operand rsp = Register(SpRegister); Operand rsp = Register(SpRegister);
@ -1570,11 +1569,13 @@ namespace ARMeilleure.CodeGen.Arm64
Debug.Assert(op1.Type == op3.Type); Debug.Assert(op1.Type == op3.Type);
} }
#pragma warning disable IDE0051 // Remove unused private member
private static void EnsureSameType(Operand op1, Operand op2, Operand op3, Operand op4) private static void EnsureSameType(Operand op1, Operand op2, Operand op3, Operand op4)
{ {
Debug.Assert(op1.Type == op2.Type); Debug.Assert(op1.Type == op2.Type);
Debug.Assert(op1.Type == op3.Type); Debug.Assert(op1.Type == op3.Type);
Debug.Assert(op1.Type == op4.Type); Debug.Assert(op1.Type == op4.Type);
} }
#pragma warning restore IDE0051
} }
} }

View File

@ -179,6 +179,35 @@ namespace ARMeilleure.CodeGen.Arm64
(uint)operation.GetSource(2).AsInt32()); (uint)operation.GetSource(2).AsInt32());
break; break;
case IntrinsicType.Vector128Unary:
GenerateVectorUnary(
context,
1,
0,
info.Inst,
operation.Destination,
operation.GetSource(0));
break;
case IntrinsicType.Vector128Binary:
GenerateVectorBinary(
context,
1,
0,
info.Inst,
operation.Destination,
operation.GetSource(0),
operation.GetSource(1));
break;
case IntrinsicType.Vector128BinaryRd:
GenerateVectorUnary(
context,
1,
0,
info.Inst,
operation.Destination,
operation.GetSource(1));
break;
case IntrinsicType.VectorUnary: case IntrinsicType.VectorUnary:
GenerateVectorUnary( GenerateVectorUnary(
context, context,
@ -659,4 +688,4 @@ namespace ARMeilleure.CodeGen.Arm64
context.Assembler.WriteInstruction(instruction, rd, rn); context.Assembler.WriteInstruction(instruction, rd, rn);
} }
} }
} }

View File

@ -1,7 +1,4 @@
using System; using System;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Intrinsics.Arm; using System.Runtime.Intrinsics.Arm;
using System.Runtime.Versioning; using System.Runtime.Versioning;
@ -35,7 +32,7 @@ namespace ARMeilleure.CodeGen.Arm64
} }
} }
#region Linux #region Linux
private const ulong AT_HWCAP = 16; private const ulong AT_HWCAP = 16;
private const ulong AT_HWCAP2 = 26; private const ulong AT_HWCAP2 = 26;
@ -46,88 +43,88 @@ namespace ARMeilleure.CodeGen.Arm64
[Flags] [Flags]
public enum LinuxFeatureFlagsHwCap : ulong public enum LinuxFeatureFlagsHwCap : ulong
{ {
Fp = 1 << 0, Fp = 1 << 0,
Asimd = 1 << 1, Asimd = 1 << 1,
Evtstrm = 1 << 2, Evtstrm = 1 << 2,
Aes = 1 << 3, Aes = 1 << 3,
Pmull = 1 << 4, Pmull = 1 << 4,
Sha1 = 1 << 5, Sha1 = 1 << 5,
Sha2 = 1 << 6, Sha2 = 1 << 6,
Crc32 = 1 << 7, Crc32 = 1 << 7,
Atomics = 1 << 8, Atomics = 1 << 8,
FpHp = 1 << 9, FpHp = 1 << 9,
AsimdHp = 1 << 10, AsimdHp = 1 << 10,
CpuId = 1 << 11, CpuId = 1 << 11,
AsimdRdm = 1 << 12, AsimdRdm = 1 << 12,
Jscvt = 1 << 13, Jscvt = 1 << 13,
Fcma = 1 << 14, Fcma = 1 << 14,
Lrcpc = 1 << 15, Lrcpc = 1 << 15,
DcpOp = 1 << 16, DcpOp = 1 << 16,
Sha3 = 1 << 17, Sha3 = 1 << 17,
Sm3 = 1 << 18, Sm3 = 1 << 18,
Sm4 = 1 << 19, Sm4 = 1 << 19,
AsimdDp = 1 << 20, AsimdDp = 1 << 20,
Sha512 = 1 << 21, Sha512 = 1 << 21,
Sve = 1 << 22, Sve = 1 << 22,
AsimdFhm = 1 << 23, AsimdFhm = 1 << 23,
Dit = 1 << 24, Dit = 1 << 24,
Uscat = 1 << 25, Uscat = 1 << 25,
Ilrcpc = 1 << 26, Ilrcpc = 1 << 26,
FlagM = 1 << 27, FlagM = 1 << 27,
Ssbs = 1 << 28, Ssbs = 1 << 28,
Sb = 1 << 29, Sb = 1 << 29,
Paca = 1 << 30, Paca = 1 << 30,
Pacg = 1UL << 31 Pacg = 1UL << 31,
} }
[Flags] [Flags]
public enum LinuxFeatureFlagsHwCap2 : ulong public enum LinuxFeatureFlagsHwCap2 : ulong
{ {
Dcpodp = 1 << 0, Dcpodp = 1 << 0,
Sve2 = 1 << 1, Sve2 = 1 << 1,
SveAes = 1 << 2, SveAes = 1 << 2,
SvePmull = 1 << 3, SvePmull = 1 << 3,
SveBitperm = 1 << 4, SveBitperm = 1 << 4,
SveSha3 = 1 << 5, SveSha3 = 1 << 5,
SveSm4 = 1 << 6, SveSm4 = 1 << 6,
FlagM2 = 1 << 7, FlagM2 = 1 << 7,
Frint = 1 << 8, Frint = 1 << 8,
SveI8mm = 1 << 9, SveI8mm = 1 << 9,
SveF32mm = 1 << 10, SveF32mm = 1 << 10,
SveF64mm = 1 << 11, SveF64mm = 1 << 11,
SveBf16 = 1 << 12, SveBf16 = 1 << 12,
I8mm = 1 << 13, I8mm = 1 << 13,
Bf16 = 1 << 14, Bf16 = 1 << 14,
Dgh = 1 << 15, Dgh = 1 << 15,
Rng = 1 << 16, Rng = 1 << 16,
Bti = 1 << 17, Bti = 1 << 17,
Mte = 1 << 18, Mte = 1 << 18,
Ecv = 1 << 19, Ecv = 1 << 19,
Afp = 1 << 20, Afp = 1 << 20,
Rpres = 1 << 21, Rpres = 1 << 21,
Mte3 = 1 << 22, Mte3 = 1 << 22,
Sme = 1 << 23, Sme = 1 << 23,
Sme_i16i64 = 1 << 24, Sme_i16i64 = 1 << 24,
Sme_f64f64 = 1 << 25, Sme_f64f64 = 1 << 25,
Sme_i8i32 = 1 << 26, Sme_i8i32 = 1 << 26,
Sme_f16f32 = 1 << 27, Sme_f16f32 = 1 << 27,
Sme_b16f32 = 1 << 28, Sme_b16f32 = 1 << 28,
Sme_f32f32 = 1 << 29, Sme_f32f32 = 1 << 29,
Sme_fa64 = 1 << 30, Sme_fa64 = 1 << 30,
Wfxt = 1UL << 31, Wfxt = 1UL << 31,
Ebf16 = 1UL << 32, Ebf16 = 1UL << 32,
Sve_Ebf16 = 1UL << 33, Sve_Ebf16 = 1UL << 33,
Cssc = 1UL << 34, Cssc = 1UL << 34,
Rprfm = 1UL << 35, Rprfm = 1UL << 35,
Sve2p1 = 1UL << 36 Sve2p1 = 1UL << 36,
} }
public static LinuxFeatureFlagsHwCap LinuxFeatureInfoHwCap { get; } = 0; public static LinuxFeatureFlagsHwCap LinuxFeatureInfoHwCap { get; } = 0;
public static LinuxFeatureFlagsHwCap2 LinuxFeatureInfoHwCap2 { get; } = 0; public static LinuxFeatureFlagsHwCap2 LinuxFeatureInfoHwCap2 { get; } = 0;
#endregion #endregion
#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, IntPtr newValue, ulong newValueSize); private static unsafe partial int sysctlbyname([MarshalAs(UnmanagedType.LPStr)] string name, out int oldValue, ref ulong oldSize, IntPtr newValue, ulong newValueSize);
@ -143,7 +140,7 @@ namespace ARMeilleure.CodeGen.Arm64
return false; return false;
} }
private static string[] _sysctlNames = new string[] private static readonly string[] _sysctlNames = new string[]
{ {
"hw.optional.floatingpoint", "hw.optional.floatingpoint",
"hw.optional.AdvSIMD", "hw.optional.AdvSIMD",
@ -153,26 +150,26 @@ namespace ARMeilleure.CodeGen.Arm64
"hw.optional.arm.FEAT_LSE", "hw.optional.arm.FEAT_LSE",
"hw.optional.armv8_crc32", "hw.optional.armv8_crc32",
"hw.optional.arm.FEAT_SHA1", "hw.optional.arm.FEAT_SHA1",
"hw.optional.arm.FEAT_SHA256" "hw.optional.arm.FEAT_SHA256",
}; };
[Flags] [Flags]
public enum MacOsFeatureFlags public enum MacOsFeatureFlags
{ {
Fp = 1 << 0, Fp = 1 << 0,
AdvSimd = 1 << 1, AdvSimd = 1 << 1,
Fp16 = 1 << 2, Fp16 = 1 << 2,
Aes = 1 << 3, Aes = 1 << 3,
Pmull = 1 << 4, Pmull = 1 << 4,
Lse = 1 << 5, Lse = 1 << 5,
Crc32 = 1 << 6, Crc32 = 1 << 6,
Sha1 = 1 << 7, Sha1 = 1 << 7,
Sha256 = 1 << 8 Sha256 = 1 << 8,
} }
public static MacOsFeatureFlags MacOsFeatureInfo { get; } = 0; public static MacOsFeatureFlags MacOsFeatureInfo { get; } = 0;
#endregion #endregion
public static bool SupportsAdvSimd => LinuxFeatureInfoHwCap.HasFlag(LinuxFeatureFlagsHwCap.Asimd) || MacOsFeatureInfo.HasFlag(MacOsFeatureFlags.AdvSimd); public static bool SupportsAdvSimd => LinuxFeatureInfoHwCap.HasFlag(LinuxFeatureFlagsHwCap.Asimd) || MacOsFeatureInfo.HasFlag(MacOsFeatureFlags.AdvSimd);
public static bool SupportsAes => LinuxFeatureInfoHwCap.HasFlag(LinuxFeatureFlagsHwCap.Aes) || MacOsFeatureInfo.HasFlag(MacOsFeatureFlags.Aes); public static bool SupportsAes => LinuxFeatureInfoHwCap.HasFlag(LinuxFeatureFlagsHwCap.Aes) || MacOsFeatureInfo.HasFlag(MacOsFeatureFlags.Aes);

View File

@ -1,8 +1,8 @@
namespace ARMeilleure.CodeGen.Arm64 namespace ARMeilleure.CodeGen.Arm64
{ {
struct IntrinsicInfo readonly struct IntrinsicInfo
{ {
public uint Inst { get; } public uint Inst { get; }
public IntrinsicType Type { get; } public IntrinsicType Type { get; }
public IntrinsicInfo(uint inst, IntrinsicType type) public IntrinsicInfo(uint inst, IntrinsicType type)
@ -11,4 +11,4 @@ namespace ARMeilleure.CodeGen.Arm64
Type = type; Type = type;
} }
} }
} }

View File

@ -5,12 +5,13 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
static class IntrinsicTable static class IntrinsicTable
{ {
private static IntrinsicInfo[] _intrinTable; private static readonly IntrinsicInfo[] _intrinTable;
static IntrinsicTable() static IntrinsicTable()
{ {
_intrinTable = new IntrinsicInfo[EnumUtils.GetCount(typeof(Intrinsic))]; _intrinTable = new IntrinsicInfo[EnumUtils.GetCount(typeof(Intrinsic))];
#pragma warning disable IDE0055 // Disable formatting
Add(Intrinsic.Arm64AbsS, new IntrinsicInfo(0x5e20b800u, IntrinsicType.ScalarUnary)); Add(Intrinsic.Arm64AbsS, new IntrinsicInfo(0x5e20b800u, IntrinsicType.ScalarUnary));
Add(Intrinsic.Arm64AbsV, new IntrinsicInfo(0x0e20b800u, IntrinsicType.VectorUnary)); Add(Intrinsic.Arm64AbsV, new IntrinsicInfo(0x0e20b800u, IntrinsicType.VectorUnary));
Add(Intrinsic.Arm64AddhnV, new IntrinsicInfo(0x0e204000u, IntrinsicType.VectorTernaryRd)); Add(Intrinsic.Arm64AddhnV, new IntrinsicInfo(0x0e204000u, IntrinsicType.VectorTernaryRd));
@ -19,8 +20,8 @@ namespace ARMeilleure.CodeGen.Arm64
Add(Intrinsic.Arm64AddvV, new IntrinsicInfo(0x0e31b800u, IntrinsicType.VectorUnary)); Add(Intrinsic.Arm64AddvV, new IntrinsicInfo(0x0e31b800u, IntrinsicType.VectorUnary));
Add(Intrinsic.Arm64AddS, new IntrinsicInfo(0x5e208400u, IntrinsicType.ScalarBinary)); Add(Intrinsic.Arm64AddS, new IntrinsicInfo(0x5e208400u, IntrinsicType.ScalarBinary));
Add(Intrinsic.Arm64AddV, new IntrinsicInfo(0x0e208400u, IntrinsicType.VectorBinary)); Add(Intrinsic.Arm64AddV, new IntrinsicInfo(0x0e208400u, IntrinsicType.VectorBinary));
Add(Intrinsic.Arm64AesdV, new IntrinsicInfo(0x4e285800u, IntrinsicType.Vector128Unary)); Add(Intrinsic.Arm64AesdV, new IntrinsicInfo(0x4e285800u, IntrinsicType.Vector128BinaryRd));
Add(Intrinsic.Arm64AeseV, new IntrinsicInfo(0x4e284800u, IntrinsicType.Vector128Unary)); Add(Intrinsic.Arm64AeseV, new IntrinsicInfo(0x4e284800u, IntrinsicType.Vector128BinaryRd));
Add(Intrinsic.Arm64AesimcV, new IntrinsicInfo(0x4e287800u, IntrinsicType.Vector128Unary)); Add(Intrinsic.Arm64AesimcV, new IntrinsicInfo(0x4e287800u, IntrinsicType.Vector128Unary));
Add(Intrinsic.Arm64AesmcV, new IntrinsicInfo(0x4e286800u, IntrinsicType.Vector128Unary)); Add(Intrinsic.Arm64AesmcV, new IntrinsicInfo(0x4e286800u, IntrinsicType.Vector128Unary));
Add(Intrinsic.Arm64AndV, new IntrinsicInfo(0x0e201c00u, IntrinsicType.VectorBinaryBitwise)); Add(Intrinsic.Arm64AndV, new IntrinsicInfo(0x0e201c00u, IntrinsicType.VectorBinaryBitwise));
@ -448,6 +449,7 @@ namespace ARMeilleure.CodeGen.Arm64
Add(Intrinsic.Arm64XtnV, new IntrinsicInfo(0x0e212800u, IntrinsicType.VectorUnary)); Add(Intrinsic.Arm64XtnV, new IntrinsicInfo(0x0e212800u, IntrinsicType.VectorUnary));
Add(Intrinsic.Arm64Zip1V, new IntrinsicInfo(0x0e003800u, IntrinsicType.VectorBinary)); Add(Intrinsic.Arm64Zip1V, new IntrinsicInfo(0x0e003800u, IntrinsicType.VectorBinary));
Add(Intrinsic.Arm64Zip2V, new IntrinsicInfo(0x0e007800u, IntrinsicType.VectorBinary)); Add(Intrinsic.Arm64Zip2V, new IntrinsicInfo(0x0e007800u, IntrinsicType.VectorBinary));
#pragma warning restore IDE0055
} }
private static void Add(Intrinsic intrin, IntrinsicInfo info) private static void Add(Intrinsic intrin, IntrinsicInfo info)
@ -460,4 +462,4 @@ namespace ARMeilleure.CodeGen.Arm64
return _intrinTable[(int)intrin]; return _intrinTable[(int)intrin];
} }
} }
} }

View File

@ -23,6 +23,10 @@ namespace ARMeilleure.CodeGen.Arm64
ScalarTernaryShlRd, ScalarTernaryShlRd,
ScalarTernaryShrRd, ScalarTernaryShrRd,
Vector128Unary,
Vector128Binary,
Vector128BinaryRd,
VectorUnary, VectorUnary,
VectorUnaryBitwise, VectorUnaryBitwise,
VectorUnaryByElem, VectorUnaryByElem,
@ -50,10 +54,7 @@ namespace ARMeilleure.CodeGen.Arm64
VectorTernaryShlRd, VectorTernaryShlRd,
VectorTernaryShrRd, VectorTernaryShrRd,
Vector128Unary,
Vector128Binary,
GetRegister, GetRegister,
SetRegister SetRegister,
} }
} }

View File

@ -1,4 +1,3 @@
using ARMeilleure.CodeGen.RegisterAllocators;
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation; using ARMeilleure.Translation;
using System; using System;
@ -31,7 +30,7 @@ namespace ARMeilleure.CodeGen.Arm64
} }
} }
public static void RunPass(CompilerContext cctx, StackAllocator stackAlloc, out int maxCallArgs) public static void RunPass(CompilerContext cctx, out int maxCallArgs)
{ {
maxCallArgs = -1; maxCallArgs = -1;
@ -41,7 +40,7 @@ namespace ARMeilleure.CodeGen.Arm64
for (BasicBlock block = cctx.Cfg.Blocks.First; block != null; block = block.ListNext) for (BasicBlock block = cctx.Cfg.Blocks.First; block != null; block = block.ListNext)
{ {
ConstantDict constants = new ConstantDict(); ConstantDict constants = new();
Operation nextNode; Operation nextNode;
@ -92,7 +91,7 @@ namespace ARMeilleure.CodeGen.Arm64
InsertReturnCopy(block.Operations, node); InsertReturnCopy(block.Operations, node);
break; break;
case Instruction.Tailcall: case Instruction.Tailcall:
InsertTailcallCopies(constants, block.Operations, stackAlloc, node, node); InsertTailcallCopies(constants, block.Operations, node, node);
break; break;
} }
} }
@ -138,10 +137,7 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
src2 = node.GetSource(1); src2 = node.GetSource(1);
Operand temp = src1; (src2, src1) = (src1, src2);
src1 = src2;
src2 = temp;
node.SetSource(0, src1); node.SetSource(0, src1);
node.SetSource(1, src2); node.SetSource(1, src2);
@ -265,9 +261,9 @@ namespace ARMeilleure.CodeGen.Arm64
Operand dest = operation.Destination; Operand dest = operation.Destination;
List<Operand> sources = new List<Operand> List<Operand> sources = new()
{ {
operation.GetSource(0) operation.GetSource(0),
}; };
int argsCount = operation.SourcesCount - 1; int argsCount = operation.SourcesCount - 1;
@ -302,10 +298,10 @@ namespace ARMeilleure.CodeGen.Arm64
if (source.Type == OperandType.V128 && passOnReg) if (source.Type == OperandType.V128 && passOnReg)
{ {
// V128 is a struct, we pass each half on a GPR if possible. // V128 is a struct, we pass each half on a GPR if possible.
Operand argReg = Gpr(CallingConvention.GetIntArgumentRegister(intCount++), OperandType.I64); Operand argReg = Gpr(CallingConvention.GetIntArgumentRegister(intCount++), OperandType.I64);
Operand argReg2 = Gpr(CallingConvention.GetIntArgumentRegister(intCount++), OperandType.I64); Operand argReg2 = Gpr(CallingConvention.GetIntArgumentRegister(intCount++), OperandType.I64);
nodes.AddBefore(node, Operation(Instruction.VectorExtract, argReg, source, Const(0))); nodes.AddBefore(node, Operation(Instruction.VectorExtract, argReg, source, Const(0)));
nodes.AddBefore(node, Operation(Instruction.VectorExtract, argReg2, source, Const(1))); nodes.AddBefore(node, Operation(Instruction.VectorExtract, argReg2, source, Const(1)));
continue; continue;
@ -339,7 +335,7 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
if (dest.Type == OperandType.V128) if (dest.Type == OperandType.V128)
{ {
Operand retLReg = Gpr(CallingConvention.GetIntReturnRegister(), OperandType.I64); Operand retLReg = Gpr(CallingConvention.GetIntReturnRegister(), OperandType.I64);
Operand retHReg = Gpr(CallingConvention.GetIntReturnRegisterHigh(), OperandType.I64); Operand retHReg = Gpr(CallingConvention.GetIntReturnRegisterHigh(), OperandType.I64);
node = nodes.AddAfter(node, Operation(Instruction.VectorCreateScalar, dest, retLReg)); node = nodes.AddAfter(node, Operation(Instruction.VectorCreateScalar, dest, retLReg));
@ -364,16 +360,14 @@ namespace ARMeilleure.CodeGen.Arm64
operation.SetSources(sources.ToArray()); operation.SetSources(sources.ToArray());
} }
private static void InsertTailcallCopies( private static void InsertTailcallCopies(ConstantDict constants,
ConstantDict constants,
IntrusiveList<Operation> nodes, IntrusiveList<Operation> nodes,
StackAllocator stackAlloc,
Operation node, Operation node,
Operation operation) Operation operation)
{ {
List<Operand> sources = new List<Operand> List<Operand> sources = new()
{ {
operation.GetSource(0) operation.GetSource(0),
}; };
int argsCount = operation.SourcesCount - 1; int argsCount = operation.SourcesCount - 1;
@ -403,7 +397,7 @@ namespace ARMeilleure.CodeGen.Arm64
if (source.Type == OperandType.V128 && passOnReg) if (source.Type == OperandType.V128 && passOnReg)
{ {
// V128 is a struct, we pass each half on a GPR if possible. // V128 is a struct, we pass each half on a GPR if possible.
Operand argReg = Gpr(CallingConvention.GetIntArgumentRegister(intCount++), OperandType.I64); Operand argReg = Gpr(CallingConvention.GetIntArgumentRegister(intCount++), OperandType.I64);
Operand argReg2 = Gpr(CallingConvention.GetIntArgumentRegister(intCount++), OperandType.I64); Operand argReg2 = Gpr(CallingConvention.GetIntArgumentRegister(intCount++), OperandType.I64);
nodes.AddBefore(node, Operation(Instruction.VectorExtract, argReg, source, Const(0))); nodes.AddBefore(node, Operation(Instruction.VectorExtract, argReg, source, Const(0)));
@ -519,7 +513,7 @@ namespace ARMeilleure.CodeGen.Arm64
if (source.Type == OperandType.V128) if (source.Type == OperandType.V128)
{ {
Operand retLReg = Gpr(CallingConvention.GetIntReturnRegister(), OperandType.I64); Operand retLReg = Gpr(CallingConvention.GetIntReturnRegister(), OperandType.I64);
Operand retHReg = Gpr(CallingConvention.GetIntReturnRegisterHigh(), OperandType.I64); Operand retHReg = Gpr(CallingConvention.GetIntReturnRegisterHigh(), OperandType.I64);
nodes.AddBefore(node, Operation(Instruction.VectorExtract, retLReg, source, Const(0))); nodes.AddBefore(node, Operation(Instruction.VectorExtract, retLReg, source, Const(0)));
@ -746,6 +740,7 @@ namespace ARMeilleure.CodeGen.Arm64
info.Type == IntrinsicType.ScalarTernaryFPRdByElem || info.Type == IntrinsicType.ScalarTernaryFPRdByElem ||
info.Type == IntrinsicType.ScalarTernaryShlRd || info.Type == IntrinsicType.ScalarTernaryShlRd ||
info.Type == IntrinsicType.ScalarTernaryShrRd || info.Type == IntrinsicType.ScalarTernaryShrRd ||
info.Type == IntrinsicType.Vector128BinaryRd ||
info.Type == IntrinsicType.VectorBinaryRd || info.Type == IntrinsicType.VectorBinaryRd ||
info.Type == IntrinsicType.VectorInsertByElem || info.Type == IntrinsicType.VectorInsertByElem ||
info.Type == IntrinsicType.VectorTernaryRd || info.Type == IntrinsicType.VectorTernaryRd ||

View File

@ -35,9 +35,9 @@ namespace ARMeilleure.CodeGen
/// <param name="relocInfo">Relocation info</param> /// <param name="relocInfo">Relocation info</param>
internal CompiledFunction(byte[] code, UnwindInfo unwindInfo, RelocInfo relocInfo) internal CompiledFunction(byte[] code, UnwindInfo unwindInfo, RelocInfo relocInfo)
{ {
Code = code; Code = code;
UnwindInfo = unwindInfo; UnwindInfo = unwindInfo;
RelocInfo = relocInfo; RelocInfo = relocInfo;
} }
/// <summary> /// <summary>
@ -65,4 +65,4 @@ namespace ARMeilleure.CodeGen
return Marshal.GetDelegateForFunctionPointer<T>(codePointer); return Marshal.GetDelegateForFunctionPointer<T>(codePointer);
} }
} }
} }

View File

@ -35,4 +35,4 @@ namespace ARMeilleure.CodeGen.Linking
return $"({nameof(Position)} = {Position}, {nameof(Symbol)} = {Symbol})"; return $"({nameof(Position)} = {Position}, {nameof(Symbol)} = {Symbol})";
} }
} }
} }

View File

@ -29,4 +29,4 @@ namespace ARMeilleure.CodeGen.Linking
_entries = entries; _entries = entries;
} }
} }
} }

View File

@ -23,6 +23,6 @@
/// <summary> /// <summary>
/// Refers to a special symbol which is handled by <see cref="Translation.PTC.Ptc.PatchCode"/>. /// Refers to a special symbol which is handled by <see cref="Translation.PTC.Ptc.PatchCode"/>.
/// </summary> /// </summary>
Special Special,
} }
} }

View File

@ -164,7 +164,7 @@ namespace ARMeilleure.CodeGen.Optimizations
} }
break; break;
case Instruction.Multiply: case Instruction.Multiply:
if (type == OperandType.I32) if (type == OperandType.I32)
{ {
EvaluateBinaryI32(operation, (x, y) => x * y); EvaluateBinaryI32(operation, (x, y) => x * y);
@ -343,4 +343,4 @@ namespace ARMeilleure.CodeGen.Optimizations
operation.TurnIntoCopy(Const(op(x, y))); operation.TurnIntoCopy(Const(op(x, y)));
} }
} }
} }

View File

@ -182,7 +182,7 @@ namespace ARMeilleure.CodeGen.Optimizations
private static void PropagateCopy(ref Span<Operation> buffer, Operation copyOp) private static void PropagateCopy(ref Span<Operation> buffer, Operation copyOp)
{ {
// Propagate copy source operand to all uses of the destination operand. // Propagate copy source operand to all uses of the destination operand.
Operand dest = copyOp.Destination; Operand dest = copyOp.Destination;
Operand source = copyOp.GetSource(0); Operand source = copyOp.GetSource(0);
Span<Operation> uses = dest.GetUses(ref buffer); Span<Operation> uses = dest.GetUses(ref buffer);
@ -249,4 +249,4 @@ namespace ARMeilleure.CodeGen.Optimizations
return operation.Destination.Type == operation.GetSource(0).Type; return operation.Destination.Type == operation.GetSource(0).Type;
} }
} }
} }

View File

@ -171,13 +171,12 @@ namespace ARMeilleure.CodeGen.Optimizations
private static ulong AllOnes(OperandType type) private static ulong AllOnes(OperandType type)
{ {
switch (type) return type switch
{ {
case OperandType.I32: return ~0U; OperandType.I32 => ~0U,
case OperandType.I64: return ~0UL; OperandType.I64 => ~0UL,
} _ => throw new ArgumentException("Invalid operand type \"" + type + "\"."),
};
throw new ArgumentException("Invalid operand type \"" + type + "\".");
} }
} }
} }

View File

@ -4,7 +4,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{ {
public int IntUsedRegisters { get; } public int IntUsedRegisters { get; }
public int VecUsedRegisters { get; } public int VecUsedRegisters { get; }
public int SpillRegionSize { get; } public int SpillRegionSize { get; }
public AllocationResult( public AllocationResult(
int intUsedRegisters, int intUsedRegisters,
@ -13,7 +13,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{ {
IntUsedRegisters = intUsedRegisters; IntUsedRegisters = intUsedRegisters;
VecUsedRegisters = vecUsedRegisters; VecUsedRegisters = vecUsedRegisters;
SpillRegionSize = spillRegionSize; SpillRegionSize = spillRegionSize;
} }
} }
} }

View File

@ -1,7 +1,6 @@
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory; using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
using static ARMeilleure.IntermediateRepresentation.Operation.Factory; using static ARMeilleure.IntermediateRepresentation.Operation.Factory;
@ -13,16 +12,16 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{ {
private readonly struct Copy private readonly struct Copy
{ {
public Register Dest { get; } public Register Dest { get; }
public Register Source { get; } public Register Source { get; }
public OperandType Type { get; } public OperandType Type { get; }
public Copy(Register dest, Register source, OperandType type) public Copy(Register dest, Register source, OperandType type)
{ {
Dest = dest; Dest = dest;
Source = source; Source = source;
Type = type; Type = type;
} }
} }
@ -42,19 +41,19 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
public void Sequence(List<Operation> sequence) public void Sequence(List<Operation> sequence)
{ {
Dictionary<Register, Register> locations = new Dictionary<Register, Register>(); Dictionary<Register, Register> locations = new();
Dictionary<Register, Register> sources = new Dictionary<Register, Register>(); Dictionary<Register, Register> sources = new();
Dictionary<Register, OperandType> types = new Dictionary<Register, OperandType>(); Dictionary<Register, OperandType> types = new();
Queue<Register> pendingQueue = new Queue<Register>(); Queue<Register> pendingQueue = new();
Queue<Register> readyQueue = new Queue<Register>(); Queue<Register> readyQueue = new();
foreach (Copy copy in _copies) foreach (Copy copy in _copies)
{ {
locations[copy.Source] = copy.Source; locations[copy.Source] = copy.Source;
sources[copy.Dest] = copy.Source; sources[copy.Dest] = copy.Source;
types[copy.Dest] = copy.Type; types[copy.Dest] = copy.Type;
pendingQueue.Enqueue(copy.Dest); pendingQueue.Enqueue(copy.Dest);
} }
@ -91,7 +90,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
} }
} }
copyDest = current; copyDest = current;
origSource = sources[copyDest]; origSource = sources[copyDest];
copySource = locations[origSource]; copySource = locations[origSource];
@ -186,10 +185,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private void AddSplitFill(LiveInterval left, LiveInterval right, OperandType type) private void AddSplitFill(LiveInterval left, LiveInterval right, OperandType type)
{ {
if (_fillQueue == null) _fillQueue ??= new Queue<Operation>();
{
_fillQueue = new Queue<Operation>();
}
Operand register = GetRegister(right.Register, type); Operand register = GetRegister(right.Register, type);
Operand offset = Const(left.SpillOffset); Operand offset = Const(left.SpillOffset);
@ -201,10 +197,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private void AddSplitSpill(LiveInterval left, LiveInterval right, OperandType type) private void AddSplitSpill(LiveInterval left, LiveInterval right, OperandType type)
{ {
if (_spillQueue == null) _spillQueue ??= new Queue<Operation>();
{
_spillQueue = new Queue<Operation>();
}
Operand offset = Const(right.SpillOffset); Operand offset = Const(right.SpillOffset);
Operand register = GetRegister(left.Register, type); Operand register = GetRegister(left.Register, type);
@ -216,10 +209,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private void AddSplitCopy(LiveInterval left, LiveInterval right, OperandType type) private void AddSplitCopy(LiveInterval left, LiveInterval right, OperandType type)
{ {
if (_parallelCopy == null) _parallelCopy ??= new ParallelCopy();
{
_parallelCopy = new ParallelCopy();
}
_parallelCopy.AddCopy(right.Register, left.Register, type); _parallelCopy.AddCopy(right.Register, left.Register, type);
@ -228,7 +218,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
public Operation[] Sequence() public Operation[] Sequence()
{ {
List<Operation> sequence = new List<Operation>(); List<Operation> sequence = new();
if (_spillQueue != null) if (_spillQueue != null)
{ {
@ -256,4 +246,4 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
return Register(reg.Index, reg.Type, type); return Register(reg.Index, reg.Type, type);
} }
} }
} }

View File

@ -20,7 +20,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
public BlockInfo(bool hasCall, int intFixedRegisters, int vecFixedRegisters) public BlockInfo(bool hasCall, int intFixedRegisters, int vecFixedRegisters)
{ {
HasCall = hasCall; HasCall = hasCall;
IntFixedRegisters = intFixedRegisters; IntFixedRegisters = intFixedRegisters;
VecFixedRegisters = vecFixedRegisters; VecFixedRegisters = vecFixedRegisters;
} }
@ -39,7 +39,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private int _first; private int _first;
private int _last; private int _last;
public bool IsBlockLocal => _first == _last; public readonly bool IsBlockLocal => _first == _last;
public LocalInfo(OperandType type, int uses, int blkIndex) public LocalInfo(OperandType type, int uses, int blkIndex)
{ {
@ -53,7 +53,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
SpillOffset = default; SpillOffset = default;
_first = -1; _first = -1;
_last = -1; _last = -1;
SetBlockIndex(blkIndex); SetBlockIndex(blkIndex);
} }
@ -348,17 +348,17 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
if (dest.Type.IsInteger()) if (dest.Type.IsInteger())
{ {
intLocalFreeRegisters &= ~(1 << selectedReg); intLocalFreeRegisters &= ~(1 << selectedReg);
intUsedRegisters |= 1 << selectedReg; intUsedRegisters |= 1 << selectedReg;
} }
else else
{ {
vecLocalFreeRegisters &= ~(1 << selectedReg); vecLocalFreeRegisters &= ~(1 << selectedReg);
vecUsedRegisters |= 1 << selectedReg; vecUsedRegisters |= 1 << selectedReg;
} }
} }
else else
{ {
info.Register = default; info.Register = default;
info.SpillOffset = Const(stackAlloc.Allocate(dest.Type.GetSizeInBytes())); info.SpillOffset = Const(stackAlloc.Allocate(dest.Type.GetSizeInBytes()));
} }
} }
@ -382,7 +382,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
: GetSpillTemp(dest, vecSpillTempRegisters, ref vecLocalAsg); : GetSpillTemp(dest, vecSpillTempRegisters, ref vecLocalAsg);
info.Sequence = sequence; info.Sequence = sequence;
info.Temp = temp; info.Temp = temp;
} }
dest = temp; dest = temp;
@ -408,7 +408,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private static int SelectSpillTemps(int mask0, int mask1) private static int SelectSpillTemps(int mask0, int mask1)
{ {
int selection = 0; int selection = 0;
int count = 0; int count = 0;
while (count < MaxIROperands && mask0 != 0) while (count < MaxIROperands && mask0 != 0)
{ {
@ -451,4 +451,4 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
return local.AssignmentsCount + local.UsesCount; return local.AssignmentsCount + local.UsesCount;
} }
} }
} }

View File

@ -9,4 +9,4 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
StackAllocator stackAlloc, StackAllocator stackAlloc,
RegisterMasks regMasks); RegisterMasks regMasks);
} }
} }

View File

@ -14,7 +14,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
// http://www.christianwimmer.at/Publications/Wimmer04a/Wimmer04a.pdf // http://www.christianwimmer.at/Publications/Wimmer04a/Wimmer04a.pdf
class LinearScanAllocator : IRegisterAllocator class LinearScanAllocator : IRegisterAllocator
{ {
private const int InstructionGap = 2; private const int InstructionGap = 2;
private const int InstructionGapMask = InstructionGap - 1; private const int InstructionGapMask = InstructionGap - 1;
private HashSet<int> _blockEdges; private HashSet<int> _blockEdges;
@ -33,7 +33,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
public StackAllocator StackAlloc { get; } public StackAllocator StackAlloc { get; }
public BitMap Active { get; } public BitMap Active { get; }
public BitMap Inactive { get; } public BitMap Inactive { get; }
public int IntUsedRegisters { get; set; } public int IntUsedRegisters { get; set; }
@ -47,9 +47,9 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
public AllocationContext(StackAllocator stackAlloc, RegisterMasks masks, int intervalsCount) public AllocationContext(StackAllocator stackAlloc, RegisterMasks masks, int intervalsCount)
{ {
StackAlloc = stackAlloc; StackAlloc = stackAlloc;
Masks = masks; Masks = masks;
Active = new BitMap(Allocators.Default, intervalsCount); Active = new BitMap(Allocators.Default, intervalsCount);
Inactive = new BitMap(Allocators.Default, intervalsCount); Inactive = new BitMap(Allocators.Default, intervalsCount);
PopulateFreePositions(RegisterType.Integer, out _intFreePositions, out _intFreePositionsCount); PopulateFreePositions(RegisterType.Integer, out _intFreePositions, out _intFreePositionsCount);
@ -443,7 +443,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
if (highest < current) if (highest < current)
{ {
highest = current; highest = current;
selected = index; selected = index;
if (current == int.MaxValue) if (current == int.MaxValue)
@ -485,9 +485,9 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private void SplitAndSpillOverlappingInterval( private void SplitAndSpillOverlappingInterval(
AllocationContext context, AllocationContext context,
LiveInterval current, LiveInterval current,
LiveInterval interval, LiveInterval interval,
int registersCount) int registersCount)
{ {
// If there's a next use after the start of the current interval, // If there's a next use after the start of the current interval,
// we need to split the spilled interval twice, and re-insert it // we need to split the spilled interval twice, and re-insert it
@ -530,8 +530,8 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private void InsertInterval(LiveInterval interval, int registersCount) private void InsertInterval(LiveInterval interval, int registersCount)
{ {
Debug.Assert(interval.UsesCount != 0, "Trying to insert a interval without uses."); Debug.Assert(interval.UsesCount != 0, "Trying to insert a interval without uses.");
Debug.Assert(!interval.IsEmpty, "Trying to insert a empty interval."); Debug.Assert(!interval.IsEmpty, "Trying to insert a empty interval.");
Debug.Assert(!interval.IsSpilled, "Trying to insert a spilled interval."); Debug.Assert(!interval.IsSpilled, "Trying to insert a spilled interval.");
int startIndex = registersCount * 2; int startIndex = registersCount * 2;
@ -545,9 +545,9 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
_intervals.Insert(insertIndex, interval); _intervals.Insert(insertIndex, interval);
} }
private void Spill(AllocationContext context, LiveInterval interval) private static void Spill(AllocationContext context, LiveInterval interval)
{ {
Debug.Assert(!interval.IsFixed, "Trying to spill a fixed interval."); Debug.Assert(!interval.IsFixed, "Trying to spill a fixed interval.");
Debug.Assert(interval.UsesCount == 0, "Trying to spill a interval with uses."); Debug.Assert(interval.UsesCount == 0, "Trying to spill a interval with uses.");
// We first check if any of the siblings were spilled, if so we can reuse // We first check if any of the siblings were spilled, if so we can reuse
@ -561,7 +561,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private void InsertSplitCopies() private void InsertSplitCopies()
{ {
Dictionary<int, CopyResolver> copyResolvers = new Dictionary<int, CopyResolver>(); Dictionary<int, CopyResolver> copyResolvers = new();
CopyResolver GetCopyResolver(int position) CopyResolver GetCopyResolver(int position)
{ {
@ -668,18 +668,15 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
continue; continue;
} }
int lEnd = _blockRanges[block.Index].End - 1; int lEnd = _blockRanges[block.Index].End - 1;
int rStart = _blockRanges[succIndex].Start; int rStart = _blockRanges[succIndex].Start;
LiveInterval left = interval.GetSplitChild(lEnd); LiveInterval left = interval.GetSplitChild(lEnd);
LiveInterval right = interval.GetSplitChild(rStart); LiveInterval right = interval.GetSplitChild(rStart);
if (left != default && right != default && left != right) if (left != default && right != default && left != right)
{ {
if (copyResolver == null) copyResolver ??= new CopyResolver();
{
copyResolver = new CopyResolver();
}
copyResolver.AddSplit(left, right); copyResolver.AddSplit(left, right);
} }
@ -856,14 +853,14 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
int mapSize = _intervals.Count; int mapSize = _intervals.Count;
BitMap[] blkLiveGen = new BitMap[cfg.Blocks.Count]; BitMap[] blkLiveGen = new BitMap[cfg.Blocks.Count];
BitMap[] blkLiveKill = new BitMap[cfg.Blocks.Count]; BitMap[] blkLiveKill = new BitMap[cfg.Blocks.Count];
// Compute local live sets. // Compute local live sets.
for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext) for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext)
{ {
BitMap liveGen = new BitMap(Allocators.Default, mapSize); BitMap liveGen = new(Allocators.Default, mapSize);
BitMap liveKill = new BitMap(Allocators.Default, mapSize); BitMap liveKill = new(Allocators.Default, mapSize);
for (Operation node = block.Operations.First; node != default; node = node.ListNext) for (Operation node = block.Operations.First; node != default; node = node.ListNext)
{ {
@ -910,17 +907,17 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
} }
} }
blkLiveGen [block.Index] = liveGen; blkLiveGen[block.Index] = liveGen;
blkLiveKill[block.Index] = liveKill; blkLiveKill[block.Index] = liveKill;
} }
// Compute global live sets. // Compute global live sets.
BitMap[] blkLiveIn = new BitMap[cfg.Blocks.Count]; BitMap[] blkLiveIn = new BitMap[cfg.Blocks.Count];
BitMap[] blkLiveOut = new BitMap[cfg.Blocks.Count]; BitMap[] blkLiveOut = new BitMap[cfg.Blocks.Count];
for (int index = 0; index < cfg.Blocks.Count; index++) for (int index = 0; index < cfg.Blocks.Count; index++)
{ {
blkLiveIn [index] = new BitMap(Allocators.Default, mapSize); blkLiveIn[index] = new BitMap(Allocators.Default, mapSize);
blkLiveOut[index] = new BitMap(Allocators.Default, mapSize); blkLiveOut[index] = new BitMap(Allocators.Default, mapSize);
} }
@ -945,9 +942,9 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
BitMap liveIn = blkLiveIn[block.Index]; BitMap liveIn = blkLiveIn[block.Index];
liveIn.Set (liveOut); liveIn.Set(liveOut);
liveIn.Clear(blkLiveKill[block.Index]); liveIn.Clear(blkLiveKill[block.Index]);
liveIn.Set (blkLiveGen [block.Index]); liveIn.Set(blkLiveGen[block.Index]);
} }
} }
while (modified); while (modified);
@ -969,7 +966,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
int instCount = Math.Max(block.Operations.Count, 1); int instCount = Math.Max(block.Operations.Count, 1);
int blockStart = operationPos - instCount * InstructionGap; int blockStart = operationPos - instCount * InstructionGap;
int blockEnd = operationPos; int blockEnd = operationPos;
_blockRanges[block.Index] = new LiveRange(blockStart, blockEnd); _blockRanges[block.Index] = new LiveRange(blockStart, blockEnd);
@ -1061,7 +1058,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{ {
int regIndex = BitOperations.TrailingZeroCount(mask); int regIndex = BitOperations.TrailingZeroCount(mask);
Register callerSavedReg = new Register(regIndex, regType); Register callerSavedReg = new(regIndex, regType);
LiveInterval interval = _intervals[GetRegisterId(callerSavedReg)]; LiveInterval interval = _intervals[GetRegisterId(callerSavedReg)];
@ -1098,4 +1095,4 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
kind == OperandKind.Register; kind == OperandKind.Register;
} }
} }
} }

View File

@ -240,8 +240,10 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
public LiveInterval Split(int position) public LiveInterval Split(int position)
{ {
LiveInterval result = new(Local, Parent); LiveInterval result = new(Local, Parent)
result.End = End; {
End = End,
};
LiveRange prev = PrevRange; LiveRange prev = PrevRange;
LiveRange curr = CurrRange; LiveRange curr = CurrRange;
@ -393,4 +395,4 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
return string.Join(", ", GetRanges()); return string.Join(", ", GetRanges());
} }
} }
} }

View File

@ -8,8 +8,8 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private int _count; private int _count;
private int _capacity; private int _capacity;
public int Count => _count; public readonly int Count => _count;
public Span<LiveInterval> Span => new(_items, _count); public readonly Span<LiveInterval> Span => new(_items, _count);
public void Add(LiveInterval interval) public void Add(LiveInterval interval)
{ {
@ -37,4 +37,4 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
_count++; _count++;
} }
} }
} }

View File

@ -71,4 +71,4 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
return $"[{Start}, {End})"; return $"[{Start}, {End})";
} }
} }
} }

View File

@ -5,8 +5,8 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{ {
readonly struct RegisterMasks readonly struct RegisterMasks
{ {
public int IntAvailableRegisters { get; } public int IntAvailableRegisters { get; }
public int VecAvailableRegisters { get; } public int VecAvailableRegisters { get; }
public int IntCallerSavedRegisters { get; } public int IntCallerSavedRegisters { get; }
public int VecCallerSavedRegisters { get; } public int VecCallerSavedRegisters { get; }
public int IntCalleeSavedRegisters { get; } public int IntCalleeSavedRegisters { get; }
@ -22,13 +22,13 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
int vecCalleeSavedRegisters, int vecCalleeSavedRegisters,
int registersCount) int registersCount)
{ {
IntAvailableRegisters = intAvailableRegisters; IntAvailableRegisters = intAvailableRegisters;
VecAvailableRegisters = vecAvailableRegisters; VecAvailableRegisters = vecAvailableRegisters;
IntCallerSavedRegisters = intCallerSavedRegisters; IntCallerSavedRegisters = intCallerSavedRegisters;
VecCallerSavedRegisters = vecCallerSavedRegisters; VecCallerSavedRegisters = vecCallerSavedRegisters;
IntCalleeSavedRegisters = intCalleeSavedRegisters; IntCalleeSavedRegisters = intCalleeSavedRegisters;
VecCalleeSavedRegisters = vecCalleeSavedRegisters; VecCalleeSavedRegisters = vecCalleeSavedRegisters;
RegistersCount = registersCount; RegistersCount = registersCount;
} }
public int GetAvailableRegisters(RegisterType type) public int GetAvailableRegisters(RegisterType type)
@ -47,4 +47,4 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
} }
} }
} }
} }

View File

@ -22,4 +22,4 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
return offset; return offset;
} }
} }
} }

View File

@ -6,15 +6,15 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{ {
private int* _items; private int* _items;
private int _capacity; private int _capacity;
private int _count;
public int Count => _count; public int Count { get; private set; }
public int FirstUse => _count > 0 ? _items[_count - 1] : LiveInterval.NotFound;
public Span<int> Span => new(_items, _count); public readonly int FirstUse => Count > 0 ? _items[Count - 1] : LiveInterval.NotFound;
public readonly Span<int> Span => new(_items, Count);
public void Add(int position) public void Add(int position)
{ {
if (_count + 1 > _capacity) if (Count + 1 > _capacity)
{ {
var oldSpan = Span; var oldSpan = Span;
@ -28,7 +28,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
// Use positions are usually inserted in descending order, so inserting in descending order is faster, // Use positions are usually inserted in descending order, so inserting in descending order is faster,
// since the number of half exchanges is reduced. // since the number of half exchanges is reduced.
int i = _count - 1; int i = Count - 1;
while (i >= 0 && _items[i] < position) while (i >= 0 && _items[i] < position)
{ {
@ -36,19 +36,19 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
} }
_items[i + 1] = position; _items[i + 1] = position;
_count++; Count++;
} }
public int NextUse(int position) public readonly int NextUse(int position)
{ {
int index = NextUseIndex(position); int index = NextUseIndex(position);
return index != LiveInterval.NotFound ? _items[index] : LiveInterval.NotFound; return index != LiveInterval.NotFound ? _items[index] : LiveInterval.NotFound;
} }
public int NextUseIndex(int position) public readonly int NextUseIndex(int position)
{ {
int i = _count - 1; int i = Count - 1;
if (i == -1 || position > _items[0]) if (i == -1 || position > _items[0])
{ {
@ -69,16 +69,18 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
// Since the list is in descending order, the new split list takes the front of the list and the current // Since the list is in descending order, the new split list takes the front of the list and the current
// list takes the back of the list. // list takes the back of the list.
UseList result = new(); UseList result = new()
result._count = index + 1; {
result._capacity = result._count; Count = index + 1,
};
result._capacity = result.Count;
result._items = _items; result._items = _items;
_count = _count - result._count; Count -= result.Count;
_capacity = _count; _capacity = Count;
_items = _items + result._count; _items += result.Count;
return result; return result;
} }
} }
} }

View File

@ -13,4 +13,4 @@ namespace ARMeilleure.CodeGen.Unwinding
PrologSize = prologSize; PrologSize = prologSize;
} }
} }
} }

View File

@ -2,10 +2,10 @@ namespace ARMeilleure.CodeGen.Unwinding
{ {
enum UnwindPseudoOp enum UnwindPseudoOp
{ {
PushReg = 0, PushReg = 0,
SetFrame = 1, SetFrame = 1,
AllocStack = 2, AllocStack = 2,
SaveReg = 3, SaveReg = 3,
SaveXmm128 = 4 SaveXmm128 = 4,
} }
} }

View File

@ -17,4 +17,4 @@ namespace ARMeilleure.CodeGen.Unwinding
StackOffsetOrAllocSize = stackOffsetOrAllocSize; StackOffsetOrAllocSize = stackOffsetOrAllocSize;
} }
} }
} }

View File

@ -15,7 +15,7 @@ namespace ARMeilleure.CodeGen.X86
private const int OpModRMBits = 24; private const int OpModRMBits = 24;
private const byte RexPrefix = 0x40; private const byte RexPrefix = 0x40;
private const byte RexWPrefix = 0x48; private const byte RexWPrefix = 0x48;
private const byte LockPrefix = 0xf0; private const byte LockPrefix = 0xf0;
@ -799,7 +799,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
JumpIndex = _jumps.Count - 1, JumpIndex = _jumps.Count - 1,
Position = (int)_stream.Position, Position = (int)_stream.Position,
Symbol = source.Symbol Symbol = source.Symbol,
}); });
} }
@ -959,7 +959,7 @@ namespace ARMeilleure.CodeGen.X86
} }
} }
bool needsSibByte = false; bool needsSibByte = false;
bool needsDisplacement = false; bool needsDisplacement = false;
int sib = 0; int sib = 0;
@ -971,7 +971,7 @@ namespace ARMeilleure.CodeGen.X86
X86Register baseRegLow = (X86Register)(baseReg.Index & 0b111); X86Register baseRegLow = (X86Register)(baseReg.Index & 0b111);
needsSibByte = memOp.Index != default || baseRegLow == X86Register.Rsp; needsSibByte = memOp.Index != default || baseRegLow == X86Register.Rsp;
needsDisplacement = memOp.Displacement != 0 || baseRegLow == X86Register.Rbp; needsDisplacement = memOp.Displacement != 0 || baseRegLow == X86Register.Rbp;
if (needsDisplacement) if (needsDisplacement)
@ -1049,7 +1049,7 @@ namespace ARMeilleure.CodeGen.X86
InstructionFlags.Prefix66 => 1, InstructionFlags.Prefix66 => 1,
InstructionFlags.PrefixF3 => 2, InstructionFlags.PrefixF3 => 2,
InstructionFlags.PrefixF2 => 3, InstructionFlags.PrefixF2 => 3,
_ => 0 _ => 0,
}; };
if (src1 != default) if (src1 != default)
@ -1081,11 +1081,19 @@ namespace ARMeilleure.CodeGen.X86
switch (opCodeHigh) switch (opCodeHigh)
{ {
case 0xf: vexByte1 |= 1; break; case 0xf:
case 0xf38: vexByte1 |= 2; break; vexByte1 |= 1;
case 0xf3a: vexByte1 |= 3; break; break;
case 0xf38:
vexByte1 |= 2;
break;
case 0xf3a:
vexByte1 |= 3;
break;
default: Debug.Assert(false, $"Failed to VEX encode opcode 0x{opCode:X}."); break; default:
Debug.Assert(false, $"Failed to VEX encode opcode 0x{opCode:X}.");
break;
} }
vexByte2 |= (rexPrefix & 8) << 4; vexByte2 |= (rexPrefix & 8) << 4;
@ -1191,11 +1199,19 @@ namespace ARMeilleure.CodeGen.X86
switch ((ushort)(opCode >> 8)) switch ((ushort)(opCode >> 8))
{ {
case 0xf00: mm = 0b01; break; case 0xf00:
case 0xf38: mm = 0b10; break; mm = 0b01;
case 0xf3a: mm = 0b11; break; break;
case 0xf38:
mm = 0b10;
break;
case 0xf3a:
mm = 0b11;
break;
default: Debug.Fail($"Failed to EVEX encode opcode 0x{opCode:X}."); break; default:
Debug.Fail($"Failed to EVEX encode opcode 0x{opCode:X}.");
break;
} }
WriteByte( WriteByte(
@ -1217,7 +1233,7 @@ namespace ARMeilleure.CodeGen.X86
InstructionFlags.Prefix66 => 0b01, InstructionFlags.Prefix66 => 0b01,
InstructionFlags.PrefixF3 => 0b10, InstructionFlags.PrefixF3 => 0b10,
InstructionFlags.PrefixF2 => 0b11, InstructionFlags.PrefixF2 => 0b11,
_ => 0 _ => 0,
}; };
WriteByte( WriteByte(
(byte)( (byte)(
@ -1233,11 +1249,19 @@ namespace ARMeilleure.CodeGen.X86
byte ll = 0b00; byte ll = 0b00;
switch (registerWidth) switch (registerWidth)
{ {
case 128: ll = 0b00; break; case 128:
case 256: ll = 0b01; break; ll = 0b00;
case 512: ll = 0b10; break; break;
case 256:
ll = 0b01;
break;
case 512:
ll = 0b10;
break;
default: Debug.Fail($"Invalid EVEX vector register width {registerWidth}."); break; default:
Debug.Fail($"Invalid EVEX vector register width {registerWidth}.");
break;
} }
// Embedded broadcast in the case of a memory operand // Embedded broadcast in the case of a memory operand
bool bcast = broadcast; bool bcast = broadcast;
@ -1315,10 +1339,7 @@ namespace ARMeilleure.CodeGen.X86
ref Jump jump = ref jumps[i]; ref Jump jump = ref jumps[i];
// If jump target not resolved yet, resolve it. // If jump target not resolved yet, resolve it.
if (jump.JumpTarget == null) jump.JumpTarget ??= _labels[jump.JumpLabel];
{
jump.JumpTarget = _labels[jump.JumpLabel];
}
long jumpTarget = jump.JumpTarget.Value; long jumpTarget = jump.JumpTarget.Value;
long offset = jumpTarget - jump.JumpPosition; long offset = jumpTarget - jump.JumpPosition;
@ -1556,4 +1577,4 @@ namespace ARMeilleure.CodeGen.X86
_stream.WriteByte((byte)(value >> 56)); _stream.WriteByte((byte)(value >> 56));
} }
} }
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
namespace ARMeilleure.CodeGen.X86 namespace ARMeilleure.CodeGen.X86
{ {
@ -12,47 +13,48 @@ namespace ARMeilleure.CodeGen.X86
private const int BadOp = 0; private const int BadOp = 0;
[Flags] [Flags]
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
private enum InstructionFlags private enum InstructionFlags
{ {
None = 0, None = 0,
RegOnly = 1 << 0, RegOnly = 1 << 0,
Reg8Src = 1 << 1, Reg8Src = 1 << 1,
Reg8Dest = 1 << 2, Reg8Dest = 1 << 2,
RexW = 1 << 3, RexW = 1 << 3,
Vex = 1 << 4, Vex = 1 << 4,
Evex = 1 << 5, Evex = 1 << 5,
PrefixBit = 16, PrefixBit = 16,
PrefixMask = 7 << PrefixBit, PrefixMask = 7 << PrefixBit,
Prefix66 = 1 << PrefixBit, Prefix66 = 1 << PrefixBit,
PrefixF3 = 2 << PrefixBit, PrefixF3 = 2 << PrefixBit,
PrefixF2 = 4 << PrefixBit PrefixF2 = 4 << PrefixBit,
} }
private readonly struct InstructionInfo private readonly struct InstructionInfo
{ {
public int OpRMR { get; } public int OpRMR { get; }
public int OpRMImm8 { get; } public int OpRMImm8 { get; }
public int OpRMImm32 { get; } public int OpRMImm32 { get; }
public int OpRImm64 { get; } public int OpRImm64 { get; }
public int OpRRM { get; } public int OpRRM { get; }
public InstructionFlags Flags { get; } public InstructionFlags Flags { get; }
public InstructionInfo( public InstructionInfo(
int opRMR, int opRMR,
int opRMImm8, int opRMImm8,
int opRMImm32, int opRMImm32,
int opRImm64, int opRImm64,
int opRRM, int opRRM,
InstructionFlags flags) InstructionFlags flags)
{ {
OpRMR = opRMR; OpRMR = opRMR;
OpRMImm8 = opRMImm8; OpRMImm8 = opRMImm8;
OpRMImm32 = opRMImm32; OpRMImm32 = opRMImm32;
OpRImm64 = opRImm64; OpRImm64 = opRImm64;
OpRRM = opRRM; OpRRM = opRRM;
Flags = flags; Flags = flags;
} }
} }
@ -62,6 +64,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
_instTable = new InstructionInfo[(int)X86Instruction.Count]; _instTable = new InstructionInfo[(int)X86Instruction.Count];
#pragma warning disable IDE0055 // Disable formatting
// Name RM/R RM/I8 RM/I32 R/I64 R/RM Flags // Name RM/R RM/I8 RM/I32 R/I64 R/RM Flags
Add(X86Instruction.Add, new InstructionInfo(0x00000001, 0x00000083, 0x00000081, BadOp, 0x00000003, InstructionFlags.None)); Add(X86Instruction.Add, new InstructionInfo(0x00000001, 0x00000083, 0x00000081, BadOp, 0x00000003, InstructionFlags.None));
Add(X86Instruction.Addpd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f58, InstructionFlags.Vex | InstructionFlags.Prefix66)); Add(X86Instruction.Addpd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f58, InstructionFlags.Vex | InstructionFlags.Prefix66));
@ -285,6 +288,7 @@ namespace ARMeilleure.CodeGen.X86
Add(X86Instruction.Xor, new InstructionInfo(0x00000031, 0x06000083, 0x06000081, BadOp, 0x00000033, InstructionFlags.None)); Add(X86Instruction.Xor, new InstructionInfo(0x00000031, 0x06000083, 0x06000081, BadOp, 0x00000033, InstructionFlags.None));
Add(X86Instruction.Xorpd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f57, InstructionFlags.Vex | InstructionFlags.Prefix66)); Add(X86Instruction.Xorpd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f57, InstructionFlags.Vex | InstructionFlags.Prefix66));
Add(X86Instruction.Xorps, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f57, InstructionFlags.Vex)); Add(X86Instruction.Xorps, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f57, InstructionFlags.Vex));
#pragma warning restore IDE0055
static void Add(X86Instruction inst, in InstructionInfo info) static void Add(X86Instruction inst, in InstructionInfo info)
{ {

View File

@ -3,6 +3,6 @@ namespace ARMeilleure.CodeGen.X86
enum CallConvName enum CallConvName
{ {
SystemV, SystemV,
Windows Windows,
} }
} }

View File

@ -20,6 +20,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
if (GetCurrentCallConv() == CallConvName.Windows) if (GetCurrentCallConv() == CallConvName.Windows)
{ {
#pragma warning disable IDE0055 // Disable formatting
return (1 << (int)X86Register.Rax) | return (1 << (int)X86Register.Rax) |
(1 << (int)X86Register.Rcx) | (1 << (int)X86Register.Rcx) |
(1 << (int)X86Register.Rdx) | (1 << (int)X86Register.Rdx) |
@ -39,6 +40,7 @@ namespace ARMeilleure.CodeGen.X86
(1 << (int)X86Register.R9) | (1 << (int)X86Register.R9) |
(1 << (int)X86Register.R10) | (1 << (int)X86Register.R10) |
(1 << (int)X86Register.R11); (1 << (int)X86Register.R11);
#pragma warning restore IDE0055
} }
} }
@ -90,22 +92,32 @@ namespace ARMeilleure.CodeGen.X86
{ {
switch (index) switch (index)
{ {
case 0: return X86Register.Rcx; case 0:
case 1: return X86Register.Rdx; return X86Register.Rcx;
case 2: return X86Register.R8; case 1:
case 3: return X86Register.R9; return X86Register.Rdx;
case 2:
return X86Register.R8;
case 3:
return X86Register.R9;
} }
} }
else /* if (GetCurrentCallConv() == CallConvName.SystemV) */ else /* if (GetCurrentCallConv() == CallConvName.SystemV) */
{ {
switch (index) switch (index)
{ {
case 0: return X86Register.Rdi; case 0:
case 1: return X86Register.Rsi; return X86Register.Rdi;
case 2: return X86Register.Rdx; case 1:
case 3: return X86Register.Rcx; return X86Register.Rsi;
case 4: return X86Register.R8; case 2:
case 5: return X86Register.R9; return X86Register.Rdx;
case 3:
return X86Register.Rcx;
case 4:
return X86Register.R8;
case 5:
return X86Register.R9;
} }
} }
@ -155,4 +167,4 @@ namespace ARMeilleure.CodeGen.X86
: CallConvName.SystemV; : CallConvName.SystemV;
} }
} }
} }

View File

@ -30,7 +30,7 @@ namespace ARMeilleure.CodeGen.X86
Assembler = new Assembler(_stream, relocatable); Assembler = new Assembler(_stream, relocatable);
CallArgsRegionSize = GetCallArgsRegionSize(allocResult, maxCallArgs, out int xmmSaveRegionSize); CallArgsRegionSize = GetCallArgsRegionSize(allocResult, maxCallArgs, out int xmmSaveRegionSize);
XmmSaveRegionSize = xmmSaveRegionSize; XmmSaveRegionSize = xmmSaveRegionSize;
} }
private static int GetCallArgsRegionSize(AllocationResult allocResult, int maxCallArgs, out int xmmSaveRegionSize) private static int GetCallArgsRegionSize(AllocationResult allocResult, int maxCallArgs, out int xmmSaveRegionSize)
@ -102,4 +102,4 @@ namespace ARMeilleure.CodeGen.X86
return label; return label;
} }
} }
} }

View File

@ -17,7 +17,7 @@ namespace ARMeilleure.CodeGen.X86
static class CodeGenerator static class CodeGenerator
{ {
private const int RegistersCount = 16; private const int RegistersCount = 16;
private const int PageSize = 0x1000; private const int PageSize = 0x1000;
private const int StackGuardSize = 0x2000; private const int StackGuardSize = 0x2000;
private static readonly Action<CodeGenContext, Operation>[] _instTable; private static readonly Action<CodeGenContext, Operation>[] _instTable;
@ -26,6 +26,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
_instTable = new Action<CodeGenContext, Operation>[EnumUtils.GetCount(typeof(Instruction))]; _instTable = new Action<CodeGenContext, Operation>[EnumUtils.GetCount(typeof(Instruction))];
#pragma warning disable IDE0055 // Disable formatting
Add(Instruction.Add, GenerateAdd); Add(Instruction.Add, GenerateAdd);
Add(Instruction.BitwiseAnd, GenerateBitwiseAnd); Add(Instruction.BitwiseAnd, GenerateBitwiseAnd);
Add(Instruction.BitwiseExclusiveOr, GenerateBitwiseExclusiveOr); Add(Instruction.BitwiseExclusiveOr, GenerateBitwiseExclusiveOr);
@ -85,6 +86,7 @@ namespace ARMeilleure.CodeGen.X86
Add(Instruction.ZeroExtend16, GenerateZeroExtend16); Add(Instruction.ZeroExtend16, GenerateZeroExtend16);
Add(Instruction.ZeroExtend32, GenerateZeroExtend32); Add(Instruction.ZeroExtend32, GenerateZeroExtend32);
Add(Instruction.ZeroExtend8, GenerateZeroExtend8); Add(Instruction.ZeroExtend8, GenerateZeroExtend8);
#pragma warning restore IDE0055
static void Add(Instruction inst, Action<CodeGenContext, Operation> func) static void Add(Instruction inst, Action<CodeGenContext, Operation> func)
{ {
@ -203,290 +205,290 @@ namespace ARMeilleure.CodeGen.X86
switch (info.Type) switch (info.Type)
{ {
case IntrinsicType.Comis_: case IntrinsicType.Comis_:
{
Operand dest = operation.Destination;
Operand src1 = operation.GetSource(0);
Operand src2 = operation.GetSource(1);
switch (operation.Intrinsic)
{
case Intrinsic.X86Comisdeq:
context.Assembler.Comisd(src1, src2);
context.Assembler.Setcc(dest, X86Condition.Equal);
break;
case Intrinsic.X86Comisdge:
context.Assembler.Comisd(src1, src2);
context.Assembler.Setcc(dest, X86Condition.AboveOrEqual);
break;
case Intrinsic.X86Comisdlt:
context.Assembler.Comisd(src1, src2);
context.Assembler.Setcc(dest, X86Condition.Below);
break;
case Intrinsic.X86Comisseq:
context.Assembler.Comiss(src1, src2);
context.Assembler.Setcc(dest, X86Condition.Equal);
break;
case Intrinsic.X86Comissge:
context.Assembler.Comiss(src1, src2);
context.Assembler.Setcc(dest, X86Condition.AboveOrEqual);
break;
case Intrinsic.X86Comisslt:
context.Assembler.Comiss(src1, src2);
context.Assembler.Setcc(dest, X86Condition.Below);
break;
}
context.Assembler.Movzx8(dest, dest, OperandType.I32);
break;
}
case IntrinsicType.Mxcsr:
{
Operand offset = operation.GetSource(0);
Debug.Assert(offset.Kind == OperandKind.Constant);
Debug.Assert(offset.Type == OperandType.I32);
int offs = offset.AsInt32() + context.CallArgsRegionSize;
Operand rsp = Register(X86Register.Rsp);
Operand memOp = MemoryOp(OperandType.I32, rsp, default, Multiplier.x1, offs);
Debug.Assert(HardwareCapabilities.SupportsSse || HardwareCapabilities.SupportsVexEncoding);
if (operation.Intrinsic == Intrinsic.X86Ldmxcsr)
{
Operand bits = operation.GetSource(1);
Debug.Assert(bits.Type == OperandType.I32);
context.Assembler.Mov(memOp, bits, OperandType.I32);
context.Assembler.Ldmxcsr(memOp);
}
else if (operation.Intrinsic == Intrinsic.X86Stmxcsr)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Debug.Assert(dest.Type == OperandType.I32); Operand src1 = operation.GetSource(0);
Operand src2 = operation.GetSource(1);
context.Assembler.Stmxcsr(memOp); switch (operation.Intrinsic)
context.Assembler.Mov(dest, memOp, OperandType.I32); {
case Intrinsic.X86Comisdeq:
context.Assembler.Comisd(src1, src2);
context.Assembler.Setcc(dest, X86Condition.Equal);
break;
case Intrinsic.X86Comisdge:
context.Assembler.Comisd(src1, src2);
context.Assembler.Setcc(dest, X86Condition.AboveOrEqual);
break;
case Intrinsic.X86Comisdlt:
context.Assembler.Comisd(src1, src2);
context.Assembler.Setcc(dest, X86Condition.Below);
break;
case Intrinsic.X86Comisseq:
context.Assembler.Comiss(src1, src2);
context.Assembler.Setcc(dest, X86Condition.Equal);
break;
case Intrinsic.X86Comissge:
context.Assembler.Comiss(src1, src2);
context.Assembler.Setcc(dest, X86Condition.AboveOrEqual);
break;
case Intrinsic.X86Comisslt:
context.Assembler.Comiss(src1, src2);
context.Assembler.Setcc(dest, X86Condition.Below);
break;
}
context.Assembler.Movzx8(dest, dest, OperandType.I32);
break;
} }
break; case IntrinsicType.Mxcsr:
} {
Operand offset = operation.GetSource(0);
Debug.Assert(offset.Kind == OperandKind.Constant);
Debug.Assert(offset.Type == OperandType.I32);
int offs = offset.AsInt32() + context.CallArgsRegionSize;
Operand rsp = Register(X86Register.Rsp);
Operand memOp = MemoryOp(OperandType.I32, rsp, default, Multiplier.x1, offs);
Debug.Assert(HardwareCapabilities.SupportsSse || HardwareCapabilities.SupportsVexEncoding);
if (operation.Intrinsic == Intrinsic.X86Ldmxcsr)
{
Operand bits = operation.GetSource(1);
Debug.Assert(bits.Type == OperandType.I32);
context.Assembler.Mov(memOp, bits, OperandType.I32);
context.Assembler.Ldmxcsr(memOp);
}
else if (operation.Intrinsic == Intrinsic.X86Stmxcsr)
{
Operand dest = operation.Destination;
Debug.Assert(dest.Type == OperandType.I32);
context.Assembler.Stmxcsr(memOp);
context.Assembler.Mov(dest, memOp, OperandType.I32);
}
break;
}
case IntrinsicType.PopCount: case IntrinsicType.PopCount:
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
EnsureSameType(dest, source); EnsureSameType(dest, source);
Debug.Assert(dest.Type.IsInteger()); Debug.Assert(dest.Type.IsInteger());
context.Assembler.Popcnt(dest, source, dest.Type); context.Assembler.Popcnt(dest, source, dest.Type);
break; break;
} }
case IntrinsicType.Unary: case IntrinsicType.Unary:
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
EnsureSameType(dest, source); EnsureSameType(dest, source);
Debug.Assert(!dest.Type.IsInteger()); Debug.Assert(!dest.Type.IsInteger());
context.Assembler.WriteInstruction(info.Inst, dest, source); context.Assembler.WriteInstruction(info.Inst, dest, source);
break; break;
} }
case IntrinsicType.UnaryToGpr: case IntrinsicType.UnaryToGpr:
{
Operand dest = operation.Destination;
Operand source = operation.GetSource(0);
Debug.Assert(dest.Type.IsInteger() && !source.Type.IsInteger());
if (operation.Intrinsic == Intrinsic.X86Cvtsi2si)
{ {
if (dest.Type == OperandType.I32) Operand dest = operation.Destination;
{ Operand source = operation.GetSource(0);
context.Assembler.Movd(dest, source); // int _mm_cvtsi128_si32(__m128i a)
}
else /* if (dest.Type == OperandType.I64) */
{
context.Assembler.Movq(dest, source); // __int64 _mm_cvtsi128_si64(__m128i a)
}
}
else
{
context.Assembler.WriteInstruction(info.Inst, dest, source, dest.Type);
}
break; Debug.Assert(dest.Type.IsInteger() && !source.Type.IsInteger());
}
if (operation.Intrinsic == Intrinsic.X86Cvtsi2si)
{
if (dest.Type == OperandType.I32)
{
context.Assembler.Movd(dest, source); // int _mm_cvtsi128_si32(__m128i a)
}
else /* if (dest.Type == OperandType.I64) */
{
context.Assembler.Movq(dest, source); // __int64 _mm_cvtsi128_si64(__m128i a)
}
}
else
{
context.Assembler.WriteInstruction(info.Inst, dest, source, dest.Type);
}
break;
}
case IntrinsicType.Binary: case IntrinsicType.Binary:
{
Operand dest = operation.Destination;
Operand src1 = operation.GetSource(0);
Operand src2 = operation.GetSource(1);
EnsureSameType(dest, src1);
if (!HardwareCapabilities.SupportsVexEncoding)
{ {
EnsureSameReg(dest, src1); Operand dest = operation.Destination;
} Operand src1 = operation.GetSource(0);
Operand src2 = operation.GetSource(1);
Debug.Assert(!dest.Type.IsInteger()); EnsureSameType(dest, src1);
Debug.Assert(!src2.Type.IsInteger() || src2.Kind == OperandKind.Constant);
context.Assembler.WriteInstruction(info.Inst, dest, src1, src2); if (!HardwareCapabilities.SupportsVexEncoding)
{
EnsureSameReg(dest, src1);
}
break; Debug.Assert(!dest.Type.IsInteger());
} Debug.Assert(!src2.Type.IsInteger() || src2.Kind == OperandKind.Constant);
case IntrinsicType.BinaryGpr:
{
Operand dest = operation.Destination;
Operand src1 = operation.GetSource(0);
Operand src2 = operation.GetSource(1);
EnsureSameType(dest, src1);
if (!HardwareCapabilities.SupportsVexEncoding)
{
EnsureSameReg(dest, src1);
}
Debug.Assert(!dest.Type.IsInteger() && src2.Type.IsInteger());
context.Assembler.WriteInstruction(info.Inst, dest, src1, src2, src2.Type);
break;
}
case IntrinsicType.Crc32:
{
Operand dest = operation.Destination;
Operand src1 = operation.GetSource(0);
Operand src2 = operation.GetSource(1);
EnsureSameReg(dest, src1);
Debug.Assert(dest.Type.IsInteger() && src1.Type.IsInteger() && src2.Type.IsInteger());
context.Assembler.WriteInstruction(info.Inst, dest, src2, dest.Type);
break;
}
case IntrinsicType.BinaryImm:
{
Operand dest = operation.Destination;
Operand src1 = operation.GetSource(0);
Operand src2 = operation.GetSource(1);
EnsureSameType(dest, src1);
if (!HardwareCapabilities.SupportsVexEncoding)
{
EnsureSameReg(dest, src1);
}
Debug.Assert(!dest.Type.IsInteger() && src2.Kind == OperandKind.Constant);
context.Assembler.WriteInstruction(info.Inst, dest, src1, src2.AsByte());
break;
}
case IntrinsicType.Ternary:
{
Operand dest = operation.Destination;
Operand src1 = operation.GetSource(0);
Operand src2 = operation.GetSource(1);
Operand src3 = operation.GetSource(2);
EnsureSameType(dest, src1, src2, src3);
Debug.Assert(!dest.Type.IsInteger());
if (info.Inst == X86Instruction.Blendvpd && HardwareCapabilities.SupportsVexEncoding)
{
context.Assembler.WriteInstruction(X86Instruction.Vblendvpd, dest, src1, src2, src3);
}
else if (info.Inst == X86Instruction.Blendvps && HardwareCapabilities.SupportsVexEncoding)
{
context.Assembler.WriteInstruction(X86Instruction.Vblendvps, dest, src1, src2, src3);
}
else if (info.Inst == X86Instruction.Pblendvb && HardwareCapabilities.SupportsVexEncoding)
{
context.Assembler.WriteInstruction(X86Instruction.Vpblendvb, dest, src1, src2, src3);
}
else
{
EnsureSameReg(dest, src1);
Debug.Assert(src3.GetRegister().Index == 0);
context.Assembler.WriteInstruction(info.Inst, dest, src1, src2); context.Assembler.WriteInstruction(info.Inst, dest, src1, src2);
break;
} }
break; case IntrinsicType.BinaryGpr:
} {
Operand dest = operation.Destination;
Operand src1 = operation.GetSource(0);
Operand src2 = operation.GetSource(1);
EnsureSameType(dest, src1);
if (!HardwareCapabilities.SupportsVexEncoding)
{
EnsureSameReg(dest, src1);
}
Debug.Assert(!dest.Type.IsInteger() && src2.Type.IsInteger());
context.Assembler.WriteInstruction(info.Inst, dest, src1, src2, src2.Type);
break;
}
case IntrinsicType.Crc32:
{
Operand dest = operation.Destination;
Operand src1 = operation.GetSource(0);
Operand src2 = operation.GetSource(1);
EnsureSameReg(dest, src1);
Debug.Assert(dest.Type.IsInteger() && src1.Type.IsInteger() && src2.Type.IsInteger());
context.Assembler.WriteInstruction(info.Inst, dest, src2, dest.Type);
break;
}
case IntrinsicType.BinaryImm:
{
Operand dest = operation.Destination;
Operand src1 = operation.GetSource(0);
Operand src2 = operation.GetSource(1);
EnsureSameType(dest, src1);
if (!HardwareCapabilities.SupportsVexEncoding)
{
EnsureSameReg(dest, src1);
}
Debug.Assert(!dest.Type.IsInteger() && src2.Kind == OperandKind.Constant);
context.Assembler.WriteInstruction(info.Inst, dest, src1, src2.AsByte());
break;
}
case IntrinsicType.Ternary:
{
Operand dest = operation.Destination;
Operand src1 = operation.GetSource(0);
Operand src2 = operation.GetSource(1);
Operand src3 = operation.GetSource(2);
EnsureSameType(dest, src1, src2, src3);
Debug.Assert(!dest.Type.IsInteger());
if (info.Inst == X86Instruction.Blendvpd && HardwareCapabilities.SupportsVexEncoding)
{
context.Assembler.WriteInstruction(X86Instruction.Vblendvpd, dest, src1, src2, src3);
}
else if (info.Inst == X86Instruction.Blendvps && HardwareCapabilities.SupportsVexEncoding)
{
context.Assembler.WriteInstruction(X86Instruction.Vblendvps, dest, src1, src2, src3);
}
else if (info.Inst == X86Instruction.Pblendvb && HardwareCapabilities.SupportsVexEncoding)
{
context.Assembler.WriteInstruction(X86Instruction.Vpblendvb, dest, src1, src2, src3);
}
else
{
EnsureSameReg(dest, src1);
Debug.Assert(src3.GetRegister().Index == 0);
context.Assembler.WriteInstruction(info.Inst, dest, src1, src2);
}
break;
}
case IntrinsicType.TernaryImm: case IntrinsicType.TernaryImm:
{
Operand dest = operation.Destination;
Operand src1 = operation.GetSource(0);
Operand src2 = operation.GetSource(1);
Operand src3 = operation.GetSource(2);
EnsureSameType(dest, src1, src2);
if (!HardwareCapabilities.SupportsVexEncoding)
{ {
EnsureSameReg(dest, src1); Operand dest = operation.Destination;
Operand src1 = operation.GetSource(0);
Operand src2 = operation.GetSource(1);
Operand src3 = operation.GetSource(2);
EnsureSameType(dest, src1, src2);
if (!HardwareCapabilities.SupportsVexEncoding)
{
EnsureSameReg(dest, src1);
}
Debug.Assert(!dest.Type.IsInteger() && src3.Kind == OperandKind.Constant);
context.Assembler.WriteInstruction(info.Inst, dest, src1, src2, src3.AsByte());
break;
} }
Debug.Assert(!dest.Type.IsInteger() && src3.Kind == OperandKind.Constant);
context.Assembler.WriteInstruction(info.Inst, dest, src1, src2, src3.AsByte());
break;
}
case IntrinsicType.Fma: case IntrinsicType.Fma:
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand src1 = operation.GetSource(0); Operand src1 = operation.GetSource(0);
Operand src2 = operation.GetSource(1); Operand src2 = operation.GetSource(1);
Operand src3 = operation.GetSource(2); Operand src3 = operation.GetSource(2);
Debug.Assert(HardwareCapabilities.SupportsVexEncoding); Debug.Assert(HardwareCapabilities.SupportsVexEncoding);
Debug.Assert(dest.Kind == OperandKind.Register && src1.Kind == OperandKind.Register && src2.Kind == OperandKind.Register); Debug.Assert(dest.Kind == OperandKind.Register && src1.Kind == OperandKind.Register && src2.Kind == OperandKind.Register);
Debug.Assert(src3.Kind == OperandKind.Register || src3.Kind == OperandKind.Memory); Debug.Assert(src3.Kind == OperandKind.Register || src3.Kind == OperandKind.Memory);
EnsureSameType(dest, src1, src2, src3); EnsureSameType(dest, src1, src2, src3);
Debug.Assert(dest.Type == OperandType.V128); Debug.Assert(dest.Type == OperandType.V128);
Debug.Assert(dest.Value == src1.Value); Debug.Assert(dest.Value == src1.Value);
context.Assembler.WriteInstruction(info.Inst, dest, src2, src3); context.Assembler.WriteInstruction(info.Inst, dest, src2, src3);
break; break;
} }
} }
} }
else else
@ -592,7 +594,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateBitwiseNot(CodeGenContext context, Operation operation) private static void GenerateBitwiseNot(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
ValidateUnOp(dest, source); ValidateUnOp(dest, source);
@ -630,7 +632,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateByteSwap(CodeGenContext context, Operation operation) private static void GenerateByteSwap(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
ValidateUnOp(dest, source); ValidateUnOp(dest, source);
@ -761,19 +763,19 @@ namespace ARMeilleure.CodeGen.X86
Operand src2 = operation.GetSource(1); Operand src2 = operation.GetSource(1);
Operand src3 = operation.GetSource(2); Operand src3 = operation.GetSource(2);
EnsureSameReg (dest, src3); EnsureSameReg(dest, src3);
EnsureSameType(dest, src2, src3); EnsureSameType(dest, src2, src3);
Debug.Assert(dest.Type.IsInteger()); Debug.Assert(dest.Type.IsInteger());
Debug.Assert(src1.Type == OperandType.I32); Debug.Assert(src1.Type == OperandType.I32);
context.Assembler.Test (src1, src1, src1.Type); context.Assembler.Test(src1, src1, src1.Type);
context.Assembler.Cmovcc(dest, src2, dest.Type, X86Condition.NotEqual); context.Assembler.Cmovcc(dest, src2, dest.Type, X86Condition.NotEqual);
} }
private static void GenerateConvertI64ToI32(CodeGenContext context, Operation operation) private static void GenerateConvertI64ToI32(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type == OperandType.I32 && source.Type == OperandType.I64); Debug.Assert(dest.Type == OperandType.I32 && source.Type == OperandType.I64);
@ -783,7 +785,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateConvertToFP(CodeGenContext context, Operation operation) private static void GenerateConvertToFP(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64); Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64);
@ -794,7 +796,7 @@ namespace ARMeilleure.CodeGen.X86
if (source.Type.IsInteger()) if (source.Type.IsInteger())
{ {
context.Assembler.Xorps (dest, dest, dest); context.Assembler.Xorps(dest, dest, dest);
context.Assembler.Cvtsi2ss(dest, dest, source, source.Type); context.Assembler.Cvtsi2ss(dest, dest, source, source.Type);
} }
else /* if (source.Type == OperandType.FP64) */ else /* if (source.Type == OperandType.FP64) */
@ -810,7 +812,7 @@ namespace ARMeilleure.CodeGen.X86
if (source.Type.IsInteger()) if (source.Type.IsInteger())
{ {
context.Assembler.Xorps (dest, dest, dest); context.Assembler.Xorps(dest, dest, dest);
context.Assembler.Cvtsi2sd(dest, dest, source, source.Type); context.Assembler.Cvtsi2sd(dest, dest, source, source.Type);
} }
else /* if (source.Type == OperandType.FP32) */ else /* if (source.Type == OperandType.FP32) */
@ -824,7 +826,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateCopy(CodeGenContext context, Operation operation) private static void GenerateCopy(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
EnsureSameType(dest, source); EnsureSameType(dest, source);
@ -837,7 +839,7 @@ namespace ARMeilleure.CodeGen.X86
return; return;
} }
if (dest.Kind == OperandKind.Register && if (dest.Kind == OperandKind.Register &&
source.Kind == OperandKind.Constant && source.Value == 0) source.Kind == OperandKind.Constant && source.Value == 0)
{ {
// Assemble "mov reg, 0" as "xor reg, reg" as the later is more efficient. // Assemble "mov reg, 0" as "xor reg, reg" as the later is more efficient.
@ -855,7 +857,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateCountLeadingZeros(CodeGenContext context, Operation operation) private static void GenerateCountLeadingZeros(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
EnsureSameType(dest, source); EnsureSameType(dest, source);
@ -888,9 +890,9 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateDivide(CodeGenContext context, Operation operation) private static void GenerateDivide(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand dividend = operation.GetSource(0); Operand dividend = operation.GetSource(0);
Operand divisor = operation.GetSource(1); Operand divisor = operation.GetSource(1);
if (!dest.Type.IsInteger()) if (!dest.Type.IsInteger())
{ {
@ -938,7 +940,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateFill(CodeGenContext context, Operation operation) private static void GenerateFill(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand offset = operation.GetSource(0); Operand offset = operation.GetSource(0);
Debug.Assert(offset.Kind == OperandKind.Constant); Debug.Assert(offset.Kind == OperandKind.Constant);
@ -954,7 +956,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateLoad(CodeGenContext context, Operation operation) private static void GenerateLoad(CodeGenContext context, Operation operation)
{ {
Operand value = operation.Destination; Operand value = operation.Destination;
Operand address = Memory(operation.GetSource(0), value.Type); Operand address = Memory(operation.GetSource(0), value.Type);
GenerateLoad(context, address, value); GenerateLoad(context, address, value);
@ -962,7 +964,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateLoad16(CodeGenContext context, Operation operation) private static void GenerateLoad16(CodeGenContext context, Operation operation)
{ {
Operand value = operation.Destination; Operand value = operation.Destination;
Operand address = Memory(operation.GetSource(0), value.Type); Operand address = Memory(operation.GetSource(0), value.Type);
Debug.Assert(value.Type.IsInteger()); Debug.Assert(value.Type.IsInteger());
@ -972,7 +974,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateLoad8(CodeGenContext context, Operation operation) private static void GenerateLoad8(CodeGenContext context, Operation operation)
{ {
Operand value = operation.Destination; Operand value = operation.Destination;
Operand address = Memory(operation.GetSource(0), value.Type); Operand address = Memory(operation.GetSource(0), value.Type);
Debug.Assert(value.Type.IsInteger()); Debug.Assert(value.Type.IsInteger());
@ -1039,7 +1041,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateNegate(CodeGenContext context, Operation operation) private static void GenerateNegate(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
ValidateUnOp(dest, source); ValidateUnOp(dest, source);
@ -1102,7 +1104,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateSignExtend16(CodeGenContext context, Operation operation) private static void GenerateSignExtend16(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
@ -1112,7 +1114,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateSignExtend32(CodeGenContext context, Operation operation) private static void GenerateSignExtend32(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
@ -1122,7 +1124,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateSignExtend8(CodeGenContext context, Operation operation) private static void GenerateSignExtend8(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
@ -1158,7 +1160,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateStackAlloc(CodeGenContext context, Operation operation) private static void GenerateStackAlloc(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand offset = operation.GetSource(0); Operand offset = operation.GetSource(0);
Debug.Assert(offset.Kind == OperandKind.Constant); Debug.Assert(offset.Kind == OperandKind.Constant);
@ -1174,7 +1176,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateStore(CodeGenContext context, Operation operation) private static void GenerateStore(CodeGenContext context, Operation operation)
{ {
Operand value = operation.GetSource(1); Operand value = operation.GetSource(1);
Operand address = Memory(operation.GetSource(0), value.Type); Operand address = Memory(operation.GetSource(0), value.Type);
GenerateStore(context, address, value); GenerateStore(context, address, value);
@ -1182,7 +1184,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateStore16(CodeGenContext context, Operation operation) private static void GenerateStore16(CodeGenContext context, Operation operation)
{ {
Operand value = operation.GetSource(1); Operand value = operation.GetSource(1);
Operand address = Memory(operation.GetSource(0), value.Type); Operand address = Memory(operation.GetSource(0), value.Type);
Debug.Assert(value.Type.IsInteger()); Debug.Assert(value.Type.IsInteger());
@ -1192,7 +1194,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateStore8(CodeGenContext context, Operation operation) private static void GenerateStore8(CodeGenContext context, Operation operation)
{ {
Operand value = operation.GetSource(1); Operand value = operation.GetSource(1);
Operand address = Memory(operation.GetSource(0), value.Type); Operand address = Memory(operation.GetSource(0), value.Type);
Debug.Assert(value.Type.IsInteger()); Debug.Assert(value.Type.IsInteger());
@ -1231,7 +1233,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateVectorCreateScalar(CodeGenContext context, Operation operation) private static void GenerateVectorCreateScalar(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(!dest.Type.IsInteger() && source.Type.IsInteger()); Debug.Assert(!dest.Type.IsInteger() && source.Type.IsInteger());
@ -1278,7 +1280,7 @@ namespace ARMeilleure.CodeGen.X86
mask1 = BitUtils.RotateRight(mask1, 8 - index * 2, 8); mask1 = BitUtils.RotateRight(mask1, 8 - index * 2, 8);
context.Assembler.Pshufd(src1, src1, (byte)mask0); context.Assembler.Pshufd(src1, src1, (byte)mask0);
context.Assembler.Movd (dest, src1); context.Assembler.Movd(dest, src1);
context.Assembler.Pshufd(src1, src1, (byte)mask1); context.Assembler.Pshufd(src1, src1, (byte)mask1);
} }
} }
@ -1294,11 +1296,11 @@ namespace ARMeilleure.CodeGen.X86
} }
else else
{ {
const byte mask = 0b01_00_11_10; const byte Mask = 0b01_00_11_10;
context.Assembler.Pshufd(src1, src1, mask); context.Assembler.Pshufd(src1, src1, Mask);
context.Assembler.Movq (dest, src1); context.Assembler.Movq(dest, src1);
context.Assembler.Pshufd(src1, src1, mask); context.Assembler.Pshufd(src1, src1, Mask);
} }
} }
else else
@ -1308,7 +1310,7 @@ namespace ARMeilleure.CodeGen.X86
(index == 1 && dest.Type == OperandType.FP64)) (index == 1 && dest.Type == OperandType.FP64))
{ {
context.Assembler.Movhlps(dest, dest, src1); context.Assembler.Movhlps(dest, dest, src1);
context.Assembler.Movq (dest, dest); context.Assembler.Movq(dest, dest);
} }
else else
{ {
@ -1455,11 +1457,11 @@ namespace ARMeilleure.CodeGen.X86
int mask0 = 0b11_10_01_00; int mask0 = 0b11_10_01_00;
int mask1 = 0b11_10_01_00; int mask1 = 0b11_10_01_00;
mask0 = BitUtils.RotateRight(mask0, index * 2, 8); mask0 = BitUtils.RotateRight(mask0, index * 2, 8);
mask1 = BitUtils.RotateRight(mask1, 8 - index * 2, 8); mask1 = BitUtils.RotateRight(mask1, 8 - index * 2, 8);
context.Assembler.Pshufd(src1, src1, (byte)mask0); // Lane to be inserted in position 0. context.Assembler.Pshufd(src1, src1, (byte)mask0); // Lane to be inserted in position 0.
context.Assembler.Movss (dest, src1, src2); // dest[127:0] = src1[127:32] | src2[31:0] context.Assembler.Movss(dest, src1, src2); // dest[127:0] = src1[127:32] | src2[31:0]
context.Assembler.Pshufd(dest, dest, (byte)mask1); // Inserted lane in original position. context.Assembler.Pshufd(dest, dest, (byte)mask1); // Inserted lane in original position.
if (dest.GetRegister() != src1.GetRegister()) if (dest.GetRegister() != src1.GetRegister())
@ -1555,7 +1557,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateVectorZeroUpper64(CodeGenContext context, Operation operation) private static void GenerateVectorZeroUpper64(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type == OperandType.V128 && source.Type == OperandType.V128); Debug.Assert(dest.Type == OperandType.V128 && source.Type == OperandType.V128);
@ -1565,7 +1567,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateVectorZeroUpper96(CodeGenContext context, Operation operation) private static void GenerateVectorZeroUpper96(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type == OperandType.V128 && source.Type == OperandType.V128); Debug.Assert(dest.Type == OperandType.V128 && source.Type == OperandType.V128);
@ -1575,7 +1577,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateZeroExtend16(CodeGenContext context, Operation operation) private static void GenerateZeroExtend16(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
@ -1585,7 +1587,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateZeroExtend32(CodeGenContext context, Operation operation) private static void GenerateZeroExtend32(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
@ -1601,7 +1603,7 @@ namespace ARMeilleure.CodeGen.X86
private static void GenerateZeroExtend8(CodeGenContext context, Operation operation) private static void GenerateZeroExtend8(CodeGenContext context, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger()); Debug.Assert(dest.Type.IsInteger() && source.Type.IsInteger());
@ -1613,13 +1615,25 @@ namespace ARMeilleure.CodeGen.X86
{ {
switch (value.Type) switch (value.Type)
{ {
case OperandType.I32: context.Assembler.Mov (value, address, OperandType.I32); break; case OperandType.I32:
case OperandType.I64: context.Assembler.Mov (value, address, OperandType.I64); break; context.Assembler.Mov(value, address, OperandType.I32);
case OperandType.FP32: context.Assembler.Movd (value, address); break; break;
case OperandType.FP64: context.Assembler.Movq (value, address); break; case OperandType.I64:
case OperandType.V128: context.Assembler.Movdqu(value, address); break; context.Assembler.Mov(value, address, OperandType.I64);
break;
case OperandType.FP32:
context.Assembler.Movd(value, address);
break;
case OperandType.FP64:
context.Assembler.Movq(value, address);
break;
case OperandType.V128:
context.Assembler.Movdqu(value, address);
break;
default: Debug.Assert(false); break; default:
Debug.Assert(false);
break;
} }
} }
@ -1627,13 +1641,25 @@ namespace ARMeilleure.CodeGen.X86
{ {
switch (value.Type) switch (value.Type)
{ {
case OperandType.I32: context.Assembler.Mov (address, value, OperandType.I32); break; case OperandType.I32:
case OperandType.I64: context.Assembler.Mov (address, value, OperandType.I64); break; context.Assembler.Mov(address, value, OperandType.I32);
case OperandType.FP32: context.Assembler.Movd (address, value); break; break;
case OperandType.FP64: context.Assembler.Movq (address, value); break; case OperandType.I64:
case OperandType.V128: context.Assembler.Movdqu(address, value); break; context.Assembler.Mov(address, value, OperandType.I64);
break;
case OperandType.FP32:
context.Assembler.Movd(address, value);
break;
case OperandType.FP64:
context.Assembler.Movq(address, value);
break;
case OperandType.V128:
context.Assembler.Movdqu(address, value);
break;
default: Debug.Assert(false); break; default:
Debug.Assert(false);
break;
} }
} }
@ -1670,21 +1696,21 @@ namespace ARMeilleure.CodeGen.X86
[Conditional("DEBUG")] [Conditional("DEBUG")]
private static void ValidateUnOp(Operand dest, Operand source) private static void ValidateUnOp(Operand dest, Operand source)
{ {
EnsureSameReg (dest, source); EnsureSameReg(dest, source);
EnsureSameType(dest, source); EnsureSameType(dest, source);
} }
[Conditional("DEBUG")] [Conditional("DEBUG")]
private static void ValidateBinOp(Operand dest, Operand src1, Operand src2) private static void ValidateBinOp(Operand dest, Operand src1, Operand src2)
{ {
EnsureSameReg (dest, src1); EnsureSameReg(dest, src1);
EnsureSameType(dest, src1, src2); EnsureSameType(dest, src1, src2);
} }
[Conditional("DEBUG")] [Conditional("DEBUG")]
private static void ValidateShift(Operand dest, Operand src1, Operand src2) private static void ValidateShift(Operand dest, Operand src1, Operand src2)
{ {
EnsureSameReg (dest, src1); EnsureSameReg(dest, src1);
EnsureSameType(dest, src1); EnsureSameType(dest, src1);
Debug.Assert(dest.Type.IsInteger() && src2.Type == OperandType.I32); Debug.Assert(dest.Type.IsInteger() && src2.Type == OperandType.I32);
@ -1722,7 +1748,7 @@ namespace ARMeilleure.CodeGen.X86
private static UnwindInfo WritePrologue(CodeGenContext context) private static UnwindInfo WritePrologue(CodeGenContext context)
{ {
List<UnwindPushEntry> pushEntries = new List<UnwindPushEntry>(); List<UnwindPushEntry> pushEntries = new();
Operand rsp = Register(X86Register.Rsp); Operand rsp = Register(X86Register.Rsp);
@ -1827,11 +1853,11 @@ namespace ARMeilleure.CodeGen.X86
// that the OS will map all pages that we'll use. We do that by // that the OS will map all pages that we'll use. We do that by
// doing a dummy read on those pages, forcing a page fault and // doing a dummy read on those pages, forcing a page fault and
// the OS to map them. If they are already mapped, nothing happens. // the OS to map them. If they are already mapped, nothing happens.
const int pageMask = PageSize - 1; const int PageMask = PageSize - 1;
size = (size + pageMask) & ~pageMask; size = (size + PageMask) & ~PageMask;
Operand rsp = Register(X86Register.Rsp); Operand rsp = Register(X86Register.Rsp);
Operand temp = Register(CallingConvention.GetIntReturnRegister()); Operand temp = Register(CallingConvention.GetIntReturnRegister());
for (int offset = PageSize; offset < size; offset += PageSize) for (int offset = PageSize; offset < size; offset += PageSize)
@ -1862,4 +1888,4 @@ namespace ARMeilleure.CodeGen.X86
return Operand.Factory.Register((int)register, RegisterType.Vector, OperandType.V128); return Operand.Factory.Register((int)register, RegisterType.Vector, OperandType.V128);
} }
} }
} }

View File

@ -47,7 +47,7 @@ namespace ARMeilleure.CodeGen.X86
0xc3, // ret 0xc3, // ret
}; };
using MemoryBlock memGetXcr0 = new MemoryBlock((ulong)asmGetXcr0.Length); using MemoryBlock memGetXcr0 = new((ulong)asmGetXcr0.Length);
memGetXcr0.Write(0, asmGetXcr0); memGetXcr0.Write(0, asmGetXcr0);
@ -62,7 +62,7 @@ namespace ARMeilleure.CodeGen.X86
public enum FeatureFlags1Edx public enum FeatureFlags1Edx
{ {
Sse = 1 << 25, Sse = 1 << 25,
Sse2 = 1 << 26 Sse2 = 1 << 26,
} }
[Flags] [Flags]
@ -79,7 +79,7 @@ namespace ARMeilleure.CodeGen.X86
Xsave = 1 << 26, Xsave = 1 << 26,
Osxsave = 1 << 27, Osxsave = 1 << 27,
Avx = 1 << 28, Avx = 1 << 28,
F16c = 1 << 29 F16c = 1 << 29,
} }
[Flags] [Flags]
@ -90,7 +90,7 @@ namespace ARMeilleure.CodeGen.X86
Avx512dq = 1 << 17, Avx512dq = 1 << 17,
Sha = 1 << 29, Sha = 1 << 29,
Avx512bw = 1 << 30, Avx512bw = 1 << 30,
Avx512vl = 1 << 31 Avx512vl = 1 << 31,
} }
[Flags] [Flags]
@ -106,7 +106,7 @@ namespace ARMeilleure.CodeGen.X86
YmmHi128 = 1 << 2, YmmHi128 = 1 << 2,
Opmask = 1 << 5, Opmask = 1 << 5,
ZmmHi256 = 1 << 6, ZmmHi256 = 1 << 6,
Hi16Zmm = 1 << 7 Hi16Zmm = 1 << 7,
} }
public static FeatureFlags1Edx FeatureInfo1Edx { get; } public static FeatureFlags1Edx FeatureInfo1Edx { get; }
@ -141,4 +141,4 @@ namespace ARMeilleure.CodeGen.X86
public static bool SupportsVexEncoding => SupportsAvx && !ForceLegacySse; public static bool SupportsVexEncoding => SupportsAvx && !ForceLegacySse;
public static bool SupportsEvexEncoding => SupportsAvx512F && !ForceLegacySse; public static bool SupportsEvexEncoding => SupportsAvx512F && !ForceLegacySse;
} }
} }

View File

@ -3,7 +3,7 @@ namespace ARMeilleure.CodeGen.X86
readonly struct IntrinsicInfo readonly struct IntrinsicInfo
{ {
public X86Instruction Inst { get; } public X86Instruction Inst { get; }
public IntrinsicType Type { get; } public IntrinsicType Type { get; }
public IntrinsicInfo(X86Instruction inst, IntrinsicType type) public IntrinsicInfo(X86Instruction inst, IntrinsicType type)
{ {
@ -11,4 +11,4 @@ namespace ARMeilleure.CodeGen.X86
Type = type; Type = type;
} }
} }
} }

View File

@ -5,12 +5,13 @@ namespace ARMeilleure.CodeGen.X86
{ {
static class IntrinsicTable static class IntrinsicTable
{ {
private static IntrinsicInfo[] _intrinTable; private static readonly IntrinsicInfo[] _intrinTable;
static IntrinsicTable() static IntrinsicTable()
{ {
_intrinTable = new IntrinsicInfo[EnumUtils.GetCount(typeof(Intrinsic))]; _intrinTable = new IntrinsicInfo[EnumUtils.GetCount(typeof(Intrinsic))];
#pragma warning disable IDE0055 // Disable formatting
Add(Intrinsic.X86Addpd, new IntrinsicInfo(X86Instruction.Addpd, IntrinsicType.Binary)); Add(Intrinsic.X86Addpd, new IntrinsicInfo(X86Instruction.Addpd, IntrinsicType.Binary));
Add(Intrinsic.X86Addps, new IntrinsicInfo(X86Instruction.Addps, IntrinsicType.Binary)); Add(Intrinsic.X86Addps, new IntrinsicInfo(X86Instruction.Addps, IntrinsicType.Binary));
Add(Intrinsic.X86Addsd, new IntrinsicInfo(X86Instruction.Addsd, IntrinsicType.Binary)); Add(Intrinsic.X86Addsd, new IntrinsicInfo(X86Instruction.Addsd, IntrinsicType.Binary));
@ -185,6 +186,7 @@ namespace ARMeilleure.CodeGen.X86
Add(Intrinsic.X86Vpternlogd, new IntrinsicInfo(X86Instruction.Vpternlogd, IntrinsicType.TernaryImm)); Add(Intrinsic.X86Vpternlogd, new IntrinsicInfo(X86Instruction.Vpternlogd, IntrinsicType.TernaryImm));
Add(Intrinsic.X86Xorpd, new IntrinsicInfo(X86Instruction.Xorpd, IntrinsicType.Binary)); Add(Intrinsic.X86Xorpd, new IntrinsicInfo(X86Instruction.Xorpd, IntrinsicType.Binary));
Add(Intrinsic.X86Xorps, new IntrinsicInfo(X86Instruction.Xorps, IntrinsicType.Binary)); Add(Intrinsic.X86Xorps, new IntrinsicInfo(X86Instruction.Xorps, IntrinsicType.Binary));
#pragma warning restore IDE0055
} }
private static void Add(Intrinsic intrin, IntrinsicInfo info) private static void Add(Intrinsic intrin, IntrinsicInfo info)
@ -197,4 +199,4 @@ namespace ARMeilleure.CodeGen.X86
return _intrinTable[(int)intrin]; return _intrinTable[(int)intrin];
} }
} }
} }

View File

@ -13,6 +13,6 @@ namespace ARMeilleure.CodeGen.X86
Crc32, Crc32,
Ternary, Ternary,
TernaryImm, TernaryImm,
Fma Fma,
} }
} }

View File

@ -10,6 +10,6 @@ namespace ARMeilleure.CodeGen.X86
Rlo = 1 << 13, // Round Mode low bit. Rlo = 1 << 13, // Round Mode low bit.
Um = 1 << 11, // Underflow Mask. Um = 1 << 11, // Underflow Mask.
Dm = 1 << 8, // Denormal Mask. Dm = 1 << 8, // Denormal Mask.
Daz = 1 << 6 // Denormals Are Zero. Daz = 1 << 6, // Denormals Are Zero.
} }
} }

View File

@ -104,11 +104,11 @@ namespace ARMeilleure.CodeGen.X86
case Instruction.Tailcall: case Instruction.Tailcall:
if (callConv == CallConvName.Windows) if (callConv == CallConvName.Windows)
{ {
PreAllocatorWindows.InsertTailcallCopies(block.Operations, stackAlloc, node); PreAllocatorWindows.InsertTailcallCopies(block.Operations, node);
} }
else else
{ {
PreAllocatorSystemV.InsertTailcallCopies(block.Operations, stackAlloc, node); PreAllocatorSystemV.InsertTailcallCopies(block.Operations, node);
} }
break; break;
@ -177,10 +177,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
src2 = node.GetSource(1); src2 = node.GetSource(1);
Operand temp = src1; (src2, src1) = (src1, src2);
src1 = src2;
src2 = temp;
node.SetSource(0, src1); node.SetSource(0, src1);
node.SetSource(1, src2); node.SetSource(1, src2);
@ -228,151 +225,151 @@ namespace ARMeilleure.CodeGen.X86
case Instruction.CompareAndSwap: case Instruction.CompareAndSwap:
case Instruction.CompareAndSwap16: case Instruction.CompareAndSwap16:
case Instruction.CompareAndSwap8: case Instruction.CompareAndSwap8:
{
OperandType type = node.GetSource(1).Type;
if (type == OperandType.V128)
{ {
// Handle the many restrictions of the compare and exchange (16 bytes) instruction: OperandType type = node.GetSource(1).Type;
// - The expected value should be in RDX:RAX.
// - The new value to be written should be in RCX:RBX. if (type == OperandType.V128)
// - The value at the memory location is loaded to RDX:RAX.
void SplitOperand(Operand source, Operand lr, Operand hr)
{ {
nodes.AddBefore(node, Operation(Instruction.VectorExtract, lr, source, Const(0))); // Handle the many restrictions of the compare and exchange (16 bytes) instruction:
nodes.AddBefore(node, Operation(Instruction.VectorExtract, hr, source, Const(1))); // - The expected value should be in RDX:RAX.
// - The new value to be written should be in RCX:RBX.
// - The value at the memory location is loaded to RDX:RAX.
void SplitOperand(Operand source, Operand lr, Operand hr)
{
nodes.AddBefore(node, Operation(Instruction.VectorExtract, lr, source, Const(0)));
nodes.AddBefore(node, Operation(Instruction.VectorExtract, hr, source, Const(1)));
}
Operand rax = Gpr(X86Register.Rax, OperandType.I64);
Operand rbx = Gpr(X86Register.Rbx, OperandType.I64);
Operand rcx = Gpr(X86Register.Rcx, OperandType.I64);
Operand rdx = Gpr(X86Register.Rdx, OperandType.I64);
SplitOperand(node.GetSource(1), rax, rdx);
SplitOperand(node.GetSource(2), rbx, rcx);
Operation operation = node;
node = nodes.AddAfter(node, Operation(Instruction.VectorCreateScalar, dest, rax));
nodes.AddAfter(node, Operation(Instruction.VectorInsert, dest, dest, rdx, Const(1)));
operation.SetDestinations(new Operand[] { rdx, rax });
operation.SetSources(new Operand[] { operation.GetSource(0), rdx, rax, rcx, rbx });
}
else
{
// Handle the many restrictions of the compare and exchange (32/64) instruction:
// - The expected value should be in (E/R)AX.
// - The value at the memory location is loaded to (E/R)AX.
Operand expected = node.GetSource(1);
Operand newValue = node.GetSource(2);
Operand rax = Gpr(X86Register.Rax, expected.Type);
nodes.AddBefore(node, Operation(Instruction.Copy, rax, expected));
// We need to store the new value into a temp, since it may
// be a constant, and this instruction does not support immediate operands.
Operand temp = Local(newValue.Type);
nodes.AddBefore(node, Operation(Instruction.Copy, temp, newValue));
node.SetSources(new Operand[] { node.GetSource(0), rax, temp });
nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax));
node.Destination = rax;
} }
Operand rax = Gpr(X86Register.Rax, OperandType.I64); break;
Operand rbx = Gpr(X86Register.Rbx, OperandType.I64);
Operand rcx = Gpr(X86Register.Rcx, OperandType.I64);
Operand rdx = Gpr(X86Register.Rdx, OperandType.I64);
SplitOperand(node.GetSource(1), rax, rdx);
SplitOperand(node.GetSource(2), rbx, rcx);
Operation operation = node;
node = nodes.AddAfter(node, Operation(Instruction.VectorCreateScalar, dest, rax));
nodes.AddAfter(node, Operation(Instruction.VectorInsert, dest, dest, rdx, Const(1)));
operation.SetDestinations(new Operand[] { rdx, rax });
operation.SetSources(new Operand[] { operation.GetSource(0), rdx, rax, rcx, rbx });
} }
else
{
// Handle the many restrictions of the compare and exchange (32/64) instruction:
// - The expected value should be in (E/R)AX.
// - The value at the memory location is loaded to (E/R)AX.
Operand expected = node.GetSource(1);
Operand newValue = node.GetSource(2);
Operand rax = Gpr(X86Register.Rax, expected.Type);
nodes.AddBefore(node, Operation(Instruction.Copy, rax, expected));
// We need to store the new value into a temp, since it may
// be a constant, and this instruction does not support immediate operands.
Operand temp = Local(newValue.Type);
nodes.AddBefore(node, Operation(Instruction.Copy, temp, newValue));
node.SetSources(new Operand[] { node.GetSource(0), rax, temp });
nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax));
node.Destination = rax;
}
break;
}
case Instruction.Divide: case Instruction.Divide:
case Instruction.DivideUI: case Instruction.DivideUI:
{
// Handle the many restrictions of the division instructions:
// - The dividend is always in RDX:RAX.
// - The result is always in RAX.
// - Additionally it also writes the remainder in RDX.
if (dest.Type.IsInteger())
{ {
// Handle the many restrictions of the division instructions:
// - The dividend is always in RDX:RAX.
// - The result is always in RAX.
// - Additionally it also writes the remainder in RDX.
if (dest.Type.IsInteger())
{
Operand src1 = node.GetSource(0);
Operand rax = Gpr(X86Register.Rax, src1.Type);
Operand rdx = Gpr(X86Register.Rdx, src1.Type);
nodes.AddBefore(node, Operation(Instruction.Copy, rax, src1));
nodes.AddBefore(node, Operation(Instruction.Clobber, rdx));
nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax));
node.SetSources(new Operand[] { rdx, rax, node.GetSource(1) });
node.Destination = rax;
}
break;
}
case Instruction.Extended:
{
bool isBlend = node.Intrinsic == Intrinsic.X86Blendvpd ||
node.Intrinsic == Intrinsic.X86Blendvps ||
node.Intrinsic == Intrinsic.X86Pblendvb;
// BLENDVPD, BLENDVPS, PBLENDVB last operand is always implied to be XMM0 when VEX is not supported.
// SHA256RNDS2 always has an implied XMM0 as a last operand.
if ((isBlend && !HardwareCapabilities.SupportsVexEncoding) || node.Intrinsic == Intrinsic.X86Sha256Rnds2)
{
Operand xmm0 = Xmm(X86Register.Xmm0, OperandType.V128);
nodes.AddBefore(node, Operation(Instruction.Copy, xmm0, node.GetSource(2)));
node.SetSource(2, xmm0);
}
break;
}
case Instruction.Multiply64HighSI:
case Instruction.Multiply64HighUI:
{
// Handle the many restrictions of the i64 * i64 = i128 multiply instructions:
// - The multiplicand is always in RAX.
// - The lower 64-bits of the result is always in RAX.
// - The higher 64-bits of the result is always in RDX.
Operand src1 = node.GetSource(0); Operand src1 = node.GetSource(0);
Operand rax = Gpr(X86Register.Rax, src1.Type); Operand rax = Gpr(X86Register.Rax, src1.Type);
Operand rdx = Gpr(X86Register.Rdx, src1.Type); Operand rdx = Gpr(X86Register.Rdx, src1.Type);
nodes.AddBefore(node, Operation(Instruction.Copy, rax, src1)); nodes.AddBefore(node, Operation(Instruction.Copy, rax, src1));
nodes.AddBefore(node, Operation(Instruction.Clobber, rdx));
nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax)); node.SetSource(0, rax);
node.SetSources(new Operand[] { rdx, rax, node.GetSource(1) }); nodes.AddAfter(node, Operation(Instruction.Copy, dest, rdx));
node.Destination = rax;
node.SetDestinations(new Operand[] { rdx, rax });
break;
} }
break;
}
case Instruction.Extended:
{
bool isBlend = node.Intrinsic == Intrinsic.X86Blendvpd ||
node.Intrinsic == Intrinsic.X86Blendvps ||
node.Intrinsic == Intrinsic.X86Pblendvb;
// BLENDVPD, BLENDVPS, PBLENDVB last operand is always implied to be XMM0 when VEX is not supported.
// SHA256RNDS2 always has an implied XMM0 as a last operand.
if ((isBlend && !HardwareCapabilities.SupportsVexEncoding) || node.Intrinsic == Intrinsic.X86Sha256Rnds2)
{
Operand xmm0 = Xmm(X86Register.Xmm0, OperandType.V128);
nodes.AddBefore(node, Operation(Instruction.Copy, xmm0, node.GetSource(2)));
node.SetSource(2, xmm0);
}
break;
}
case Instruction.Multiply64HighSI:
case Instruction.Multiply64HighUI:
{
// Handle the many restrictions of the i64 * i64 = i128 multiply instructions:
// - The multiplicand is always in RAX.
// - The lower 64-bits of the result is always in RAX.
// - The higher 64-bits of the result is always in RDX.
Operand src1 = node.GetSource(0);
Operand rax = Gpr(X86Register.Rax, src1.Type);
Operand rdx = Gpr(X86Register.Rdx, src1.Type);
nodes.AddBefore(node, Operation(Instruction.Copy, rax, src1));
node.SetSource(0, rax);
nodes.AddAfter(node, Operation(Instruction.Copy, dest, rdx));
node.SetDestinations(new Operand[] { rdx, rax });
break;
}
case Instruction.RotateRight: case Instruction.RotateRight:
case Instruction.ShiftLeft: case Instruction.ShiftLeft:
case Instruction.ShiftRightSI: case Instruction.ShiftRightSI:
case Instruction.ShiftRightUI: case Instruction.ShiftRightUI:
{
// The shift register is always implied to be CL (low 8-bits of RCX or ECX).
if (node.GetSource(1).Kind == OperandKind.LocalVariable)
{ {
Operand rcx = Gpr(X86Register.Rcx, OperandType.I32); // The shift register is always implied to be CL (low 8-bits of RCX or ECX).
if (node.GetSource(1).Kind == OperandKind.LocalVariable)
{
Operand rcx = Gpr(X86Register.Rcx, OperandType.I32);
nodes.AddBefore(node, Operation(Instruction.Copy, rcx, node.GetSource(1))); nodes.AddBefore(node, Operation(Instruction.Copy, rcx, node.GetSource(1)));
node.SetSource(1, rcx); node.SetSource(1, rcx);
}
break;
} }
break;
}
} }
} }
@ -459,7 +456,7 @@ namespace ARMeilleure.CodeGen.X86
// Unsigned integer to FP conversions are not supported on X86. // Unsigned integer to FP conversions are not supported on X86.
// We need to turn them into signed integer to FP conversions, and // We need to turn them into signed integer to FP conversions, and
// adjust the final result. // adjust the final result.
Operand dest = node.Destination; Operand dest = node.Destination;
Operand source = node.GetSource(0); Operand source = node.GetSource(0);
Debug.Assert(source.Type.IsInteger(), $"Invalid source type \"{source.Type}\"."); Debug.Assert(source.Type.IsInteger(), $"Invalid source type \"{source.Type}\".");
@ -472,8 +469,8 @@ namespace ARMeilleure.CodeGen.X86
// and then use the 64-bits signed conversion instructions. // and then use the 64-bits signed conversion instructions.
Operand zex = Local(OperandType.I64); Operand zex = Local(OperandType.I64);
node = nodes.AddAfter(node, Operation(Instruction.ZeroExtend32, zex, source)); node = nodes.AddAfter(node, Operation(Instruction.ZeroExtend32, zex, source));
node = nodes.AddAfter(node, Operation(Instruction.ConvertToFP, dest, zex)); nodes.AddAfter(node, Operation(Instruction.ConvertToFP, dest, zex));
} }
else /* if (source.Type == OperandType.I64) */ else /* if (source.Type == OperandType.I64) */
{ {
@ -487,15 +484,15 @@ namespace ARMeilleure.CodeGen.X86
// --- This can be done efficiently by adding the result to itself. // --- This can be done efficiently by adding the result to itself.
// -- Then, we need to add the least significant bit that was shifted out. // -- Then, we need to add the least significant bit that was shifted out.
// --- We can convert the least significant bit to float, and add it to the result. // --- We can convert the least significant bit to float, and add it to the result.
Operand lsb = Local(OperandType.I64); Operand lsb = Local(OperandType.I64);
Operand half = Local(OperandType.I64); Operand half = Local(OperandType.I64);
Operand lsbF = Local(dest.Type); Operand lsbF = Local(dest.Type);
node = nodes.AddAfter(node, Operation(Instruction.Copy, lsb, source)); node = nodes.AddAfter(node, Operation(Instruction.Copy, lsb, source));
node = nodes.AddAfter(node, Operation(Instruction.Copy, half, source)); node = nodes.AddAfter(node, Operation(Instruction.Copy, half, source));
node = nodes.AddAfter(node, Operation(Instruction.BitwiseAnd, lsb, lsb, Const(1L))); node = nodes.AddAfter(node, Operation(Instruction.BitwiseAnd, lsb, lsb, Const(1L)));
node = nodes.AddAfter(node, Operation(Instruction.ShiftRightUI, half, half, Const(1))); node = nodes.AddAfter(node, Operation(Instruction.ShiftRightUI, half, half, Const(1)));
node = nodes.AddAfter(node, Operation(Instruction.ConvertToFP, lsbF, lsb)); node = nodes.AddAfter(node, Operation(Instruction.ConvertToFP, lsbF, lsb));
@ -513,7 +510,7 @@ namespace ARMeilleure.CodeGen.X86
// There's no SSE FP negate instruction, so we need to transform that into // There's no SSE FP negate instruction, so we need to transform that into
// a XOR of the value to be negated with a mask with the highest bit set. // a XOR of the value to be negated with a mask with the highest bit set.
// This also produces -0 for a negation of the value 0. // This also produces -0 for a negation of the value 0.
Operand dest = node.Destination; Operand dest = node.Destination;
Operand source = node.GetSource(0); Operand source = node.GetSource(0);
Debug.Assert(dest.Type == OperandType.FP32 || Debug.Assert(dest.Type == OperandType.FP32 ||
@ -569,14 +566,14 @@ namespace ARMeilleure.CodeGen.X86
if ((index & 1) != 0) if ((index & 1) != 0)
{ {
node = nodes.AddAfter(node, Operation(Instruction.ZeroExtend8, temp1, temp1)); node = nodes.AddAfter(node, Operation(Instruction.ZeroExtend8, temp1, temp1));
node = nodes.AddAfter(node, Operation(Instruction.ShiftLeft, temp2, temp2, Const(8))); node = nodes.AddAfter(node, Operation(Instruction.ShiftLeft, temp2, temp2, Const(8)));
node = nodes.AddAfter(node, Operation(Instruction.BitwiseOr, temp1, temp1, temp2)); node = nodes.AddAfter(node, Operation(Instruction.BitwiseOr, temp1, temp1, temp2));
} }
else else
{ {
node = nodes.AddAfter(node, Operation(Instruction.ZeroExtend8, temp2, temp2)); node = nodes.AddAfter(node, Operation(Instruction.ZeroExtend8, temp2, temp2));
node = nodes.AddAfter(node, Operation(Instruction.BitwiseAnd, temp1, temp1, Const(0xff00))); node = nodes.AddAfter(node, Operation(Instruction.BitwiseAnd, temp1, temp1, Const(0xff00)));
node = nodes.AddAfter(node, Operation(Instruction.BitwiseOr, temp1, temp1, temp2)); node = nodes.AddAfter(node, Operation(Instruction.BitwiseOr, temp1, temp1, temp2));
} }
Operation vinsOp = Operation(Instruction.VectorInsert16, dest, src1, temp1, Const(index >> 1)); Operation vinsOp = Operation(Instruction.VectorInsert16, dest, src1, temp1, Const(index >> 1));
@ -709,16 +706,11 @@ namespace ARMeilleure.CodeGen.X86
private static bool HasConstSrc1(Instruction inst) private static bool HasConstSrc1(Instruction inst)
{ {
switch (inst) return inst switch
{ {
case Instruction.Copy: Instruction.Copy or Instruction.LoadArgument or Instruction.Spill or Instruction.SpillArg => true,
case Instruction.LoadArgument: _ => false,
case Instruction.Spill: };
case Instruction.SpillArg:
return true;
}
return false;
} }
private static bool HasConstSrc2(Instruction inst) private static bool HasConstSrc2(Instruction inst)
@ -762,15 +754,15 @@ namespace ARMeilleure.CodeGen.X86
case Instruction.BranchIf: case Instruction.BranchIf:
case Instruction.Compare: case Instruction.Compare:
{ {
Operand comp = operation.GetSource(2); Operand comp = operation.GetSource(2);
Debug.Assert(comp.Kind == OperandKind.Constant); Debug.Assert(comp.Kind == OperandKind.Constant);
var compType = (Comparison)comp.AsInt32(); var compType = (Comparison)comp.AsInt32();
return compType == Comparison.Equal || compType == Comparison.NotEqual; return compType == Comparison.Equal || compType == Comparison.NotEqual;
} }
} }
return false; return false;
@ -793,4 +785,4 @@ namespace ARMeilleure.CodeGen.X86
return info.Type != IntrinsicType.Crc32; return info.Type != IntrinsicType.Crc32;
} }
} }
} }

View File

@ -1,4 +1,3 @@
using ARMeilleure.CodeGen.RegisterAllocators;
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation; using ARMeilleure.Translation;
using System; using System;
@ -15,9 +14,9 @@ namespace ARMeilleure.CodeGen.X86
{ {
Operand dest = node.Destination; Operand dest = node.Destination;
List<Operand> sources = new List<Operand> List<Operand> sources = new()
{ {
node.GetSource(0) node.GetSource(0),
}; };
int argsCount = node.SourcesCount - 1; int argsCount = node.SourcesCount - 1;
@ -52,10 +51,10 @@ namespace ARMeilleure.CodeGen.X86
if (source.Type == OperandType.V128 && passOnReg) if (source.Type == OperandType.V128 && passOnReg)
{ {
// V128 is a struct, we pass each half on a GPR if possible. // V128 is a struct, we pass each half on a GPR if possible.
Operand argReg = Gpr(CallingConvention.GetIntArgumentRegister(intCount++), OperandType.I64); Operand argReg = Gpr(CallingConvention.GetIntArgumentRegister(intCount++), OperandType.I64);
Operand argReg2 = Gpr(CallingConvention.GetIntArgumentRegister(intCount++), OperandType.I64); Operand argReg2 = Gpr(CallingConvention.GetIntArgumentRegister(intCount++), OperandType.I64);
nodes.AddBefore(node, Operation(Instruction.VectorExtract, argReg, source, Const(0))); nodes.AddBefore(node, Operation(Instruction.VectorExtract, argReg, source, Const(0)));
nodes.AddBefore(node, Operation(Instruction.VectorExtract, argReg2, source, Const(1))); nodes.AddBefore(node, Operation(Instruction.VectorExtract, argReg2, source, Const(1)));
continue; continue;
@ -91,7 +90,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
if (dest.Type == OperandType.V128) if (dest.Type == OperandType.V128)
{ {
Operand retLReg = Gpr(CallingConvention.GetIntReturnRegister(), OperandType.I64); Operand retLReg = Gpr(CallingConvention.GetIntReturnRegister(), OperandType.I64);
Operand retHReg = Gpr(CallingConvention.GetIntReturnRegisterHigh(), OperandType.I64); Operand retHReg = Gpr(CallingConvention.GetIntReturnRegisterHigh(), OperandType.I64);
Operation operation = node; Operation operation = node;
@ -116,11 +115,11 @@ namespace ARMeilleure.CodeGen.X86
} }
} }
public static void InsertTailcallCopies(IntrusiveList<Operation> nodes, StackAllocator stackAlloc, Operation node) public static void InsertTailcallCopies(IntrusiveList<Operation> nodes, Operation node)
{ {
List<Operand> sources = new List<Operand> List<Operand> sources = new()
{ {
node.GetSource(0) node.GetSource(0),
}; };
int argsCount = node.SourcesCount - 1; int argsCount = node.SourcesCount - 1;
@ -251,11 +250,11 @@ namespace ARMeilleure.CodeGen.X86
// V128 is a struct, we pass each half on a GPR if possible. // V128 is a struct, we pass each half on a GPR if possible.
Operand pArg = Local(OperandType.V128); Operand pArg = Local(OperandType.V128);
Operand argLReg = Gpr(CallingConvention.GetIntArgumentRegister(intCount), OperandType.I64); Operand argLReg = Gpr(CallingConvention.GetIntArgumentRegister(intCount), OperandType.I64);
Operand argHReg = Gpr(CallingConvention.GetIntArgumentRegister(intCount + 1), OperandType.I64); Operand argHReg = Gpr(CallingConvention.GetIntArgumentRegister(intCount + 1), OperandType.I64);
Operation copyL = Operation(Instruction.VectorCreateScalar, pArg, argLReg); Operation copyL = Operation(Instruction.VectorCreateScalar, pArg, argLReg);
Operation copyH = Operation(Instruction.VectorInsert, pArg, pArg, argHReg, Const(1)); Operation copyH = Operation(Instruction.VectorInsert, pArg, pArg, argHReg, Const(1));
cctx.Cfg.Entry.Operations.AddFirst(copyH); cctx.Cfg.Entry.Operations.AddFirst(copyH);
cctx.Cfg.Entry.Operations.AddFirst(copyL); cctx.Cfg.Entry.Operations.AddFirst(copyL);
@ -313,7 +312,7 @@ namespace ARMeilleure.CodeGen.X86
if (source.Type == OperandType.V128) if (source.Type == OperandType.V128)
{ {
Operand retLReg = Gpr(CallingConvention.GetIntReturnRegister(), OperandType.I64); Operand retLReg = Gpr(CallingConvention.GetIntReturnRegister(), OperandType.I64);
Operand retHReg = Gpr(CallingConvention.GetIntReturnRegisterHigh(), OperandType.I64); Operand retHReg = Gpr(CallingConvention.GetIntReturnRegisterHigh(), OperandType.I64);
nodes.AddBefore(node, Operation(Instruction.VectorExtract, retLReg, source, Const(0))); nodes.AddBefore(node, Operation(Instruction.VectorExtract, retLReg, source, Const(0)));
@ -331,4 +330,4 @@ namespace ARMeilleure.CodeGen.X86
} }
} }
} }
} }

View File

@ -155,7 +155,7 @@ namespace ARMeilleure.CodeGen.X86
node.SetSources(sources); node.SetSources(sources);
} }
public static void InsertTailcallCopies(IntrusiveList<Operation> nodes, StackAllocator stackAlloc, Operation node) public static void InsertTailcallCopies(IntrusiveList<Operation> nodes, Operation node)
{ {
int argsCount = node.SourcesCount - 1; int argsCount = node.SourcesCount - 1;
int maxArgs = CallingConvention.GetArgumentsOnRegsCount(); int maxArgs = CallingConvention.GetArgumentsOnRegsCount();
@ -324,4 +324,4 @@ namespace ARMeilleure.CodeGen.X86
node.SetSources(Array.Empty<Operand>()); node.SetSources(Array.Empty<Operand>());
} }
} }
} }

View File

@ -5,22 +5,22 @@ namespace ARMeilleure.CodeGen.X86
{ {
enum X86Condition enum X86Condition
{ {
Overflow = 0x0, Overflow = 0x0,
NotOverflow = 0x1, NotOverflow = 0x1,
Below = 0x2, Below = 0x2,
AboveOrEqual = 0x3, AboveOrEqual = 0x3,
Equal = 0x4, Equal = 0x4,
NotEqual = 0x5, NotEqual = 0x5,
BelowOrEqual = 0x6, BelowOrEqual = 0x6,
Above = 0x7, Above = 0x7,
Sign = 0x8, Sign = 0x8,
NotSign = 0x9, NotSign = 0x9,
ParityEven = 0xa, ParityEven = 0xa,
ParityOdd = 0xb, ParityOdd = 0xb,
Less = 0xc, Less = 0xc,
GreaterOrEqual = 0xd, GreaterOrEqual = 0xd,
LessOrEqual = 0xe, LessOrEqual = 0xe,
Greater = 0xf Greater = 0xf,
} }
static class ComparisonX86Extensions static class ComparisonX86Extensions
@ -29,6 +29,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
return comp switch return comp switch
{ {
#pragma warning disable IDE0055 // Disable formatting
Comparison.Equal => X86Condition.Equal, Comparison.Equal => X86Condition.Equal,
Comparison.NotEqual => X86Condition.NotEqual, Comparison.NotEqual => X86Condition.NotEqual,
Comparison.Greater => X86Condition.Greater, Comparison.Greater => X86Condition.Greater,
@ -39,9 +40,10 @@ namespace ARMeilleure.CodeGen.X86
Comparison.Less => X86Condition.Less, Comparison.Less => X86Condition.Less,
Comparison.GreaterOrEqualUI => X86Condition.AboveOrEqual, Comparison.GreaterOrEqualUI => X86Condition.AboveOrEqual,
Comparison.LessUI => X86Condition.Below, Comparison.LessUI => X86Condition.Below,
#pragma warning restore IDE0055
_ => throw new ArgumentException(null, nameof(comp)) _ => throw new ArgumentException(null, nameof(comp)),
}; };
} }
} }
} }

View File

@ -226,6 +226,6 @@ namespace ARMeilleure.CodeGen.X86
Xorpd, Xorpd,
Xorps, Xorps,
Count Count,
} }
} }

View File

@ -215,7 +215,7 @@ namespace ARMeilleure.CodeGen.X86
1 => Multiplier.x2, 1 => Multiplier.x2,
2 => Multiplier.x4, 2 => Multiplier.x4,
3 => Multiplier.x8, 3 => Multiplier.x8,
_ => Multiplier.x1 _ => Multiplier.x1,
}; };
baseOp = indexOnSrc2 ? src1 : src2; baseOp = indexOnSrc2 ? src1 : src2;

View File

@ -1,5 +1,8 @@
using System.Diagnostics.CodeAnalysis;
namespace ARMeilleure.CodeGen.X86 namespace ARMeilleure.CodeGen.X86
{ {
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
enum X86Register enum X86Register
{ {
Invalid = -1, Invalid = -1,
@ -12,8 +15,8 @@ namespace ARMeilleure.CodeGen.X86
Rbp = 5, Rbp = 5,
Rsi = 6, Rsi = 6,
Rdi = 7, Rdi = 7,
R8 = 8, R8 = 8,
R9 = 9, R9 = 9,
R10 = 10, R10 = 10,
R11 = 11, R11 = 11,
R12 = 12, R12 = 12,
@ -21,21 +24,21 @@ namespace ARMeilleure.CodeGen.X86
R14 = 14, R14 = 14,
R15 = 15, R15 = 15,
Xmm0 = 0, Xmm0 = 0,
Xmm1 = 1, Xmm1 = 1,
Xmm2 = 2, Xmm2 = 2,
Xmm3 = 3, Xmm3 = 3,
Xmm4 = 4, Xmm4 = 4,
Xmm5 = 5, Xmm5 = 5,
Xmm6 = 6, Xmm6 = 6,
Xmm7 = 7, Xmm7 = 7,
Xmm8 = 8, Xmm8 = 8,
Xmm9 = 9, Xmm9 = 9,
Xmm10 = 10, Xmm10 = 10,
Xmm11 = 11, Xmm11 = 11,
Xmm12 = 12, Xmm12 = 12,
Xmm13 = 13, Xmm13 = 13,
Xmm14 = 14, Xmm14 = 14,
Xmm15 = 15 Xmm15 = 15,
} }
} }

View File

@ -82,8 +82,10 @@ namespace ARMeilleure.Common
} }
else else
{ {
_page = new PageInfo(); _page = new PageInfo
_page.Pointer = (byte*)NativeAllocator.Instance.Allocate(_pageSize); {
Pointer = (byte*)NativeAllocator.Instance.Allocate(_pageSize),
};
_pages.Add(_page); _pages.Add(_page);
} }
@ -106,7 +108,7 @@ namespace ARMeilleure.Common
// Free excess pages that was allocated. // Free excess pages that was allocated.
while (_pages.Count > _pageCount) while (_pages.Count > _pageCount)
{ {
NativeAllocator.Instance.Free(_pages[_pages.Count - 1].Pointer); NativeAllocator.Instance.Free(_pages[^1].Pointer);
_pages.RemoveAt(_pages.Count - 1); _pages.RemoveAt(_pages.Count - 1);
} }
@ -125,12 +127,13 @@ namespace ARMeilleure.Common
// If arena is used frequently, keep pages for longer. Otherwise keep pages for a shorter amount of time. // If arena is used frequently, keep pages for longer. Otherwise keep pages for a shorter amount of time.
int now = Environment.TickCount; int now = Environment.TickCount;
int count = (now - _lastReset) switch { int count = (now - _lastReset) switch
{
>= 5000 => 0, >= 5000 => 0,
>= 2500 => 50, >= 2500 => 50,
>= 1000 => 100, >= 1000 => 100,
>= 10 => 1500, >= 10 => 1500,
_ => 5000 _ => 5000,
}; };
for (int i = _pages.Count - 1; i >= 0; i--) for (int i = _pages.Count - 1; i >= 0; i--)

View File

@ -138,7 +138,7 @@ namespace ARMeilleure.Common
var newSpan = new Span<long>(_masks, _count); var newSpan = new Span<long>(_masks, _count);
oldSpan.CopyTo(newSpan); oldSpan.CopyTo(newSpan);
newSpan.Slice(oldSpan.Length).Clear(); newSpan[oldSpan.Length..].Clear();
_allocator.Free(oldMask); _allocator.Free(oldMask);
} }
@ -176,8 +176,8 @@ namespace ARMeilleure.Common
private int _bit; private int _bit;
private readonly BitMap _map; private readonly BitMap _map;
public int Current => (int)_index * IntSize + _bit; public readonly int Current => (int)_index * IntSize + _bit;
object IEnumerator.Current => Current; readonly object IEnumerator.Current => Current;
public Enumerator(BitMap map) public Enumerator(BitMap map)
{ {
@ -214,9 +214,9 @@ namespace ARMeilleure.Common
return true; return true;
} }
public void Reset() { } public readonly void Reset() { }
public void Dispose() { } public readonly void Dispose() { }
} }
} }
} }

View File

@ -5,10 +5,10 @@ namespace ARMeilleure.Decoders
{ {
class Block class Block
{ {
public ulong Address { get; set; } public ulong Address { get; set; }
public ulong EndAddress { get; set; } public ulong EndAddress { get; set; }
public Block Next { get; set; } public Block Next { get; set; }
public Block Branch { get; set; } public Block Branch { get; set; }
public bool Exit { get; set; } public bool Exit { get; set; }
@ -43,14 +43,14 @@ namespace ARMeilleure.Decoders
rightBlock.EndAddress = EndAddress; rightBlock.EndAddress = EndAddress;
rightBlock.Next = Next; rightBlock.Next = Next;
rightBlock.Branch = Branch; rightBlock.Branch = Branch;
rightBlock.OpCodes.AddRange(OpCodes.GetRange(splitIndex, splitCount)); rightBlock.OpCodes.AddRange(OpCodes.GetRange(splitIndex, splitCount));
EndAddress = rightBlock.Address; EndAddress = rightBlock.Address;
Next = rightBlock; Next = rightBlock;
Branch = null; Branch = null;
OpCodes.RemoveRange(splitIndex, splitCount); OpCodes.RemoveRange(splitIndex, splitCount);
@ -58,9 +58,9 @@ namespace ARMeilleure.Decoders
private static int BinarySearch(List<OpCode> opCodes, ulong address) private static int BinarySearch(List<OpCode> opCodes, ulong address)
{ {
int left = 0; int left = 0;
int middle = 0; int middle = 0;
int right = opCodes.Count - 1; int right = opCodes.Count - 1;
while (left <= right) while (left <= right)
{ {
@ -92,10 +92,10 @@ namespace ARMeilleure.Decoders
{ {
if (OpCodes.Count > 0) if (OpCodes.Count > 0)
{ {
return OpCodes[OpCodes.Count - 1]; return OpCodes[^1];
} }
return null; return null;
} }
} }
} }

View File

@ -2,22 +2,22 @@ namespace ARMeilleure.Decoders
{ {
enum Condition enum Condition
{ {
Eq = 0, Eq = 0,
Ne = 1, Ne = 1,
GeUn = 2, GeUn = 2,
LtUn = 3, LtUn = 3,
Mi = 4, Mi = 4,
Pl = 5, Pl = 5,
Vs = 6, Vs = 6,
Vc = 7, Vc = 7,
GtUn = 8, GtUn = 8,
LeUn = 9, LeUn = 9,
Ge = 10, Ge = 10,
Lt = 11, Lt = 11,
Gt = 12, Gt = 12,
Le = 13, Le = 13,
Al = 14, Al = 14,
Nv = 15 Nv = 15,
} }
static class ConditionExtensions static class ConditionExtensions
@ -29,4 +29,4 @@ namespace ARMeilleure.Decoders
return (Condition)((int)cond ^ 1); return (Condition)((int)cond ^ 1);
} }
} }
} }

View File

@ -2,9 +2,9 @@ namespace ARMeilleure.Decoders
{ {
enum DataOp enum DataOp
{ {
Adr = 0, Adr = 0,
Arithmetic = 1, Arithmetic = 1,
Logical = 2, Logical = 2,
BitField = 3 BitField = 3,
} }
} }

View File

@ -20,11 +20,11 @@ namespace ARMeilleure.Decoders
public static Block[] Decode(IMemoryManager memory, ulong address, ExecutionMode mode, bool highCq, DecoderMode dMode) public static Block[] Decode(IMemoryManager memory, ulong address, ExecutionMode mode, bool highCq, DecoderMode dMode)
{ {
List<Block> blocks = new List<Block>(); List<Block> blocks = new();
Queue<Block> workQueue = new Queue<Block>(); Queue<Block> workQueue = new();
Dictionary<ulong, Block> visited = new Dictionary<ulong, Block>(); Dictionary<ulong, Block> visited = new();
Debug.Assert(MaxInstsPerFunctionLowCq <= MaxInstsPerFunction); Debug.Assert(MaxInstsPerFunctionLowCq <= MaxInstsPerFunction);
@ -163,7 +163,7 @@ namespace ARMeilleure.Decoders
{ {
index = 0; index = 0;
int left = 0; int left = 0;
int right = blocks.Count - 1; int right = blocks.Count - 1;
while (left <= right) while (left <= right)
@ -196,9 +196,9 @@ namespace ARMeilleure.Decoders
private static void FillBlock( private static void FillBlock(
IMemoryManager memory, IMemoryManager memory,
ExecutionMode mode, ExecutionMode mode,
Block block, Block block,
ulong limitAddress) ulong limitAddress)
{ {
ulong address = block.Address; ulong address = block.Address;
int itBlockSize = 0; int itBlockSize = 0;
@ -241,12 +241,12 @@ namespace ARMeilleure.Decoders
private static bool IsUnconditionalBranch(OpCode opCode) private static bool IsUnconditionalBranch(OpCode opCode)
{ {
return opCode is OpCodeBImmAl || return opCode is OpCodeBImmAl ||
opCode is OpCodeBReg || IsAarch32UnconditionalBranch(opCode); opCode is OpCodeBReg || IsAarch32UnconditionalBranch(opCode);
} }
private static bool IsAarch32UnconditionalBranch(OpCode opCode) private static bool IsAarch32UnconditionalBranch(OpCode opCode)
{ {
if (!(opCode is OpCode32 op)) if (opCode is not OpCode32 op)
{ {
return false; return false;
} }
@ -290,9 +290,9 @@ namespace ARMeilleure.Decoders
if (opCode is IOpCode32Mem opMem) if (opCode is IOpCode32Mem opMem)
{ {
rt = opMem.Rt; rt = opMem.Rt;
rn = opMem.Rn; rn = opMem.Rn;
wBack = opMem.WBack; wBack = opMem.WBack;
isLoad = opMem.IsLoad; isLoad = opMem.IsLoad;
// For the dual load, we also need to take into account the // For the dual load, we also need to take into account the
@ -304,12 +304,12 @@ namespace ARMeilleure.Decoders
} }
else if (opCode is IOpCode32MemMult opMemMult) else if (opCode is IOpCode32MemMult opMemMult)
{ {
const int pcMask = 1 << RegisterAlias.Aarch32Pc; const int PCMask = 1 << RegisterAlias.Aarch32Pc;
rt = (opMemMult.RegisterMask & pcMask) != 0 ? RegisterAlias.Aarch32Pc : 0; rt = (opMemMult.RegisterMask & PCMask) != 0 ? RegisterAlias.Aarch32Pc : 0;
rn = opMemMult.Rn; rn = opMemMult.Rn;
wBack = opMemMult.PostOffset != 0; wBack = opMemMult.PostOffset != 0;
isLoad = opMemMult.IsLoad; isLoad = opMemMult.IsLoad;
} }
else else
{ {
@ -388,4 +388,4 @@ namespace ARMeilleure.Decoders
} }
} }
} }
} }

View File

@ -10,7 +10,7 @@ namespace ARMeilleure.Decoders
Imm8ToFP64Table = BuildImm8ToFP64Table(); Imm8ToFP64Table = BuildImm8ToFP64Table();
} }
public static readonly uint[] Imm8ToFP32Table; public static readonly uint[] Imm8ToFP32Table;
public static readonly ulong[] Imm8ToFP64Table; public static readonly ulong[] Imm8ToFP64Table;
private static uint[] BuildImm8ToFP32Table() private static uint[] BuildImm8ToFP32Table()
@ -40,47 +40,47 @@ namespace ARMeilleure.Decoders
// abcdefgh -> aBbbbbbc defgh000 00000000 00000000 (B = ~b) // abcdefgh -> aBbbbbbc defgh000 00000000 00000000 (B = ~b)
private static uint ExpandImm8ToFP32(uint imm) private static uint ExpandImm8ToFP32(uint imm)
{ {
uint MoveBit(uint bits, int from, int to) static uint MoveBit(uint bits, int from, int to)
{ {
return ((bits >> from) & 1U) << to; return ((bits >> from) & 1U) << to;
} }
return MoveBit(imm, 7, 31) | MoveBit(~imm, 6, 30) | return MoveBit(imm, 7, 31) | MoveBit(~imm, 6, 30) |
MoveBit(imm, 6, 29) | MoveBit( imm, 6, 28) | MoveBit(imm, 6, 29) | MoveBit(imm, 6, 28) |
MoveBit(imm, 6, 27) | MoveBit( imm, 6, 26) | MoveBit(imm, 6, 27) | MoveBit(imm, 6, 26) |
MoveBit(imm, 6, 25) | MoveBit( imm, 5, 24) | MoveBit(imm, 6, 25) | MoveBit(imm, 5, 24) |
MoveBit(imm, 4, 23) | MoveBit( imm, 3, 22) | MoveBit(imm, 4, 23) | MoveBit(imm, 3, 22) |
MoveBit(imm, 2, 21) | MoveBit( imm, 1, 20) | MoveBit(imm, 2, 21) | MoveBit(imm, 1, 20) |
MoveBit(imm, 0, 19); MoveBit(imm, 0, 19);
} }
// abcdefgh -> aBbbbbbb bbcdefgh 00000000 00000000 00000000 00000000 00000000 00000000 (B = ~b) // abcdefgh -> aBbbbbbb bbcdefgh 00000000 00000000 00000000 00000000 00000000 00000000 (B = ~b)
private static ulong ExpandImm8ToFP64(ulong imm) private static ulong ExpandImm8ToFP64(ulong imm)
{ {
ulong MoveBit(ulong bits, int from, int to) static ulong MoveBit(ulong bits, int from, int to)
{ {
return ((bits >> from) & 1UL) << to; return ((bits >> from) & 1UL) << to;
} }
return MoveBit(imm, 7, 63) | MoveBit(~imm, 6, 62) | return MoveBit(imm, 7, 63) | MoveBit(~imm, 6, 62) |
MoveBit(imm, 6, 61) | MoveBit( imm, 6, 60) | MoveBit(imm, 6, 61) | MoveBit(imm, 6, 60) |
MoveBit(imm, 6, 59) | MoveBit( imm, 6, 58) | MoveBit(imm, 6, 59) | MoveBit(imm, 6, 58) |
MoveBit(imm, 6, 57) | MoveBit( imm, 6, 56) | MoveBit(imm, 6, 57) | MoveBit(imm, 6, 56) |
MoveBit(imm, 6, 55) | MoveBit( imm, 6, 54) | MoveBit(imm, 6, 55) | MoveBit(imm, 6, 54) |
MoveBit(imm, 5, 53) | MoveBit( imm, 4, 52) | MoveBit(imm, 5, 53) | MoveBit(imm, 4, 52) |
MoveBit(imm, 3, 51) | MoveBit( imm, 2, 50) | MoveBit(imm, 3, 51) | MoveBit(imm, 2, 50) |
MoveBit(imm, 1, 49) | MoveBit( imm, 0, 48); MoveBit(imm, 1, 49) | MoveBit(imm, 0, 48);
} }
public struct BitMask public struct BitMask
{ {
public long WMask; public long WMask;
public long TMask; public long TMask;
public int Pos; public int Pos;
public int Shift; public int Shift;
public bool IsUndefined; public bool IsUndefined;
public static BitMask Invalid => new BitMask { IsUndefined = true }; public static BitMask Invalid => new() { IsUndefined = true };
} }
public static BitMask DecodeBitMask(int opCode, bool immediate) public static BitMask DecodeBitMask(int opCode, bool immediate)
@ -88,7 +88,7 @@ namespace ARMeilleure.Decoders
int immS = (opCode >> 10) & 0x3f; int immS = (opCode >> 10) & 0x3f;
int immR = (opCode >> 16) & 0x3f; int immR = (opCode >> 16) & 0x3f;
int n = (opCode >> 22) & 1; int n = (opCode >> 22) & 1;
int sf = (opCode >> 31) & 1; int sf = (opCode >> 31) & 1;
int length = BitUtils.HighestBitSet((~immS & 0x3f) | (n << 6)); int length = BitUtils.HighestBitSet((~immS & 0x3f) | (n << 6));
@ -115,7 +115,7 @@ namespace ARMeilleure.Decoders
if (r > 0) if (r > 0)
{ {
wMask = BitUtils.RotateRight(wMask, r, size); wMask = BitUtils.RotateRight(wMask, r, size);
wMask &= BitUtils.FillWithOnes(size); wMask &= BitUtils.FillWithOnes(size);
} }
@ -124,8 +124,8 @@ namespace ARMeilleure.Decoders
WMask = BitUtils.Replicate(wMask, size), WMask = BitUtils.Replicate(wMask, size),
TMask = BitUtils.Replicate(tMask, size), TMask = BitUtils.Replicate(tMask, size),
Pos = immS, Pos = immS,
Shift = immR Shift = immR,
}; };
} }
@ -164,4 +164,4 @@ namespace ARMeilleure.Decoders
return false; return false;
} }
} }
} }

View File

@ -6,4 +6,4 @@
SingleBlock, SingleBlock,
SingleInstruction, SingleInstruction,
} }
} }

View File

@ -14,4 +14,4 @@ namespace ARMeilleure.Decoders
OperandType GetOperandType(); OperandType GetOperandType();
} }
} }

View File

@ -6,4 +6,4 @@ namespace ARMeilleure.Decoders
uint GetPc(); uint GetPc();
} }
} }

View File

@ -5,4 +5,4 @@ namespace ARMeilleure.Decoders
int Rd { get; } int Rd { get; }
int Rn { get; } int Rn { get; }
} }
} }

View File

@ -6,4 +6,4 @@
bool IsRotated { get; } bool IsRotated { get; }
} }
} }

View File

@ -4,4 +4,4 @@ namespace ARMeilleure.Decoders
{ {
int Immediate { get; } int Immediate { get; }
} }
} }

View File

@ -7,4 +7,4 @@
ShiftType ShiftType { get; } ShiftType ShiftType { get; }
} }
} }

View File

@ -7,4 +7,4 @@
ShiftType ShiftType { get; } ShiftType ShiftType { get; }
} }
} }

View File

@ -1,4 +1,4 @@
namespace ARMeilleure.Decoders namespace ARMeilleure.Decoders
{ {
interface IOpCode32BImm : IOpCode32, IOpCodeBImm { } interface IOpCode32BImm : IOpCode32, IOpCodeBImm { }
} }

View File

@ -4,4 +4,4 @@ namespace ARMeilleure.Decoders
{ {
int Rm { get; } int Rm { get; }
} }
} }

View File

@ -4,4 +4,4 @@
{ {
int Id { get; } int Id { get; }
} }
} }

View File

@ -4,4 +4,4 @@
{ {
bool? SetFlags { get; } bool? SetFlags { get; }
} }
} }

View File

@ -13,4 +13,4 @@ namespace ARMeilleure.Decoders
int Immediate { get; } int Immediate { get; }
} }
} }

View File

@ -12,4 +12,4 @@ namespace ARMeilleure.Decoders
int Offset { get; } int Offset { get; }
} }
} }

View File

@ -4,4 +4,4 @@
{ {
int Rm { get; } int Rm { get; }
} }
} }

View File

@ -5,4 +5,4 @@ namespace ARMeilleure.Decoders
int Rm { get; } int Rm { get; }
ShiftType ShiftType { get; } ShiftType ShiftType { get; }
} }
} }

View File

@ -7,4 +7,4 @@ namespace ARMeilleure.Decoders
DataOp DataOp { get; } DataOp DataOp { get; }
} }
} }

View File

@ -4,4 +4,4 @@ namespace ARMeilleure.Decoders
{ {
long Immediate { get; } long Immediate { get; }
} }
} }

View File

@ -3,8 +3,8 @@ namespace ARMeilleure.Decoders
interface IOpCodeAluRs : IOpCodeAlu interface IOpCodeAluRs : IOpCodeAlu
{ {
int Shift { get; } int Shift { get; }
int Rm { get; } int Rm { get; }
ShiftType ShiftType { get; } ShiftType ShiftType { get; }
} }
} }

View File

@ -3,8 +3,8 @@ namespace ARMeilleure.Decoders
interface IOpCodeAluRx : IOpCodeAlu interface IOpCodeAluRx : IOpCodeAlu
{ {
int Shift { get; } int Shift { get; }
int Rm { get; } int Rm { get; }
IntType IntType { get; } IntType IntType { get; }
} }
} }

View File

@ -4,4 +4,4 @@ namespace ARMeilleure.Decoders
{ {
long Immediate { get; } long Immediate { get; }
} }
} }

View File

@ -4,4 +4,4 @@ namespace ARMeilleure.Decoders
{ {
Condition Cond { get; } Condition Cond { get; }
} }
} }

View File

@ -2,10 +2,10 @@ namespace ARMeilleure.Decoders
{ {
interface IOpCodeLit : IOpCode interface IOpCodeLit : IOpCode
{ {
int Rt { get; } int Rt { get; }
long Immediate { get; } long Immediate { get; }
int Size { get; } int Size { get; }
bool Signed { get; } bool Signed { get; }
bool Prefetch { get; } bool Prefetch { get; }
} }
} }

View File

@ -4,4 +4,4 @@ namespace ARMeilleure.Decoders
{ {
int Size { get; } int Size { get; }
} }
} }

View File

@ -4,15 +4,15 @@ namespace ARMeilleure.Decoders
{ {
readonly struct InstDescriptor readonly struct InstDescriptor
{ {
public static InstDescriptor Undefined => new InstDescriptor(InstName.Und, InstEmit.Und); public static InstDescriptor Undefined => new(InstName.Und, InstEmit.Und);
public InstName Name { get; } public InstName Name { get; }
public InstEmitter Emitter { get; } public InstEmitter Emitter { get; }
public InstDescriptor(InstName name, InstEmitter emitter) public InstDescriptor(InstName name, InstEmitter emitter)
{ {
Name = name; Name = name;
Emitter = emitter; Emitter = emitter;
} }
} }
} }

View File

@ -3,4 +3,4 @@ using ARMeilleure.Translation;
namespace ARMeilleure.Decoders namespace ARMeilleure.Decoders
{ {
delegate void InstEmitter(ArmEmitterContext context); delegate void InstEmitter(ArmEmitterContext context);
} }

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