From d059ffb15dad8eeb53989ae3b2037b6705289151 Mon Sep 17 00:00:00 2001
From: jduncanator <1518948+jduncanator@users.noreply.github.com>
Date: Thu, 31 Oct 2019 15:50:12 +1100
Subject: [PATCH 1/3] Increase IPC buffer size (#803)
This is a hack, but it works for now. We should really determine a way to automatically calculate the required buffer size to avoid situations where specific IPC calls "overflow" the maximum size.
---
Ryujinx.HLE/HOS/Ipc/IpcHandler.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Ryujinx.HLE/HOS/Ipc/IpcHandler.cs b/Ryujinx.HLE/HOS/Ipc/IpcHandler.cs
index beb7878fdd..dd36871a24 100644
--- a/Ryujinx.HLE/HOS/Ipc/IpcHandler.cs
+++ b/Ryujinx.HLE/HOS/Ipc/IpcHandler.cs
@@ -67,7 +67,7 @@ namespace Ryujinx.HLE.HOS.Ipc
case 3:
{
- request = FillResponse(response, 0, 0x500);
+ request = FillResponse(response, 0, 0x1000);
break;
}
From 35443bac5a16ced668d84e0a22c21ca9076b3924 Mon Sep 17 00:00:00 2001
From: GalladeGuy
Date: Thu, 31 Oct 2019 13:21:56 -0400
Subject: [PATCH 2/3] Update README.md (#802)
* Update README.md
Improve grammar, replace Switch hacking guide with one that's more up-to-date, and add a guide for shared font dumping
* Update README.md
* Remove shared fonts section
---
README.md | 63 ++++++++++++++++++++++++++-----------------------------
1 file changed, 30 insertions(+), 33 deletions(-)
diff --git a/README.md b/README.md
index be3d1fea18..13f91eb6c1 100644
--- a/README.md
+++ b/README.md
@@ -16,92 +16,89 @@
- A lot of games boot, but only a handful are playable, see the compatiblity list here.
+ A lot of games boot, but only some are playable. See the compatiblity list here.
## Usage
To run this emulator, you need the [.NET Core 2.1 (or higher) SDK](https://dotnet.microsoft.com/download/dotnet-core).
-If you use a pre-built version, you can use the graphical interface to run your games/homebrew apps.
+If you use a pre-built version, you can use the graphical interface to run your games and homebrew.
If you build it yourself you will need to:
Run `dotnet run -c Release -- path\to\homebrew.nro` inside the Ryujinx project folder to run homebrew apps.
Run `dotnet run -c Release -- path\to\game.nsp/xci` to run official games.
-Every file related to Ryujinx is stored in the `RyuFs` folder. Located in `C:\Users\USERNAME\AppData\Roaming\` for Windows, `/home/USERNAME/.config` for Linux or `/Users/USERNAME/Library/Application Support/` for macOS.
+Every file related to Ryujinx is stored in the `RyuFs` folder. Located in `C:\Users\USERNAME\AppData\Roaming\` for Windows, `/home/USERNAME/.config` for Linux or `/Users/USERNAME/Library/Application Support/` for macOS. It can also be accessed by clicking `Open Ryujinx Folder` under the File menu in the GUI.
## Latest build
-These builds are compiled automatically for each commit on the master branch.
-**They may be unstable or might not work at all.**
+These builds are compiled automatically for each commit on the master branch, **and may be unstable or completely broken.**
+
The latest automatic build for Windows, macOS, and Linux can be found on the [Official Website](https://ryujinx.org/#/Build).
## Requirements
- **Switch Keys**
- Everything on the Switch is encrypted, so if you want to run anything else, other than homebrews, you have to dump them from your console. To get more information please take a look at our [Keys Documentation](KEYS.md) *(Outdated)*
-
- - **Shared Fonts**
-
- Some games draw text using fonts files, those are what is called Shared Fonts.
- All you have to do is [Download](https://ryujinx.org/ryujinx_shared_fonts.zip) them and extract those files in `RyuFs\system\fonts`.
+ Everything on the Switch is encrypted, so if you want to run anything other than homebrew, you have to dump encryption keys from your console. To get more information please take a look at our [Keys Documentation](KEYS.md) *(Outdated)*
- **FFmpeg Dependencies**
- Ryujinx has a basic implementation of `NVDEC` (video decoder used by the Switch's GPU).
- Many games use videos that use NVDEC, so you need to download [Zeranoe FFmpeg Builds](http://ffmpeg.zeranoe.com/builds/) for your system, and in **Shared** linking.
- When it's done, extract the `bin` folder directly into your Ryujinx folder.
+ Ryujinx has a basic implementation of `NVDEC`, a video decoder used by the Switch's GPU. Many games include videos that use it, so you need to download [Zeranoe's FFmpeg Builds](http://ffmpeg.zeranoe.com/builds/) for **Shared** linking and your computer's operating system. When it's done, extract the contents of the `bin` folder directly into your Ryujinx folder.
- **System Titles**
- Some of our System Modules implementation (like time) require [System Data Archives](https://switchbrew.org/wiki/Title_list#System_Data_Archives).
- You can install them by mounting your nand partition using [HacDiskMount](https://switchtools.sshnuke.net/) and copy the content in `RyuFs/nand/system`.
+ Some of our System Module implementations, like `time`, require [System Data Archives](https://switchbrew.org/wiki/Title_list#System_Data_Archives). You can install them by mounting your nand partition using [HacDiskMount](https://switchtools.sshnuke.net/) and copying the content to `RyuFs/nand/system`.
- **Executables**
- Ryujinx is able to run games or homebrews.
- You need a hacked Switch to dump them ([Hack Guide](https://switch.hacks.guide/)).
- You need to dump your own games with [NxDumpTool](https://github.com/DarkMatterCore/nxdumptool) for XCI dump or [SwitchSDTool](https://github.com/CaitSith2/SwitchSDTool) for NSP dump.
- You can find homebrew on different related websites or on the [Switch Appstore](https://www.switchbru.com/appstore/).
+ Ryujinx is able to run both official games and homebrew.
+
+ Homebrew is available on many websites, such as the [Switch Appstore](https://www.switchbru.com/appstore/).
+
+ A hacked Switch is needed to dump games, which you can learn how to do [here](https://nh-server.github.io/switch-guide/). Once you've hacked your Switch, you need to dump your own games with [NxDumpTool](https://github.com/DarkMatterCore/nxdumptool) to get an XCI dump or [SwitchSDTool](https://github.com/CaitSith2/SwitchSDTool) to get an NSP dump.
## Features
- **Audio**
- Everything for audio is partially supported. We currently use a C# wrapper for [libsoundio](http://libsound.io/) and we support [OpenAL](https://openal.org/downloads/OpenAL11CoreSDK.zip) (installation needed) too as a fallback. Our current Opus implementation is pretty incomplete.
+ Everything for audio is partially supported. We currently use a C# wrapper for [libsoundio](http://libsound.io/), and we support [OpenAL](https://openal.org/downloads/OpenAL11CoreSDK.zip) (installation needed) too as a fallback. Our current Opus implementation is pretty incomplete.
- **CPU**
- The CPU emulator emulates an ARMv8 CPU, and only the new 64-bits ARMv8 instructions are implemented (with a few instructions still missing). It translates the ARM code to a custom IR and then it performs a few optimizations and turns that into x86 code.
- To handle that we use our own JIT called ARMeilleure, which has the custom IR and compiles the code to x86.
- ChocolArm is the old ARM emulator, is being replaced by ARMeilleure (It can still be enabled inside the configuration menu/file) and it works by translating the ARM code to .NET IL. The runtime JIT then compiles that to the platform CPU code. On .NET Core, the JIT is called RyuJIT (hence the project name, Ryujinx).
+ The CPU emulator, ARMeilleure, emulates an ARMv8 CPU, and currently only has support for the new 64-bit ARMv8 instructions (with a few instructions still missing). It translates the ARM code to a custom IR, performs a few optimizations, and turns that into x86 code. To handle that, we use our own JIT called ARMeilleure, which uses the custom IR and compiles the code to x86.
+
+ ChocolArm is the old ARM emulator which worked by translating the ARM code to .NET IL. The runtime JIT then compiles that to the platform CPU code. On .NET Core, the JIT is called RyuJIT, hence the project name, Ryujinx. It is being replaced by ARMeilleure, but can still be enabled inside the configuration menu.
- **GPU**
- The GPU emulator emulates the Switch Maxwell GPU, using the OpenGL API (4.2 minimum) through a custom build of OpenTK.
+ The GPU emulator emulates the Switch's Maxwell GPU using the OpenGL API (version 4.2 minimum) through a custom build of OpenTK.
- **Input**
- We currently have Keyboard, Mouse, Touch, and JoyCon input support (emulated through the keyboard) and some controllers too. You can set-up everything inside the configuration menu/file.
+ We currently have support for keyboard, mouse, touch input, JoyCon input support emulated through the keyboard, and some controllers too. You can set up everything inside the configuration menu.
- **Configuration**
- The emulator has some options, like Dump shaders, Enabled/Disabled some Logging, Remap Controllers, Choose Controller, and more. You can set-up all of them through the graphical interface or manually through the Config File: `Config.json`.
-For more information [you can go here](CONFIG.md) *(Outdated)*.
+ The emulator has settings for dumping shaders, enabling or disabling some logging, remapping controllers, and more. You can configure all of them through the graphical interface or manually through the config file, `Config.json`.
+
+ For more information [you can go here](CONFIG.md) *(Outdated)*.
## Compatibility
-You can check out the compatibility list [here](https://github.com/Ryujinx/Ryujinx-Games-List/issues).
+You can check out the compatibility list [here](https://github.com/Ryujinx/Ryujinx-Games-List/issues).
+
Don't hesitate to open a new issue if a game isn't already on there.
## Help
-If you have homebrew that currently doesn't work within the emulator, you can contact us through our Discord with the compiled *.NRO / *.NSO (and source code if possible) and we'll take note of whatever is causing the app / game to not work, on the watch list and fix it at a later date.
-If you need help for setting up Ryujinx, you can go to our Discord server too.
+If you have homebrew that currently doesn't work within the emulator, you can contact us through our Discord with the .NRO/.NSO and source code, if possible. We'll take note of whatever is causing the app/game to not work, on the watch list and fix it at a later date.
+
+If you need help with setting up Ryujinx, you can ask questions in the support channel of our Discord server.
## Contact
-For contributions, help, support, and suggestions or if you just want to get in touch with the team; join our [Discord server](https://discord.gg/N2FmfVc)!
-For donation support, please take a look at our [Patreon](https://www.patreon.com/ryujinx).
\ No newline at end of file
+If you have contributions, need support, have suggestions, or just want to get in touch with the team, join our [Discord server](https://discord.gg/N2FmfVc)!
+
+If you'd like to donate, please take a look at our [Patreon](https://www.patreon.com/ryujinx).
From eee639d6ba544fa5dd9352426d55e91bc54e157d Mon Sep 17 00:00:00 2001
From: LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com>
Date: Thu, 31 Oct 2019 19:09:03 +0100
Subject: [PATCH 3/3] .NET Core 3.0 is here! (#784)
* .NET Core 3.0 is here!
* Remove IMemoryManager.cs and its references.
* Add T Math/F.FusedMultiplyAdd(T, T, T). Nits.
* Nit.
* Update appveyor.yml
* Revert "Resolve Visual Studio build issues"
This reverts commit 1772128ce0fc058e6280001aace3a77a7a96897b.
* Update SvcTable.cs
---
ARMeilleure/ARMeilleure.csproj | 3 +-
.../Instructions/InstEmitSimdArithmetic.cs | 10 +-
ARMeilleure/Instructions/SoftFloat.cs | 30 +-
ARMeilleure/Memory/IMemoryManager.cs | 40 -
ARMeilleure/Memory/MemoryHelper.cs | 8 +-
ARMeilleure/Memory/MemoryManager.cs | 2 +-
ARMeilleure/State/ExecutionContext.cs | 2 +-
ARMeilleure/State/IExecutionContext.cs | 37 -
ARMeilleure/Translation/ITranslator.cs | 9 -
ARMeilleure/Translation/Translator.cs | 6 +-
ChocolArm64/ChocolArm64.csproj | 39 -
ChocolArm64/Decoders/BitUtils.cs | 59 -
ChocolArm64/Decoders/Block.cs | 99 -
ChocolArm64/Decoders/Condition.cs | 32 -
ChocolArm64/Decoders/DataOp.cs | 10 -
ChocolArm64/Decoders/Decoder.cs | 379 --
ChocolArm64/Decoders/DecoderHelper.cs | 112 -
ChocolArm64/Decoders/IOpCode32.cs | 9 -
ChocolArm64/Decoders/IOpCode32Alu.cs | 10 -
ChocolArm64/Decoders/IOpCode32BImm.cs | 4 -
ChocolArm64/Decoders/IOpCode32BReg.cs | 7 -
ChocolArm64/Decoders/IOpCode32Mem.cs | 12 -
ChocolArm64/Decoders/IOpCode32MemMult.cs | 13 -
ChocolArm64/Decoders/IOpCode64.cs | 13 -
ChocolArm64/Decoders/IOpCodeAlu64.cs | 10 -
ChocolArm64/Decoders/IOpCodeAluImm64.cs | 7 -
ChocolArm64/Decoders/IOpCodeAluRs64.cs | 10 -
ChocolArm64/Decoders/IOpCodeAluRx64.cs | 10 -
ChocolArm64/Decoders/IOpCodeBImm.cs | 7 -
ChocolArm64/Decoders/IOpCodeCond64.cs | 7 -
ChocolArm64/Decoders/IOpCodeLit64.cs | 11 -
ChocolArm64/Decoders/IOpCodeSimd64.cs | 7 -
ChocolArm64/Decoders/IntType.cs | 14 -
ChocolArm64/Decoders/OpCode32.cs | 24 -
ChocolArm64/Decoders/OpCode32Alu.cs | 20 -
ChocolArm64/Decoders/OpCode32AluImm.cs | 21 -
ChocolArm64/Decoders/OpCode32AluRsImm.cs | 20 -
ChocolArm64/Decoders/OpCode32BImm.cs | 29 -
ChocolArm64/Decoders/OpCode32BReg.cs | 14 -
ChocolArm64/Decoders/OpCode32Mem.cs | 37 -
ChocolArm64/Decoders/OpCode32MemImm.cs | 12 -
ChocolArm64/Decoders/OpCode32MemImm8.cs | 15 -
ChocolArm64/Decoders/OpCode32MemMult.cs | 57 -
ChocolArm64/Decoders/OpCode64.cs | 40 -
ChocolArm64/Decoders/OpCodeAdr64.cs | 18 -
ChocolArm64/Decoders/OpCodeAlu64.cs | 23 -
ChocolArm64/Decoders/OpCodeAluImm64.cs | 39 -
ChocolArm64/Decoders/OpCodeAluRs64.cs | 29 -
ChocolArm64/Decoders/OpCodeAluRx64.cs | 19 -
ChocolArm64/Decoders/OpCodeBImm64.cs | 11 -
ChocolArm64/Decoders/OpCodeBImmAl64.cs | 12 -
ChocolArm64/Decoders/OpCodeBImmCmp64.cs | 20 -
ChocolArm64/Decoders/OpCodeBImmCond64.cs | 25 -
ChocolArm64/Decoders/OpCodeBImmTest64.cs | 20 -
ChocolArm64/Decoders/OpCodeBReg64.cs | 24 -
ChocolArm64/Decoders/OpCodeBfm64.cs | 29 -
ChocolArm64/Decoders/OpCodeCcmp64.cs | 31 -
ChocolArm64/Decoders/OpCodeCcmpImm64.cs | 11 -
ChocolArm64/Decoders/OpCodeCcmpReg64.cs | 15 -
ChocolArm64/Decoders/OpCodeCsel64.cs | 17 -
ChocolArm64/Decoders/OpCodeException64.cs | 14 -
ChocolArm64/Decoders/OpCodeMem64.cs | 19 -
ChocolArm64/Decoders/OpCodeMemEx64.cs | 16 -
ChocolArm64/Decoders/OpCodeMemImm64.cs | 53 -
ChocolArm64/Decoders/OpCodeMemLit64.cs | 28 -
ChocolArm64/Decoders/OpCodeMemPair64.cs | 25 -
ChocolArm64/Decoders/OpCodeMemReg64.cs | 20 -
ChocolArm64/Decoders/OpCodeMov64.cs | 35 -
ChocolArm64/Decoders/OpCodeMul64.cs | 16 -
ChocolArm64/Decoders/OpCodeSimd64.cs | 25 -
ChocolArm64/Decoders/OpCodeSimdCvt64.cs | 21 -
ChocolArm64/Decoders/OpCodeSimdExt64.cs | 14 -
ChocolArm64/Decoders/OpCodeSimdFcond64.cs | 17 -
ChocolArm64/Decoders/OpCodeSimdFmov64.cs | 33 -
ChocolArm64/Decoders/OpCodeSimdImm64.cs | 100 -
ChocolArm64/Decoders/OpCodeSimdIns64.cs | 36 -
ChocolArm64/Decoders/OpCodeSimdMemImm64.cs | 19 -
ChocolArm64/Decoders/OpCodeSimdMemLit64.cs | 31 -
ChocolArm64/Decoders/OpCodeSimdMemMs64.cs | 48 -
ChocolArm64/Decoders/OpCodeSimdMemPair64.cs | 16 -
ChocolArm64/Decoders/OpCodeSimdMemReg64.cs | 14 -
ChocolArm64/Decoders/OpCodeSimdMemSs64.cs | 97 -
ChocolArm64/Decoders/OpCodeSimdReg64.cs | 18 -
ChocolArm64/Decoders/OpCodeSimdRegElem64.cs | 31 -
ChocolArm64/Decoders/OpCodeSimdRegElemF64.cs | 33 -
ChocolArm64/Decoders/OpCodeSimdShImm64.cs | 16 -
ChocolArm64/Decoders/OpCodeSimdTbl64.cs | 12 -
ChocolArm64/Decoders/OpCodeSystem64.cs | 24 -
ChocolArm64/Decoders/OpCodeT16.cs | 14 -
ChocolArm64/Decoders/OpCodeT16AluImm8.cs | 22 -
ChocolArm64/Decoders/OpCodeT16BReg.cs | 14 -
ChocolArm64/Decoders/ShiftType.cs | 10 -
ChocolArm64/Events/CpuTraceEventArgs.cs | 14 -
ChocolArm64/Events/InstExceptionEventArgs.cs | 16 -
ChocolArm64/Events/InstUndefinedEventArgs.cs | 16 -
ChocolArm64/Instructions/CryptoHelper.cs | 331 --
ChocolArm64/Instructions/Inst.cs | 18 -
ChocolArm64/Instructions/InstEmit32Helper.cs | 146 -
ChocolArm64/Instructions/InstEmitAlu.cs | 422 --
ChocolArm64/Instructions/InstEmitAlu32.cs | 142 -
ChocolArm64/Instructions/InstEmitAluHelper.cs | 462 --
ChocolArm64/Instructions/InstEmitBfm.cs | 243 --
ChocolArm64/Instructions/InstEmitCcmp.cs | 82 -
ChocolArm64/Instructions/InstEmitCsel.cs | 59 -
ChocolArm64/Instructions/InstEmitException.cs | 87 -
ChocolArm64/Instructions/InstEmitFlow.cs | 181 -
ChocolArm64/Instructions/InstEmitFlow32.cs | 81 -
.../Instructions/InstEmitFlowHelper.cs | 144 -
ChocolArm64/Instructions/InstEmitHash.cs | 115 -
ChocolArm64/Instructions/InstEmitMemory.cs | 241 --
ChocolArm64/Instructions/InstEmitMemory32.cs | 320 --
ChocolArm64/Instructions/InstEmitMemoryEx.cs | 350 --
.../Instructions/InstEmitMemoryHelper.cs | 475 ---
ChocolArm64/Instructions/InstEmitMove.cs | 41 -
ChocolArm64/Instructions/InstEmitMul.cs | 80 -
.../Instructions/InstEmitSimdArithmetic.cs | 3797 -----------------
ChocolArm64/Instructions/InstEmitSimdCmp.cs | 862 ----
.../Instructions/InstEmitSimdCrypto.cs | 54 -
ChocolArm64/Instructions/InstEmitSimdCvt.cs | 1382 ------
ChocolArm64/Instructions/InstEmitSimdHash.cs | 140 -
.../Instructions/InstEmitSimdHelper.cs | 1580 -------
.../Instructions/InstEmitSimdLogical.cs | 437 --
.../Instructions/InstEmitSimdMemory.cs | 182 -
ChocolArm64/Instructions/InstEmitSimdMove.cs | 793 ----
ChocolArm64/Instructions/InstEmitSimdShift.cs | 1175 -----
ChocolArm64/Instructions/InstEmitSystem.cs | 137 -
ChocolArm64/Instructions/InstEmitter.cs | 6 -
ChocolArm64/Instructions/SoftFallback.cs | 1194 ------
ChocolArm64/Instructions/SoftFloat.cs | 2790 ------------
ChocolArm64/Instructions/VectorHelper.cs | 646 ---
.../IntermediateRepresentation/BasicBlock.cs | 122 -
.../IntermediateRepresentation/ILLabel.cs | 4 -
.../IntermediateRepresentation/Operation.cs | 112 -
.../OperationType.cs | 18 -
.../RegisterMask.cs | 56 -
ChocolArm64/Memory/CompareExchange128.cs | 151 -
ChocolArm64/Memory/IMemory.cs | 37 -
ChocolArm64/Memory/MemoryHelper.cs | 71 -
ChocolArm64/Memory/MemoryManagement.cs | 114 -
ChocolArm64/Memory/MemoryManagementUnix.cs | 70 -
ChocolArm64/Memory/MemoryManagementWindows.cs | 155 -
ChocolArm64/Memory/MemoryManager.cs | 1017 -----
ChocolArm64/Memory/MemoryProtection.cs | 16 -
.../Memory/MemoryProtectionException.cs | 10 -
ChocolArm64/OpCodeTable.cs | 792 ----
ChocolArm64/Optimizations.cs | 27 -
ChocolArm64/State/Aarch32Mode.cs | 15 -
ChocolArm64/State/CpuThreadState.cs | 354 --
ChocolArm64/State/ExecutionMode.cs | 9 -
ChocolArm64/State/FpExc.cs | 12 -
ChocolArm64/State/FpType.cs | 11 -
ChocolArm64/State/Fpcr.cs | 11 -
ChocolArm64/State/Fpsr.cs | 8 -
ChocolArm64/State/PState.cs | 24 -
ChocolArm64/State/Register.cs | 148 -
ChocolArm64/State/RegisterAlias.cs | 41 -
ChocolArm64/State/RegisterConsts.cs | 8 -
ChocolArm64/State/RegisterSize.cs | 10 -
ChocolArm64/State/RegisterType.cs | 9 -
ChocolArm64/State/RoundMode.cs | 10 -
ChocolArm64/Translation/CallType.cs | 9 -
ChocolArm64/Translation/ILEmitterCtx.cs | 709 ---
ChocolArm64/Translation/ILGeneratorEx.cs | 121 -
ChocolArm64/Translation/RegisterUsage.cs | 176 -
ChocolArm64/Translation/TranslatedSub.cs | 93 -
.../Translation/TranslatedSubBuilder.cs | 274 --
ChocolArm64/Translation/TranslationTier.cs | 11 -
ChocolArm64/Translation/Translator.cs | 252 --
ChocolArm64/Translation/TranslatorCache.cs | 196 -
ChocolArm64/Translation/TranslatorQueue.cs | 77 -
.../Translation/TranslatorQueueItem.cs | 27 -
README.md | 60 +-
Ryujinx.Audio/Ryujinx.Audio.csproj | 4 +-
Ryujinx.Common/Ryujinx.Common.csproj | 2 +-
.../Graphics3d/Texture/ImageUtils.cs | 4 +-
.../Graphics3d/Texture/TextureHelper.cs | 4 +-
Ryujinx.Graphics/Memory/NvGpuVmm.cs | 4 +-
Ryujinx.Graphics/Memory/NvGpuVmmCache.cs | 4 +-
Ryujinx.Graphics/Ryujinx.Graphics.csproj | 4 +-
Ryujinx.HLE/HOS/Homebrew.cs | 16 +-
Ryujinx.HLE/HOS/Horizon.cs | 2 -
Ryujinx.HLE/HOS/Ipc/IpcHandler.cs | 2 +-
.../HOS/Kernel/Memory/KMemoryManager.cs | 4 +-
.../HOS/Kernel/Process/HleProcessDebugger.cs | 7 +-
Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs | 19 +-
.../HOS/Kernel/SupervisorCall/SvcHandler.cs | 4 +-
.../HOS/Kernel/SupervisorCall/SvcTable.cs | 24 +-
.../HOS/Kernel/SupervisorCall/SvcThread.cs | 4 +-
Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs | 12 +-
Ryujinx.HLE/HOS/ServiceCtx.cs | 4 +-
.../AudioRendererManager/IAudioRenderer.cs | 4 +-
.../AudioRendererManager/VoiceContext.cs | 4 +-
Ryujinx.HLE/Ryujinx.HLE.csproj | 12 +-
Ryujinx.HLE/Utilities/StructReader.cs | 4 +-
Ryujinx.HLE/Utilities/StructWriter.cs | 4 +-
Ryujinx.LLE/Luea.csproj | 2 +-
Ryujinx.Profiler/Ryujinx.Profiler.csproj | 2 +-
.../Ryujinx.ShaderTools.csproj | 2 +-
.../Ryujinx.Tests.Unicorn.csproj | 4 +-
Ryujinx.Tests/Ryujinx.Tests.csproj | 3 +-
Ryujinx.sln | 10 -
Ryujinx/Config.json | 1 -
Ryujinx/Configuration.cs | 13 +-
Ryujinx/Ryujinx.csproj | 9 +-
Ryujinx/Ui/SwitchSettings.cs | 3 -
Ryujinx/Ui/SwitchSettings.glade | 20 +-
Ryujinx/_schema.json | 12 -
appveyor.yml | 12 +-
208 files changed, 138 insertions(+), 27346 deletions(-)
delete mode 100644 ARMeilleure/Memory/IMemoryManager.cs
delete mode 100644 ARMeilleure/State/IExecutionContext.cs
delete mode 100644 ARMeilleure/Translation/ITranslator.cs
delete mode 100644 ChocolArm64/ChocolArm64.csproj
delete mode 100644 ChocolArm64/Decoders/BitUtils.cs
delete mode 100644 ChocolArm64/Decoders/Block.cs
delete mode 100644 ChocolArm64/Decoders/Condition.cs
delete mode 100644 ChocolArm64/Decoders/DataOp.cs
delete mode 100644 ChocolArm64/Decoders/Decoder.cs
delete mode 100644 ChocolArm64/Decoders/DecoderHelper.cs
delete mode 100644 ChocolArm64/Decoders/IOpCode32.cs
delete mode 100644 ChocolArm64/Decoders/IOpCode32Alu.cs
delete mode 100644 ChocolArm64/Decoders/IOpCode32BImm.cs
delete mode 100644 ChocolArm64/Decoders/IOpCode32BReg.cs
delete mode 100644 ChocolArm64/Decoders/IOpCode32Mem.cs
delete mode 100644 ChocolArm64/Decoders/IOpCode32MemMult.cs
delete mode 100644 ChocolArm64/Decoders/IOpCode64.cs
delete mode 100644 ChocolArm64/Decoders/IOpCodeAlu64.cs
delete mode 100644 ChocolArm64/Decoders/IOpCodeAluImm64.cs
delete mode 100644 ChocolArm64/Decoders/IOpCodeAluRs64.cs
delete mode 100644 ChocolArm64/Decoders/IOpCodeAluRx64.cs
delete mode 100644 ChocolArm64/Decoders/IOpCodeBImm.cs
delete mode 100644 ChocolArm64/Decoders/IOpCodeCond64.cs
delete mode 100644 ChocolArm64/Decoders/IOpCodeLit64.cs
delete mode 100644 ChocolArm64/Decoders/IOpCodeSimd64.cs
delete mode 100644 ChocolArm64/Decoders/IntType.cs
delete mode 100644 ChocolArm64/Decoders/OpCode32.cs
delete mode 100644 ChocolArm64/Decoders/OpCode32Alu.cs
delete mode 100644 ChocolArm64/Decoders/OpCode32AluImm.cs
delete mode 100644 ChocolArm64/Decoders/OpCode32AluRsImm.cs
delete mode 100644 ChocolArm64/Decoders/OpCode32BImm.cs
delete mode 100644 ChocolArm64/Decoders/OpCode32BReg.cs
delete mode 100644 ChocolArm64/Decoders/OpCode32Mem.cs
delete mode 100644 ChocolArm64/Decoders/OpCode32MemImm.cs
delete mode 100644 ChocolArm64/Decoders/OpCode32MemImm8.cs
delete mode 100644 ChocolArm64/Decoders/OpCode32MemMult.cs
delete mode 100644 ChocolArm64/Decoders/OpCode64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeAdr64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeAlu64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeAluImm64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeAluRs64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeAluRx64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeBImm64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeBImmAl64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeBImmCmp64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeBImmCond64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeBImmTest64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeBReg64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeBfm64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeCcmp64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeCcmpImm64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeCcmpReg64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeCsel64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeException64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeMem64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeMemEx64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeMemImm64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeMemLit64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeMemPair64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeMemReg64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeMov64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeMul64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeSimd64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeSimdCvt64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeSimdExt64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeSimdFcond64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeSimdFmov64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeSimdImm64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeSimdIns64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeSimdMemImm64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeSimdMemLit64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeSimdMemMs64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeSimdMemPair64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeSimdMemReg64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeSimdMemSs64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeSimdReg64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeSimdRegElem64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeSimdRegElemF64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeSimdShImm64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeSimdTbl64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeSystem64.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeT16.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeT16AluImm8.cs
delete mode 100644 ChocolArm64/Decoders/OpCodeT16BReg.cs
delete mode 100644 ChocolArm64/Decoders/ShiftType.cs
delete mode 100644 ChocolArm64/Events/CpuTraceEventArgs.cs
delete mode 100644 ChocolArm64/Events/InstExceptionEventArgs.cs
delete mode 100644 ChocolArm64/Events/InstUndefinedEventArgs.cs
delete mode 100644 ChocolArm64/Instructions/CryptoHelper.cs
delete mode 100644 ChocolArm64/Instructions/Inst.cs
delete mode 100644 ChocolArm64/Instructions/InstEmit32Helper.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitAlu.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitAlu32.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitAluHelper.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitBfm.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitCcmp.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitCsel.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitException.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitFlow.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitFlow32.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitFlowHelper.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitHash.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitMemory.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitMemory32.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitMemoryEx.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitMemoryHelper.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitMove.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitMul.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitSimdArithmetic.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitSimdCmp.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitSimdCrypto.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitSimdCvt.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitSimdHash.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitSimdHelper.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitSimdLogical.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitSimdMemory.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitSimdMove.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitSimdShift.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitSystem.cs
delete mode 100644 ChocolArm64/Instructions/InstEmitter.cs
delete mode 100644 ChocolArm64/Instructions/SoftFallback.cs
delete mode 100644 ChocolArm64/Instructions/SoftFloat.cs
delete mode 100644 ChocolArm64/Instructions/VectorHelper.cs
delete mode 100644 ChocolArm64/IntermediateRepresentation/BasicBlock.cs
delete mode 100644 ChocolArm64/IntermediateRepresentation/ILLabel.cs
delete mode 100644 ChocolArm64/IntermediateRepresentation/Operation.cs
delete mode 100644 ChocolArm64/IntermediateRepresentation/OperationType.cs
delete mode 100644 ChocolArm64/IntermediateRepresentation/RegisterMask.cs
delete mode 100644 ChocolArm64/Memory/CompareExchange128.cs
delete mode 100644 ChocolArm64/Memory/IMemory.cs
delete mode 100644 ChocolArm64/Memory/MemoryHelper.cs
delete mode 100644 ChocolArm64/Memory/MemoryManagement.cs
delete mode 100644 ChocolArm64/Memory/MemoryManagementUnix.cs
delete mode 100644 ChocolArm64/Memory/MemoryManagementWindows.cs
delete mode 100644 ChocolArm64/Memory/MemoryManager.cs
delete mode 100644 ChocolArm64/Memory/MemoryProtection.cs
delete mode 100644 ChocolArm64/Memory/MemoryProtectionException.cs
delete mode 100644 ChocolArm64/OpCodeTable.cs
delete mode 100644 ChocolArm64/Optimizations.cs
delete mode 100644 ChocolArm64/State/Aarch32Mode.cs
delete mode 100644 ChocolArm64/State/CpuThreadState.cs
delete mode 100644 ChocolArm64/State/ExecutionMode.cs
delete mode 100644 ChocolArm64/State/FpExc.cs
delete mode 100644 ChocolArm64/State/FpType.cs
delete mode 100644 ChocolArm64/State/Fpcr.cs
delete mode 100644 ChocolArm64/State/Fpsr.cs
delete mode 100644 ChocolArm64/State/PState.cs
delete mode 100644 ChocolArm64/State/Register.cs
delete mode 100644 ChocolArm64/State/RegisterAlias.cs
delete mode 100644 ChocolArm64/State/RegisterConsts.cs
delete mode 100644 ChocolArm64/State/RegisterSize.cs
delete mode 100644 ChocolArm64/State/RegisterType.cs
delete mode 100644 ChocolArm64/State/RoundMode.cs
delete mode 100644 ChocolArm64/Translation/CallType.cs
delete mode 100644 ChocolArm64/Translation/ILEmitterCtx.cs
delete mode 100644 ChocolArm64/Translation/ILGeneratorEx.cs
delete mode 100644 ChocolArm64/Translation/RegisterUsage.cs
delete mode 100644 ChocolArm64/Translation/TranslatedSub.cs
delete mode 100644 ChocolArm64/Translation/TranslatedSubBuilder.cs
delete mode 100644 ChocolArm64/Translation/TranslationTier.cs
delete mode 100644 ChocolArm64/Translation/Translator.cs
delete mode 100644 ChocolArm64/Translation/TranslatorCache.cs
delete mode 100644 ChocolArm64/Translation/TranslatorQueue.cs
delete mode 100644 ChocolArm64/Translation/TranslatorQueueItem.cs
diff --git a/ARMeilleure/ARMeilleure.csproj b/ARMeilleure/ARMeilleure.csproj
index 15e5c0274b..4f55243fed 100644
--- a/ARMeilleure/ARMeilleure.csproj
+++ b/ARMeilleure/ARMeilleure.csproj
@@ -1,9 +1,8 @@
- netcoreapp2.1
+ netcoreapp3.0
win-x64;osx-x64;linux-x64
- latest
diff --git a/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs b/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs
index 44659e8057..c411a6d3fc 100644
--- a/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs
+++ b/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs
@@ -1033,14 +1033,13 @@ namespace ARMeilleure.Instructions
}
}
- public static void Fnmadd_S(ArmEmitterContext context)
+ public static void Fnmadd_S(ArmEmitterContext context) // Fused.
{
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
int sizeF = op.Size & 1;
- OperandType type = sizeF != 0 ? OperandType.FP64
- : OperandType.FP32;
+ OperandType type = sizeF != 0 ? OperandType.FP64 : OperandType.FP32;
Operand ne = context.VectorExtract(type, GetVec(op.Rn), 0);
Operand me = context.VectorExtract(type, GetVec(op.Rm), 0);
@@ -1051,14 +1050,13 @@ namespace ARMeilleure.Instructions
context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), res, 0));
}
- public static void Fnmsub_S(ArmEmitterContext context)
+ public static void Fnmsub_S(ArmEmitterContext context) // Fused.
{
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
int sizeF = op.Size & 1;
- OperandType type = sizeF != 0 ? OperandType.FP64
- : OperandType.FP32;
+ OperandType type = sizeF != 0 ? OperandType.FP64 : OperandType.FP32;
Operand ne = context.VectorExtract(type, GetVec(op.Rn), 0);
Operand me = context.VectorExtract(type, GetVec(op.Rm), 0);
diff --git a/ARMeilleure/Instructions/SoftFloat.cs b/ARMeilleure/Instructions/SoftFloat.cs
index 7358e6b2cb..af22c85d21 100644
--- a/ARMeilleure/Instructions/SoftFloat.cs
+++ b/ARMeilleure/Instructions/SoftFloat.cs
@@ -1073,10 +1073,7 @@ namespace ARMeilleure.Instructions
}
else
{
- // TODO: When available, use: T MathF.FusedMultiplyAdd(T, T, T);
- // https://github.com/dotnet/corefx/issues/31903
-
- result = valueA + (value1 * value2);
+ result = MathF.FusedMultiplyAdd(value1, value2, valueA);
if ((context.Fpcr & FPCR.Fz) != 0 && float.IsSubnormal(result))
{
@@ -1256,10 +1253,7 @@ namespace ARMeilleure.Instructions
}
else
{
- // TODO: When available, use: T MathF.FusedMultiplyAdd(T, T, T);
- // https://github.com/dotnet/corefx/issues/31903
-
- result = 2f + (value1 * value2);
+ result = MathF.FusedMultiplyAdd(value1, value2, 2f);
if ((context.Fpcr & FPCR.Fz) != 0 && float.IsSubnormal(result))
{
@@ -1388,10 +1382,7 @@ namespace ARMeilleure.Instructions
}
else
{
- // TODO: When available, use: T MathF.FusedMultiplyAdd(T, T, T);
- // https://github.com/dotnet/corefx/issues/31903
-
- result = (3f + (value1 * value2)) / 2f;
+ result = MathF.FusedMultiplyAdd(value1, value2, 3f) / 2f;
if ((context.Fpcr & FPCR.Fz) != 0 && float.IsSubnormal(result))
{
@@ -2142,10 +2133,7 @@ namespace ARMeilleure.Instructions
}
else
{
- // TODO: When available, use: T Math.FusedMultiplyAdd(T, T, T);
- // https://github.com/dotnet/corefx/issues/31903
-
- result = valueA + (value1 * value2);
+ result = Math.FusedMultiplyAdd(value1, value2, valueA);
if ((context.Fpcr & FPCR.Fz) != 0 && double.IsSubnormal(result))
{
@@ -2323,10 +2311,7 @@ namespace ARMeilleure.Instructions
}
else
{
- // TODO: When available, use: T Math.FusedMultiplyAdd(T, T, T);
- // https://github.com/dotnet/corefx/issues/31903
-
- result = 2d + (value1 * value2);
+ result = Math.FusedMultiplyAdd(value1, value2, 2d);
if ((context.Fpcr & FPCR.Fz) != 0 && double.IsSubnormal(result))
{
@@ -2455,10 +2440,7 @@ namespace ARMeilleure.Instructions
}
else
{
- // TODO: When available, use: T Math.FusedMultiplyAdd(T, T, T);
- // https://github.com/dotnet/corefx/issues/31903
-
- result = (3d + (value1 * value2)) / 2d;
+ result = Math.FusedMultiplyAdd(value1, value2, 3d) / 2d;
if ((context.Fpcr & FPCR.Fz) != 0 && double.IsSubnormal(result))
{
diff --git a/ARMeilleure/Memory/IMemoryManager.cs b/ARMeilleure/Memory/IMemoryManager.cs
deleted file mode 100644
index bcee5db230..0000000000
--- a/ARMeilleure/Memory/IMemoryManager.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using ARMeilleure.State;
-using System;
-
-namespace ARMeilleure.Memory
-{
- public interface IMemoryManager : IMemory, IDisposable
- {
- void Map(long va, long pa, long size);
-
- void Unmap(long position, long size);
-
- bool IsMapped(long position);
-
- long GetPhysicalAddress(long virtualAddress);
-
- bool IsRegionModified(long position, long size);
-
- bool TryGetHostAddress(long position, long size, out IntPtr ptr);
-
- bool IsValidPosition(long position);
-
- bool AtomicCompareExchangeInt32(long position, int expected, int desired);
-
- int AtomicIncrementInt32(long position);
-
- int AtomicDecrementInt32(long position);
-
- byte[] ReadBytes(long position, long size);
-
- void ReadBytes(long position, byte[] data, int startIndex, int size);
-
- void WriteVector128(long position, V128 value);
-
- void WriteBytes(long position, byte[] data);
-
- void WriteBytes(long position, byte[] data, int startIndex, int size);
-
- void CopyBytes(long src, long dst, long size);
- }
-}
\ No newline at end of file
diff --git a/ARMeilleure/Memory/MemoryHelper.cs b/ARMeilleure/Memory/MemoryHelper.cs
index 71ddac2388..8e310d4d7f 100644
--- a/ARMeilleure/Memory/MemoryHelper.cs
+++ b/ARMeilleure/Memory/MemoryHelper.cs
@@ -7,7 +7,7 @@ namespace ARMeilleure.Memory
{
public static class MemoryHelper
{
- public static void FillWithZeros(IMemoryManager memory, long position, int size)
+ public static void FillWithZeros(MemoryManager memory, long position, int size)
{
int size8 = size & ~(8 - 1);
@@ -22,7 +22,7 @@ namespace ARMeilleure.Memory
}
}
- public unsafe static T Read(IMemoryManager memory, long position) where T : struct
+ public unsafe static T Read(MemoryManager memory, long position) where T : struct
{
long size = Marshal.SizeOf();
@@ -34,7 +34,7 @@ namespace ARMeilleure.Memory
}
}
- public unsafe static void Write(IMemoryManager memory, long position, T value) where T : struct
+ public unsafe static void Write(MemoryManager memory, long position, T value) where T : struct
{
long size = Marshal.SizeOf();
@@ -48,7 +48,7 @@ namespace ARMeilleure.Memory
memory.WriteBytes(position, data);
}
- public static string ReadAsciiString(IMemoryManager memory, long position, long maxSize = -1)
+ public static string ReadAsciiString(MemoryManager memory, long position, long maxSize = -1)
{
using (MemoryStream ms = new MemoryStream())
{
diff --git a/ARMeilleure/Memory/MemoryManager.cs b/ARMeilleure/Memory/MemoryManager.cs
index 12c1184373..c62249881d 100644
--- a/ARMeilleure/Memory/MemoryManager.cs
+++ b/ARMeilleure/Memory/MemoryManager.cs
@@ -7,7 +7,7 @@ using static ARMeilleure.Memory.MemoryManagement;
namespace ARMeilleure.Memory
{
- public unsafe class MemoryManager : IMemoryManager
+ public unsafe class MemoryManager
{
public const int PageBits = 12;
public const int PageSize = 1 << PageBits;
diff --git a/ARMeilleure/State/ExecutionContext.cs b/ARMeilleure/State/ExecutionContext.cs
index 22cfcb6943..406766803e 100644
--- a/ARMeilleure/State/ExecutionContext.cs
+++ b/ARMeilleure/State/ExecutionContext.cs
@@ -3,7 +3,7 @@ using System.Diagnostics;
namespace ARMeilleure.State
{
- public class ExecutionContext : IExecutionContext
+ public class ExecutionContext
{
private const int MinCountForCheck = 40000;
diff --git a/ARMeilleure/State/IExecutionContext.cs b/ARMeilleure/State/IExecutionContext.cs
deleted file mode 100644
index df91b7a1e7..0000000000
--- a/ARMeilleure/State/IExecutionContext.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System;
-
-namespace ARMeilleure.State
-{
- public interface IExecutionContext : IDisposable
- {
- uint CtrEl0 { get; }
- uint DczidEl0 { get; }
-
- ulong CntfrqEl0 { get; set; }
- ulong CntpctEl0 { get; }
-
- long TpidrEl0 { get; set; }
- long Tpidr { get; set; }
-
- FPCR Fpcr { get; set; }
- FPSR Fpsr { get; set; }
-
- bool IsAarch32 { get; set; }
-
- bool Running { get; set; }
-
- event EventHandler Interrupt;
- event EventHandler Break;
- event EventHandler SupervisorCall;
- event EventHandler Undefined;
-
- ulong GetX(int index);
- void SetX(int index, ulong value);
-
- V128 GetV(int index);
-
- bool GetPstateFlag(PState flag);
-
- void RequestInterrupt();
- }
-}
\ No newline at end of file
diff --git a/ARMeilleure/Translation/ITranslator.cs b/ARMeilleure/Translation/ITranslator.cs
deleted file mode 100644
index 1063d3a658..0000000000
--- a/ARMeilleure/Translation/ITranslator.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using ARMeilleure.State;
-
-namespace ARMeilleure.Translation
-{
- public interface ITranslator
- {
- void Execute(IExecutionContext context, ulong address);
- }
-}
\ No newline at end of file
diff --git a/ARMeilleure/Translation/Translator.cs b/ARMeilleure/Translation/Translator.cs
index 6a74512141..6531e9f0f7 100644
--- a/ARMeilleure/Translation/Translator.cs
+++ b/ARMeilleure/Translation/Translator.cs
@@ -12,7 +12,7 @@ using static ARMeilleure.IntermediateRepresentation.OperandHelper;
namespace ARMeilleure.Translation
{
- public class Translator : ITranslator
+ public class Translator
{
private const ulong CallFlag = InstEmitFlowHelper.CallFlag;
@@ -54,10 +54,8 @@ namespace ARMeilleure.Translation
}
}
- public void Execute(IExecutionContext ctx, ulong address)
+ public void Execute(State.ExecutionContext context, ulong address)
{
- State.ExecutionContext context = (State.ExecutionContext)ctx;
-
if (Interlocked.Increment(ref _threadCount) == 1)
{
Thread backgroundTranslatorThread = new Thread(TranslateQueuedSubs);
diff --git a/ChocolArm64/ChocolArm64.csproj b/ChocolArm64/ChocolArm64.csproj
deleted file mode 100644
index cccdd94df5..0000000000
--- a/ChocolArm64/ChocolArm64.csproj
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
- netcoreapp2.1
- win-x64;osx-x64;linux-x64
- Debug;Release;Profile Debug;Profile Release
-
-
-
- true
-
-
-
- true
- TRACE;USE_PROFILING
- false
-
-
-
- true
-
-
-
- true
- TRACE;USE_PROFILING
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/ChocolArm64/Decoders/BitUtils.cs b/ChocolArm64/Decoders/BitUtils.cs
deleted file mode 100644
index 8b9fb5e3cb..0000000000
--- a/ChocolArm64/Decoders/BitUtils.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-namespace ChocolArm64.Decoders
-{
- static class BitUtils
- {
- public static int HighestBitSet32(int value)
- {
- for (int bit = 31; bit >= 0; bit--)
- {
- if (((value >> bit) & 1) != 0)
- {
- return bit;
- }
- }
-
- return -1;
- }
-
- private static readonly sbyte[] HbsNibbleTbl = { -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 };
-
- public static int HighestBitSetNibble(int value) => HbsNibbleTbl[value & 0b1111];
-
- public static long Replicate(long bits, int size)
- {
- long output = 0;
-
- for (int bit = 0; bit < 64; bit += size)
- {
- output |= bits << bit;
- }
-
- return output;
- }
-
- public static long FillWithOnes(int bits)
- {
- return bits == 64 ? -1L : (1L << bits) - 1;
- }
-
- public static int RotateRight(int bits, int shift, int size)
- {
- return (int)RotateRight((uint)bits, shift, size);
- }
-
- public static uint RotateRight(uint bits, int shift, int size)
- {
- return (bits >> shift) | (bits << (size - shift));
- }
-
- public static long RotateRight(long bits, int shift, int size)
- {
- return (long)RotateRight((ulong)bits, shift, size);
- }
-
- public static ulong RotateRight(ulong bits, int shift, int size)
- {
- return (bits >> shift) | (bits << (size - shift));
- }
- }
-}
diff --git a/ChocolArm64/Decoders/Block.cs b/ChocolArm64/Decoders/Block.cs
deleted file mode 100644
index fc87fd1839..0000000000
--- a/ChocolArm64/Decoders/Block.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace ChocolArm64.Decoders
-{
- class Block
- {
- public ulong Address { get; set; }
- public ulong EndAddress { get; set; }
-
- public Block Next { get; set; }
- public Block Branch { get; set; }
-
- public List OpCodes { get; private set; }
-
- public Block()
- {
- OpCodes = new List();
- }
-
- public Block(ulong address) : this()
- {
- Address = address;
- }
-
- public void Split(Block rightBlock)
- {
- int splitIndex = BinarySearch(OpCodes, rightBlock.Address);
-
- if ((ulong)OpCodes[splitIndex].Position < rightBlock.Address)
- {
- splitIndex++;
- }
-
- int splitCount = OpCodes.Count - splitIndex;
-
- if (splitCount <= 0)
- {
- throw new ArgumentException("Can't split at right block address.");
- }
-
- rightBlock.EndAddress = EndAddress;
-
- rightBlock.Next = Next;
- rightBlock.Branch = Branch;
-
- rightBlock.OpCodes.AddRange(OpCodes.GetRange(splitIndex, splitCount));
-
- EndAddress = rightBlock.Address;
-
- Next = rightBlock;
- Branch = null;
-
- OpCodes.RemoveRange(splitIndex, splitCount);
- }
-
- private static int BinarySearch(List opCodes, ulong address)
- {
- int left = 0;
- int middle = 0;
- int right = opCodes.Count - 1;
-
- while (left <= right)
- {
- int size = right - left;
-
- middle = left + (size >> 1);
-
- OpCode64 opCode = opCodes[middle];
-
- if (address == (ulong)opCode.Position)
- {
- break;
- }
-
- if (address < (ulong)opCode.Position)
- {
- right = middle - 1;
- }
- else
- {
- left = middle + 1;
- }
- }
-
- return middle;
- }
-
- public OpCode64 GetLastOp()
- {
- if (OpCodes.Count > 0)
- {
- return OpCodes[OpCodes.Count - 1];
- }
-
- return null;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/Condition.cs b/ChocolArm64/Decoders/Condition.cs
deleted file mode 100644
index ef4b2959db..0000000000
--- a/ChocolArm64/Decoders/Condition.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-namespace ChocolArm64.Decoders
-{
- enum Condition
- {
- Eq = 0,
- Ne = 1,
- GeUn = 2,
- LtUn = 3,
- Mi = 4,
- Pl = 5,
- Vs = 6,
- Vc = 7,
- GtUn = 8,
- LeUn = 9,
- Ge = 10,
- Lt = 11,
- Gt = 12,
- Le = 13,
- Al = 14,
- Nv = 15
- }
-
- static class ConditionExtensions
- {
- public static Condition Invert(this Condition cond)
- {
- // Bit 0 of all conditions is basically a negation bit, so
- // inverting this bit has the effect of inverting the condition.
- return (Condition)((int)cond ^ 1);
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/DataOp.cs b/ChocolArm64/Decoders/DataOp.cs
deleted file mode 100644
index b7768bb4d0..0000000000
--- a/ChocolArm64/Decoders/DataOp.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace ChocolArm64.Decoders
-{
- enum DataOp
- {
- Adr = 0,
- Arithmetic = 1,
- Logical = 2,
- BitField = 3
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/Decoder.cs b/ChocolArm64/Decoders/Decoder.cs
deleted file mode 100644
index a1eeee15fb..0000000000
--- a/ChocolArm64/Decoders/Decoder.cs
+++ /dev/null
@@ -1,379 +0,0 @@
-using ChocolArm64.Instructions;
-using ChocolArm64.Memory;
-using ChocolArm64.State;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Reflection.Emit;
-
-namespace ChocolArm64.Decoders
-{
- static class Decoder
- {
- private delegate object OpActivator(Inst inst, long position, int opCode);
-
- private static ConcurrentDictionary _opActivators;
-
- static Decoder()
- {
- _opActivators = new ConcurrentDictionary();
- }
-
- public static Block[] DecodeBasicBlock(MemoryManager memory, ulong address, ExecutionMode mode)
- {
- Block block = new Block(address);
-
- FillBlock(memory, mode, block, ulong.MaxValue);
-
- OpCode64 lastOp = block.GetLastOp();
-
- if (IsBranch(lastOp) && !IsCall(lastOp) && lastOp is IOpCodeBImm op)
- {
- // It's possible that the branch on this block lands on the middle of the block.
- // This is more common on tight loops. In this case, we can improve the codegen
- // a bit by changing the CFG and either making the branch point to the same block
- // (which indicates that the block is a loop that jumps back to the start), and the
- // other possible case is a jump somewhere on the middle of the block, which is
- // also a loop, but in this case we need to split the block in half.
- if ((ulong)op.Imm == address)
- {
- block.Branch = block;
- }
- else if ((ulong)op.Imm > address &&
- (ulong)op.Imm < block.EndAddress)
- {
- Block rightBlock = new Block((ulong)op.Imm);
-
- block.Split(rightBlock);
-
- return new Block[] { block, rightBlock };
- }
- }
-
- return new Block[] { block };
- }
-
- public static Block[] DecodeSubroutine(MemoryManager memory, ulong address, ExecutionMode mode)
- {
- List blocks = new List();
-
- Queue workQueue = new Queue();
-
- Dictionary visited = new Dictionary();
-
- Block GetBlock(ulong blkAddress)
- {
- if (!visited.TryGetValue(blkAddress, out Block block))
- {
- block = new Block(blkAddress);
-
- workQueue.Enqueue(block);
-
- visited.Add(blkAddress, block);
- }
-
- return block;
- }
-
- GetBlock(address);
-
- while (workQueue.TryDequeue(out Block currBlock))
- {
- // Check if the current block is inside another block.
- if (BinarySearch(blocks, currBlock.Address, out int nBlkIndex))
- {
- Block nBlock = blocks[nBlkIndex];
-
- if (nBlock.Address == currBlock.Address)
- {
- throw new InvalidOperationException("Found duplicate block address on the list.");
- }
-
- nBlock.Split(currBlock);
-
- blocks.Insert(nBlkIndex + 1, currBlock);
-
- continue;
- }
-
- // If we have a block after the current one, set the limit address.
- ulong limitAddress = ulong.MaxValue;
-
- if (nBlkIndex != blocks.Count)
- {
- Block nBlock = blocks[nBlkIndex];
-
- int nextIndex = nBlkIndex + 1;
-
- if (nBlock.Address < currBlock.Address && nextIndex < blocks.Count)
- {
- limitAddress = blocks[nextIndex].Address;
- }
- else if (nBlock.Address > currBlock.Address)
- {
- limitAddress = blocks[nBlkIndex].Address;
- }
- }
-
- FillBlock(memory, mode, currBlock, limitAddress);
-
- if (currBlock.OpCodes.Count != 0)
- {
- // Set child blocks. "Branch" is the block the branch instruction
- // points to (when taken), "Next" is the block at the next address,
- // executed when the branch is not taken. For Unconditional Branches
- // (except BL/BLR that are sub calls) or end of executable, Next is null.
- OpCode64 lastOp = currBlock.GetLastOp();
-
- bool isCall = IsCall(lastOp);
-
- if (lastOp is IOpCodeBImm op && !isCall)
- {
- currBlock.Branch = GetBlock((ulong)op.Imm);
- }
-
- if (!IsUnconditionalBranch(lastOp) || isCall)
- {
- currBlock.Next = GetBlock(currBlock.EndAddress);
- }
- }
-
- // Insert the new block on the list (sorted by address).
- if (blocks.Count != 0)
- {
- Block nBlock = blocks[nBlkIndex];
-
- blocks.Insert(nBlkIndex + (nBlock.Address < currBlock.Address ? 1 : 0), currBlock);
- }
- else
- {
- blocks.Add(currBlock);
- }
- }
-
- return blocks.ToArray();
- }
-
- private static bool BinarySearch(List blocks, ulong address, out int index)
- {
- index = 0;
-
- int left = 0;
- int right = blocks.Count - 1;
-
- while (left <= right)
- {
- int size = right - left;
-
- int middle = left + (size >> 1);
-
- Block block = blocks[middle];
-
- index = middle;
-
- if (address >= block.Address && address < block.EndAddress)
- {
- return true;
- }
-
- if (address < block.Address)
- {
- right = middle - 1;
- }
- else
- {
- left = middle + 1;
- }
- }
-
- return false;
- }
-
- private static void FillBlock(
- MemoryManager memory,
- ExecutionMode mode,
- Block block,
- ulong limitAddress)
- {
- ulong address = block.Address;
-
- OpCode64 opCode;
-
- do
- {
- if (address >= limitAddress)
- {
- break;
- }
-
- opCode = DecodeOpCode(memory, address, mode);
-
- block.OpCodes.Add(opCode);
-
- address += (ulong)opCode.OpCodeSizeInBytes;
- }
- while (!(IsBranch(opCode) || IsException(opCode)));
-
- block.EndAddress = address;
- }
-
- private static bool IsBranch(OpCode64 opCode)
- {
- return opCode is OpCodeBImm64 ||
- opCode is OpCodeBReg64 || IsAarch32Branch(opCode);
- }
-
- private static bool IsUnconditionalBranch(OpCode64 opCode)
- {
- return opCode is OpCodeBImmAl64 ||
- opCode is OpCodeBReg64 || IsAarch32UnconditionalBranch(opCode);
- }
-
- private static bool IsAarch32UnconditionalBranch(OpCode64 opCode)
- {
- if (!(opCode is OpCode32 op))
- {
- return false;
- }
-
- // Note: On ARM32, most instructions have conditional execution,
- // so there's no "Always" (unconditional) branch like on ARM64.
- // We need to check if the condition is "Always" instead.
- return IsAarch32Branch(op) && op.Cond >= Condition.Al;
- }
-
- private static bool IsAarch32Branch(OpCode64 opCode)
- {
- // Note: On ARM32, most ALU operations can write to R15 (PC),
- // so we must consider such operations as a branch in potential as well.
- if (opCode is IOpCode32Alu opAlu && opAlu.Rd == RegisterAlias.Aarch32Pc)
- {
- return true;
- }
-
- // Same thing for memory operations. We have the cases where PC is a target
- // register (Rt == 15 or (mask & (1 << 15)) != 0), and cases where there is
- // a write back to PC (wback == true && Rn == 15), however the later may
- // be "undefined" depending on the CPU, so compilers should not produce that.
- if (opCode is IOpCode32Mem || opCode is IOpCode32MemMult)
- {
- int rt, rn;
-
- bool wBack, isLoad;
-
- if (opCode is IOpCode32Mem opMem)
- {
- rt = opMem.Rt;
- rn = opMem.Rn;
- wBack = opMem.WBack;
- isLoad = opMem.IsLoad;
-
- // For the dual load, we also need to take into account the
- // case were Rt2 == 15 (PC).
- if (rt == 14 && opMem.Emitter == InstEmit32.Ldrd)
- {
- rt = RegisterAlias.Aarch32Pc;
- }
- }
- else if (opCode is IOpCode32MemMult opMemMult)
- {
- const int pcMask = 1 << RegisterAlias.Aarch32Pc;
-
- rt = (opMemMult.RegisterMask & pcMask) != 0 ? RegisterAlias.Aarch32Pc : 0;
- rn = opMemMult.Rn;
- wBack = opMemMult.PostOffset != 0;
- isLoad = opMemMult.IsLoad;
- }
- else
- {
- throw new NotImplementedException($"The type \"{opCode.GetType().Name}\" is not implemented on the decoder.");
- }
-
- if ((rt == RegisterAlias.Aarch32Pc && isLoad) ||
- (rn == RegisterAlias.Aarch32Pc && wBack))
- {
- return true;
- }
- }
-
- // Explicit branch instructions.
- return opCode is IOpCode32BImm ||
- opCode is IOpCode32BReg;
- }
-
- private static bool IsCall(OpCode64 opCode)
- {
- // TODO (CQ): ARM32 support.
- return opCode.Emitter == InstEmit.Bl ||
- opCode.Emitter == InstEmit.Blr;
- }
-
- private static bool IsException(OpCode64 opCode)
- {
- return opCode.Emitter == InstEmit.Brk ||
- opCode.Emitter == InstEmit.Svc ||
- opCode.Emitter == InstEmit.Und;
- }
-
- public static OpCode64 DecodeOpCode(MemoryManager memory, ulong address, ExecutionMode mode)
- {
- int opCode = memory.ReadInt32((long)address);
-
- Inst inst;
-
- if (mode == ExecutionMode.Aarch64)
- {
- inst = OpCodeTable.GetInstA64(opCode);
- }
- else
- {
- if (mode == ExecutionMode.Aarch32Arm)
- {
- inst = OpCodeTable.GetInstA32(opCode);
- }
- else /* if (mode == ExecutionMode.Aarch32Thumb) */
- {
- inst = OpCodeTable.GetInstT32(opCode);
- }
- }
-
- OpCode64 decodedOpCode = new OpCode64(Inst.Undefined, (long)address, opCode);
-
- if (inst.Type != null)
- {
- decodedOpCode = MakeOpCode(inst.Type, inst, (long)address, opCode);
- }
-
- return decodedOpCode;
- }
-
- private static OpCode64 MakeOpCode(Type type, Inst inst, long position, int opCode)
- {
- if (type == null)
- {
- throw new ArgumentNullException(nameof(type));
- }
-
- OpActivator createInstance = _opActivators.GetOrAdd(type, CacheOpActivator);
-
- return (OpCode64)createInstance(inst, position, opCode);
- }
-
- private static OpActivator CacheOpActivator(Type type)
- {
- Type[] argTypes = new Type[] { typeof(Inst), typeof(long), typeof(int) };
-
- DynamicMethod mthd = new DynamicMethod($"Make{type.Name}", type, argTypes);
-
- ILGenerator generator = mthd.GetILGenerator();
-
- generator.Emit(OpCodes.Ldarg_0);
- generator.Emit(OpCodes.Ldarg_1);
- generator.Emit(OpCodes.Ldarg_2);
- generator.Emit(OpCodes.Newobj, type.GetConstructor(argTypes));
- generator.Emit(OpCodes.Ret);
-
- return (OpActivator)mthd.CreateDelegate(typeof(OpActivator));
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/DecoderHelper.cs b/ChocolArm64/Decoders/DecoderHelper.cs
deleted file mode 100644
index 2209472b7d..0000000000
--- a/ChocolArm64/Decoders/DecoderHelper.cs
+++ /dev/null
@@ -1,112 +0,0 @@
-using System;
-
-namespace ChocolArm64.Decoders
-{
- static class DecoderHelper
- {
- public struct BitMask
- {
- public long WMask;
- public long TMask;
- public int Pos;
- public int Shift;
- public bool IsUndefined;
-
- public static BitMask Invalid => new BitMask { IsUndefined = true };
- }
-
- public static BitMask DecodeBitMask(int opCode, bool immediate)
- {
- int immS = (opCode >> 10) & 0x3f;
- int immR = (opCode >> 16) & 0x3f;
-
- int n = (opCode >> 22) & 1;
- int sf = (opCode >> 31) & 1;
-
- int length = BitUtils.HighestBitSet32((~immS & 0x3f) | (n << 6));
-
- if (length < 1 || (sf == 0 && n != 0))
- {
- return BitMask.Invalid;
- }
-
- int size = 1 << length;
-
- int levels = size - 1;
-
- int s = immS & levels;
- int r = immR & levels;
-
- if (immediate && s == levels)
- {
- return BitMask.Invalid;
- }
-
- long wMask = BitUtils.FillWithOnes(s + 1);
- long tMask = BitUtils.FillWithOnes(((s - r) & levels) + 1);
-
- if (r > 0)
- {
- wMask = BitUtils.RotateRight(wMask, r, size);
- wMask &= BitUtils.FillWithOnes(size);
- }
-
- return new BitMask()
- {
- WMask = BitUtils.Replicate(wMask, size),
- TMask = BitUtils.Replicate(tMask, size),
-
- Pos = immS,
- Shift = immR
- };
- }
-
- public static long DecodeImm8Float(long imm, int size)
- {
- int e = 0, f = 0;
-
- switch (size)
- {
- case 0: e = 8; f = 23; break;
- case 1: e = 11; f = 52; break;
-
- default: throw new ArgumentOutOfRangeException(nameof(size));
- }
-
- long value = (imm & 0x3f) << f - 4;
-
- long eBit = (imm >> 6) & 1;
- long sBit = (imm >> 7) & 1;
-
- if (eBit != 0)
- {
- value |= (1L << e - 3) - 1 << f + 2;
- }
-
- value |= (eBit ^ 1) << f + e - 1;
- value |= sBit << f + e;
-
- return value;
- }
-
- public static long DecodeImm24_2(int opCode)
- {
- return ((long)opCode << 40) >> 38;
- }
-
- public static long DecodeImm26_2(int opCode)
- {
- return ((long)opCode << 38) >> 36;
- }
-
- public static long DecodeImmS19_2(int opCode)
- {
- return (((long)opCode << 40) >> 43) & ~3;
- }
-
- public static long DecodeImmS14_2(int opCode)
- {
- return (((long)opCode << 45) >> 48) & ~3;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/IOpCode32.cs b/ChocolArm64/Decoders/IOpCode32.cs
deleted file mode 100644
index 3353ffe8d8..0000000000
--- a/ChocolArm64/Decoders/IOpCode32.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace ChocolArm64.Decoders
-{
- interface IOpCode32 : IOpCode64
- {
- Condition Cond { get; }
-
- uint GetPc();
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/IOpCode32Alu.cs b/ChocolArm64/Decoders/IOpCode32Alu.cs
deleted file mode 100644
index d6f6d82a4f..0000000000
--- a/ChocolArm64/Decoders/IOpCode32Alu.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace ChocolArm64.Decoders
-{
- interface IOpCode32Alu : IOpCode32
- {
- int Rd { get; }
- int Rn { get; }
-
- bool SetFlags { get; }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/IOpCode32BImm.cs b/ChocolArm64/Decoders/IOpCode32BImm.cs
deleted file mode 100644
index b69c1e369f..0000000000
--- a/ChocolArm64/Decoders/IOpCode32BImm.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace ChocolArm64.Decoders
-{
- interface IOpCode32BImm : IOpCode32, IOpCodeBImm { }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/IOpCode32BReg.cs b/ChocolArm64/Decoders/IOpCode32BReg.cs
deleted file mode 100644
index a498b02d7c..0000000000
--- a/ChocolArm64/Decoders/IOpCode32BReg.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace ChocolArm64.Decoders
-{
- interface IOpCode32BReg : IOpCode32
- {
- int Rm { get; }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/IOpCode32Mem.cs b/ChocolArm64/Decoders/IOpCode32Mem.cs
deleted file mode 100644
index 8ed25add88..0000000000
--- a/ChocolArm64/Decoders/IOpCode32Mem.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace ChocolArm64.Decoders
-{
- interface IOpCode32Mem : IOpCode32
- {
- int Rt { get; }
- int Rn { get; }
-
- bool WBack { get; }
-
- bool IsLoad { get; }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/IOpCode32MemMult.cs b/ChocolArm64/Decoders/IOpCode32MemMult.cs
deleted file mode 100644
index d611c53bff..0000000000
--- a/ChocolArm64/Decoders/IOpCode32MemMult.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace ChocolArm64.Decoders
-{
- interface IOpCode32MemMult : IOpCode32
- {
- int Rn { get; }
-
- int RegisterMask { get; }
-
- int PostOffset { get; }
-
- bool IsLoad { get; }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/IOpCode64.cs b/ChocolArm64/Decoders/IOpCode64.cs
deleted file mode 100644
index e940712311..0000000000
--- a/ChocolArm64/Decoders/IOpCode64.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using ChocolArm64.Instructions;
-using ChocolArm64.State;
-
-namespace ChocolArm64.Decoders
-{
- interface IOpCode64
- {
- long Position { get; }
-
- InstEmitter Emitter { get; }
- RegisterSize RegisterSize { get; }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/IOpCodeAlu64.cs b/ChocolArm64/Decoders/IOpCodeAlu64.cs
deleted file mode 100644
index b9a5fe9e68..0000000000
--- a/ChocolArm64/Decoders/IOpCodeAlu64.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace ChocolArm64.Decoders
-{
- interface IOpCodeAlu64 : IOpCode64
- {
- int Rd { get; }
- int Rn { get; }
-
- DataOp DataOp { get; }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/IOpCodeAluImm64.cs b/ChocolArm64/Decoders/IOpCodeAluImm64.cs
deleted file mode 100644
index 4b305e27b7..0000000000
--- a/ChocolArm64/Decoders/IOpCodeAluImm64.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace ChocolArm64.Decoders
-{
- interface IOpCodeAluImm64 : IOpCodeAlu64
- {
- long Imm { get; }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/IOpCodeAluRs64.cs b/ChocolArm64/Decoders/IOpCodeAluRs64.cs
deleted file mode 100644
index df503ae9d8..0000000000
--- a/ChocolArm64/Decoders/IOpCodeAluRs64.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace ChocolArm64.Decoders
-{
- interface IOpCodeAluRs64 : IOpCodeAlu64
- {
- int Shift { get; }
- int Rm { get; }
-
- ShiftType ShiftType { get; }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/IOpCodeAluRx64.cs b/ChocolArm64/Decoders/IOpCodeAluRx64.cs
deleted file mode 100644
index f41fc4d2f0..0000000000
--- a/ChocolArm64/Decoders/IOpCodeAluRx64.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace ChocolArm64.Decoders
-{
- interface IOpCodeAluRx64 : IOpCodeAlu64
- {
- int Shift { get; }
- int Rm { get; }
-
- IntType IntType { get; }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/IOpCodeBImm.cs b/ChocolArm64/Decoders/IOpCodeBImm.cs
deleted file mode 100644
index f0c6a83256..0000000000
--- a/ChocolArm64/Decoders/IOpCodeBImm.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace ChocolArm64.Decoders
-{
- interface IOpCodeBImm : IOpCode64
- {
- long Imm { get; }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/IOpCodeCond64.cs b/ChocolArm64/Decoders/IOpCodeCond64.cs
deleted file mode 100644
index 2c465406bd..0000000000
--- a/ChocolArm64/Decoders/IOpCodeCond64.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace ChocolArm64.Decoders
-{
- interface IOpCodeCond64 : IOpCode64
- {
- Condition Cond { get; }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/IOpCodeLit64.cs b/ChocolArm64/Decoders/IOpCodeLit64.cs
deleted file mode 100644
index c6dc2c7fc1..0000000000
--- a/ChocolArm64/Decoders/IOpCodeLit64.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace ChocolArm64.Decoders
-{
- interface IOpCodeLit64 : IOpCode64
- {
- int Rt { get; }
- long Imm { get; }
- int Size { get; }
- bool Signed { get; }
- bool Prefetch { get; }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/IOpCodeSimd64.cs b/ChocolArm64/Decoders/IOpCodeSimd64.cs
deleted file mode 100644
index fc8f54d608..0000000000
--- a/ChocolArm64/Decoders/IOpCodeSimd64.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace ChocolArm64.Decoders
-{
- interface IOpCodeSimd64 : IOpCode64
- {
- int Size { get; }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/IntType.cs b/ChocolArm64/Decoders/IntType.cs
deleted file mode 100644
index 70f833ec56..0000000000
--- a/ChocolArm64/Decoders/IntType.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace ChocolArm64.Decoders
-{
- enum IntType
- {
- UInt8 = 0,
- UInt16 = 1,
- UInt32 = 2,
- UInt64 = 3,
- Int8 = 4,
- Int16 = 5,
- Int32 = 6,
- Int64 = 7
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCode32.cs b/ChocolArm64/Decoders/OpCode32.cs
deleted file mode 100644
index 1909757c19..0000000000
--- a/ChocolArm64/Decoders/OpCode32.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using ChocolArm64.Instructions;
-using ChocolArm64.State;
-
-namespace ChocolArm64.Decoders
-{
- class OpCode32 : OpCode64
- {
- public Condition Cond { get; protected set; }
-
- public OpCode32(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- RegisterSize = RegisterSize.Int32;
-
- Cond = (Condition)((uint)opCode >> 28);
- }
-
- public uint GetPc()
- {
- // Due to backwards compatibility and legacy behavior of ARMv4 CPUs pipeline,
- // the PC actually points 2 instructions ahead.
- return (uint)Position + (uint)OpCodeSizeInBytes * 2;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCode32Alu.cs b/ChocolArm64/Decoders/OpCode32Alu.cs
deleted file mode 100644
index 0cf066966b..0000000000
--- a/ChocolArm64/Decoders/OpCode32Alu.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCode32Alu : OpCode32, IOpCode32Alu
- {
- public int Rd { get; private set; }
- public int Rn { get; private set; }
-
- public bool SetFlags { get; private set; }
-
- public OpCode32Alu(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Rd = (opCode >> 12) & 0xf;
- Rn = (opCode >> 16) & 0xf;
-
- SetFlags = ((opCode >> 20) & 1) != 0;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCode32AluImm.cs b/ChocolArm64/Decoders/OpCode32AluImm.cs
deleted file mode 100644
index 4302f117e4..0000000000
--- a/ChocolArm64/Decoders/OpCode32AluImm.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCode32AluImm : OpCode32Alu
- {
- public int Imm { get; private set; }
-
- public bool IsRotated { get; private set; }
-
- public OpCode32AluImm(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- int value = (opCode >> 0) & 0xff;
- int shift = (opCode >> 8) & 0xf;
-
- Imm = BitUtils.RotateRight(value, shift * 2, 32);
-
- IsRotated = shift != 0;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCode32AluRsImm.cs b/ChocolArm64/Decoders/OpCode32AluRsImm.cs
deleted file mode 100644
index f23916be55..0000000000
--- a/ChocolArm64/Decoders/OpCode32AluRsImm.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCode32AluRsImm : OpCode32Alu
- {
- public int Rm { get; private set; }
- public int Imm { get; private set; }
-
- public ShiftType ShiftType { get; private set; }
-
- public OpCode32AluRsImm(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Rm = (opCode >> 0) & 0xf;
- Imm = (opCode >> 7) & 0x1f;
-
- ShiftType = (ShiftType)((opCode >> 5) & 3);
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCode32BImm.cs b/ChocolArm64/Decoders/OpCode32BImm.cs
deleted file mode 100644
index 7f3c29a677..0000000000
--- a/ChocolArm64/Decoders/OpCode32BImm.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCode32BImm : OpCode32, IOpCode32BImm
- {
- public long Imm { get; private set; }
-
- public OpCode32BImm(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- uint pc = GetPc();
-
- // When the condition is never, the instruction is BLX to Thumb mode.
- if (Cond != Condition.Nv)
- {
- pc &= ~3u;
- }
-
- Imm = pc + DecoderHelper.DecodeImm24_2(opCode);
-
- if (Cond == Condition.Nv)
- {
- long H = (opCode >> 23) & 2;
-
- Imm |= H;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCode32BReg.cs b/ChocolArm64/Decoders/OpCode32BReg.cs
deleted file mode 100644
index 4a0fa5376b..0000000000
--- a/ChocolArm64/Decoders/OpCode32BReg.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCode32BReg : OpCode32, IOpCode32BReg
- {
- public int Rm { get; private set; }
-
- public OpCode32BReg(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Rm = opCode & 0xf;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCode32Mem.cs b/ChocolArm64/Decoders/OpCode32Mem.cs
deleted file mode 100644
index ed648a5f73..0000000000
--- a/ChocolArm64/Decoders/OpCode32Mem.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCode32Mem : OpCode32, IOpCode32Mem
- {
- public int Rt { get; private set; }
- public int Rn { get; private set; }
-
- public int Imm { get; protected set; }
-
- public bool Index { get; private set; }
- public bool Add { get; private set; }
- public bool WBack { get; private set; }
- public bool Unprivileged { get; private set; }
-
- public bool IsLoad { get; private set; }
-
- public OpCode32Mem(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Rt = (opCode >> 12) & 0xf;
- Rn = (opCode >> 16) & 0xf;
-
- bool isLoad = (opCode & (1 << 20)) != 0;
- bool w = (opCode & (1 << 21)) != 0;
- bool u = (opCode & (1 << 23)) != 0;
- bool p = (opCode & (1 << 24)) != 0;
-
- Index = p;
- Add = u;
- WBack = !p || w;
- Unprivileged = !p && w;
-
- IsLoad = isLoad || inst.Emitter == InstEmit32.Ldrd;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCode32MemImm.cs b/ChocolArm64/Decoders/OpCode32MemImm.cs
deleted file mode 100644
index ca46e08f87..0000000000
--- a/ChocolArm64/Decoders/OpCode32MemImm.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCode32MemImm : OpCode32Mem
- {
- public OpCode32MemImm(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Imm = opCode & 0xfff;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCode32MemImm8.cs b/ChocolArm64/Decoders/OpCode32MemImm8.cs
deleted file mode 100644
index 02e446e8f1..0000000000
--- a/ChocolArm64/Decoders/OpCode32MemImm8.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCode32MemImm8 : OpCode32Mem
- {
- public OpCode32MemImm8(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- int imm4L = (opCode >> 0) & 0xf;
- int imm4H = (opCode >> 8) & 0xf;
-
- Imm = imm4L | (imm4H << 4);
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCode32MemMult.cs b/ChocolArm64/Decoders/OpCode32MemMult.cs
deleted file mode 100644
index 652da8a552..0000000000
--- a/ChocolArm64/Decoders/OpCode32MemMult.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCode32MemMult : OpCode32, IOpCode32MemMult
- {
- public int Rn { get; private set; }
-
- public int RegisterMask { get; private set; }
- public int Offset { get; private set; }
- public int PostOffset { get; private set; }
-
- public bool IsLoad { get; private set; }
-
- public OpCode32MemMult(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Rn = (opCode >> 16) & 0xf;
-
- bool isLoad = (opCode & (1 << 20)) != 0;
- bool w = (opCode & (1 << 21)) != 0;
- bool u = (opCode & (1 << 23)) != 0;
- bool p = (opCode & (1 << 24)) != 0;
-
- RegisterMask = opCode & 0xffff;
-
- int regsSize = 0;
-
- for (int index = 0; index < 16; index++)
- {
- regsSize += (RegisterMask >> index) & 1;
- }
-
- regsSize *= 4;
-
- if (!u)
- {
- Offset -= regsSize;
- }
-
- if (u == p)
- {
- Offset += 4;
- }
-
- if (w)
- {
- PostOffset = u ? regsSize : -regsSize;
- }
- else
- {
- PostOffset = 0;
- }
-
- IsLoad = isLoad;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCode64.cs b/ChocolArm64/Decoders/OpCode64.cs
deleted file mode 100644
index 1072228e1c..0000000000
--- a/ChocolArm64/Decoders/OpCode64.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using ChocolArm64.Instructions;
-using ChocolArm64.State;
-using System;
-
-namespace ChocolArm64.Decoders
-{
- class OpCode64 : IOpCode64
- {
- public long Position { get; private set; }
- public int RawOpCode { get; private set; }
-
- public int OpCodeSizeInBytes { get; protected set; } = 4;
-
- public InstEmitter Emitter { get; protected set; }
- public RegisterSize RegisterSize { get; protected set; }
-
- public OpCode64(Inst inst, long position, int opCode)
- {
- Position = position;
- RawOpCode = opCode;
-
- RegisterSize = RegisterSize.Int64;
-
- Emitter = inst.Emitter;
- }
-
- public int GetBitsCount()
- {
- switch (RegisterSize)
- {
- case RegisterSize.Int32: return 32;
- case RegisterSize.Int64: return 64;
- case RegisterSize.Simd64: return 64;
- case RegisterSize.Simd128: return 128;
- }
-
- throw new InvalidOperationException();
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeAdr64.cs b/ChocolArm64/Decoders/OpCodeAdr64.cs
deleted file mode 100644
index 98b2f07bbe..0000000000
--- a/ChocolArm64/Decoders/OpCodeAdr64.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeAdr64 : OpCode64
- {
- public int Rd { get; private set; }
- public long Imm { get; private set; }
-
- public OpCodeAdr64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Rd = opCode & 0x1f;
-
- Imm = DecoderHelper.DecodeImmS19_2(opCode);
- Imm |= ((long)opCode >> 29) & 3;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeAlu64.cs b/ChocolArm64/Decoders/OpCodeAlu64.cs
deleted file mode 100644
index b46fef4f7a..0000000000
--- a/ChocolArm64/Decoders/OpCodeAlu64.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeAlu64 : OpCode64, IOpCodeAlu64
- {
- public int Rd { get; protected set; }
- public int Rn { get; private set; }
-
- public DataOp DataOp { get; private set; }
-
- public OpCodeAlu64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Rd = (opCode >> 0) & 0x1f;
- Rn = (opCode >> 5) & 0x1f;
- DataOp = (DataOp)((opCode >> 24) & 0x3);
-
- RegisterSize = (opCode >> 31) != 0
- ? State.RegisterSize.Int64
- : State.RegisterSize.Int32;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeAluImm64.cs b/ChocolArm64/Decoders/OpCodeAluImm64.cs
deleted file mode 100644
index 64ac08a7a6..0000000000
--- a/ChocolArm64/Decoders/OpCodeAluImm64.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using ChocolArm64.Instructions;
-using System;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeAluImm64 : OpCodeAlu64, IOpCodeAluImm64
- {
- public long Imm { get; private set; }
-
- public OpCodeAluImm64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- if (DataOp == DataOp.Arithmetic)
- {
- Imm = (opCode >> 10) & 0xfff;
-
- int shift = (opCode >> 22) & 3;
-
- Imm <<= shift * 12;
- }
- else if (DataOp == DataOp.Logical)
- {
- var bm = DecoderHelper.DecodeBitMask(opCode, true);
-
- if (bm.IsUndefined)
- {
- Emitter = InstEmit.Und;
-
- return;
- }
-
- Imm = bm.WMask;
- }
- else
- {
- throw new ArgumentException(nameof(opCode));
- }
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeAluRs64.cs b/ChocolArm64/Decoders/OpCodeAluRs64.cs
deleted file mode 100644
index bed840b8ea..0000000000
--- a/ChocolArm64/Decoders/OpCodeAluRs64.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeAluRs64 : OpCodeAlu64, IOpCodeAluRs64
- {
- public int Shift { get; private set; }
- public int Rm { get; private set; }
-
- public ShiftType ShiftType { get; private set; }
-
- public OpCodeAluRs64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- int shift = (opCode >> 10) & 0x3f;
-
- if (shift >= GetBitsCount())
- {
- Emitter = InstEmit.Und;
-
- return;
- }
-
- Shift = shift;
-
- Rm = (opCode >> 16) & 0x1f;
- ShiftType = (ShiftType)((opCode >> 22) & 0x3);
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeAluRx64.cs b/ChocolArm64/Decoders/OpCodeAluRx64.cs
deleted file mode 100644
index 24cee056cb..0000000000
--- a/ChocolArm64/Decoders/OpCodeAluRx64.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeAluRx64 : OpCodeAlu64, IOpCodeAluRx64
- {
- public int Shift { get; private set; }
- public int Rm { get; private set; }
-
- public IntType IntType { get; private set; }
-
- public OpCodeAluRx64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Shift = (opCode >> 10) & 0x7;
- IntType = (IntType)((opCode >> 13) & 0x7);
- Rm = (opCode >> 16) & 0x1f;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeBImm64.cs b/ChocolArm64/Decoders/OpCodeBImm64.cs
deleted file mode 100644
index bb5326ce6b..0000000000
--- a/ChocolArm64/Decoders/OpCodeBImm64.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeBImm64 : OpCode64, IOpCodeBImm
- {
- public long Imm { get; protected set; }
-
- public OpCodeBImm64(Inst inst, long position, int opCode) : base(inst, position, opCode) { }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeBImmAl64.cs b/ChocolArm64/Decoders/OpCodeBImmAl64.cs
deleted file mode 100644
index f419ffa033..0000000000
--- a/ChocolArm64/Decoders/OpCodeBImmAl64.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeBImmAl64 : OpCodeBImm64
- {
- public OpCodeBImmAl64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Imm = position + DecoderHelper.DecodeImm26_2(opCode);
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeBImmCmp64.cs b/ChocolArm64/Decoders/OpCodeBImmCmp64.cs
deleted file mode 100644
index 2e674a54c3..0000000000
--- a/ChocolArm64/Decoders/OpCodeBImmCmp64.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeBImmCmp64 : OpCodeBImm64
- {
- public int Rt { get; private set; }
-
- public OpCodeBImmCmp64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Rt = opCode & 0x1f;
-
- Imm = position + DecoderHelper.DecodeImmS19_2(opCode);
-
- RegisterSize = (opCode >> 31) != 0
- ? State.RegisterSize.Int64
- : State.RegisterSize.Int32;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeBImmCond64.cs b/ChocolArm64/Decoders/OpCodeBImmCond64.cs
deleted file mode 100644
index ca7df5542c..0000000000
--- a/ChocolArm64/Decoders/OpCodeBImmCond64.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeBImmCond64 : OpCodeBImm64, IOpCodeCond64
- {
- public Condition Cond { get; private set; }
-
- public OpCodeBImmCond64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- int o0 = (opCode >> 4) & 1;
-
- if (o0 != 0)
- {
- Emitter = InstEmit.Und;
-
- return;
- }
-
- Cond = (Condition)(opCode & 0xf);
-
- Imm = position + DecoderHelper.DecodeImmS19_2(opCode);
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeBImmTest64.cs b/ChocolArm64/Decoders/OpCodeBImmTest64.cs
deleted file mode 100644
index a2e8baeaeb..0000000000
--- a/ChocolArm64/Decoders/OpCodeBImmTest64.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeBImmTest64 : OpCodeBImm64
- {
- public int Rt { get; private set; }
- public int Pos { get; private set; }
-
- public OpCodeBImmTest64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Rt = opCode & 0x1f;
-
- Imm = position + DecoderHelper.DecodeImmS14_2(opCode);
-
- Pos = (opCode >> 19) & 0x1f;
- Pos |= (opCode >> 26) & 0x20;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeBReg64.cs b/ChocolArm64/Decoders/OpCodeBReg64.cs
deleted file mode 100644
index 74dbff5839..0000000000
--- a/ChocolArm64/Decoders/OpCodeBReg64.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeBReg64 : OpCode64
- {
- public int Rn { get; private set; }
-
- public OpCodeBReg64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- int op4 = (opCode >> 0) & 0x1f;
- int op2 = (opCode >> 16) & 0x1f;
-
- if (op2 != 0b11111 || op4 != 0b00000)
- {
- Emitter = InstEmit.Und;
-
- return;
- }
-
- Rn = (opCode >> 5) & 0x1f;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeBfm64.cs b/ChocolArm64/Decoders/OpCodeBfm64.cs
deleted file mode 100644
index 6891a8f4fc..0000000000
--- a/ChocolArm64/Decoders/OpCodeBfm64.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeBfm64 : OpCodeAlu64
- {
- public long WMask { get; private set; }
- public long TMask { get; private set; }
- public int Pos { get; private set; }
- public int Shift { get; private set; }
-
- public OpCodeBfm64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- var bm = DecoderHelper.DecodeBitMask(opCode, false);
-
- if (bm.IsUndefined)
- {
- Emitter = InstEmit.Und;
-
- return;
- }
-
- WMask = bm.WMask;
- TMask = bm.TMask;
- Pos = bm.Pos;
- Shift = bm.Shift;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeCcmp64.cs b/ChocolArm64/Decoders/OpCodeCcmp64.cs
deleted file mode 100644
index d65a24a47e..0000000000
--- a/ChocolArm64/Decoders/OpCodeCcmp64.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using ChocolArm64.Instructions;
-using ChocolArm64.State;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeCcmp64 : OpCodeAlu64, IOpCodeCond64
- {
- public int Nzcv { get; private set; }
- protected int RmImm;
-
- public Condition Cond { get; private set; }
-
- public OpCodeCcmp64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- int o3 = (opCode >> 4) & 1;
-
- if (o3 != 0)
- {
- Emitter = InstEmit.Und;
-
- return;
- }
-
- Nzcv = (opCode >> 0) & 0xf;
- Cond = (Condition)((opCode >> 12) & 0xf);
- RmImm = (opCode >> 16) & 0x1f;
-
- Rd = RegisterAlias.Zr;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeCcmpImm64.cs b/ChocolArm64/Decoders/OpCodeCcmpImm64.cs
deleted file mode 100644
index 78d5de5502..0000000000
--- a/ChocolArm64/Decoders/OpCodeCcmpImm64.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeCcmpImm64 : OpCodeCcmp64, IOpCodeAluImm64
- {
- public long Imm => RmImm;
-
- public OpCodeCcmpImm64(Inst inst, long position, int opCode) : base(inst, position, opCode) { }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeCcmpReg64.cs b/ChocolArm64/Decoders/OpCodeCcmpReg64.cs
deleted file mode 100644
index a0544d987a..0000000000
--- a/ChocolArm64/Decoders/OpCodeCcmpReg64.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeCcmpReg64 : OpCodeCcmp64, IOpCodeAluRs64
- {
- public int Rm => RmImm;
-
- public int Shift => 0;
-
- public ShiftType ShiftType => ShiftType.Lsl;
-
- public OpCodeCcmpReg64(Inst inst, long position, int opCode) : base(inst, position, opCode) { }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeCsel64.cs b/ChocolArm64/Decoders/OpCodeCsel64.cs
deleted file mode 100644
index 108a279836..0000000000
--- a/ChocolArm64/Decoders/OpCodeCsel64.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeCsel64 : OpCodeAlu64, IOpCodeCond64
- {
- public int Rm { get; private set; }
-
- public Condition Cond { get; private set; }
-
- public OpCodeCsel64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Rm = (opCode >> 16) & 0x1f;
- Cond = (Condition)((opCode >> 12) & 0xf);
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeException64.cs b/ChocolArm64/Decoders/OpCodeException64.cs
deleted file mode 100644
index 2554124c78..0000000000
--- a/ChocolArm64/Decoders/OpCodeException64.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeException64 : OpCode64
- {
- public int Id { get; private set; }
-
- public OpCodeException64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Id = (opCode >> 5) & 0xffff;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeMem64.cs b/ChocolArm64/Decoders/OpCodeMem64.cs
deleted file mode 100644
index 36e6758352..0000000000
--- a/ChocolArm64/Decoders/OpCodeMem64.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeMem64 : OpCode64
- {
- public int Rt { get; protected set; }
- public int Rn { get; protected set; }
- public int Size { get; protected set; }
- public bool Extend64 { get; protected set; }
-
- public OpCodeMem64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Rt = (opCode >> 0) & 0x1f;
- Rn = (opCode >> 5) & 0x1f;
- Size = (opCode >> 30) & 0x3;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeMemEx64.cs b/ChocolArm64/Decoders/OpCodeMemEx64.cs
deleted file mode 100644
index 39935eb36e..0000000000
--- a/ChocolArm64/Decoders/OpCodeMemEx64.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeMemEx64 : OpCodeMem64
- {
- public int Rt2 { get; private set; }
- public int Rs { get; private set; }
-
- public OpCodeMemEx64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Rt2 = (opCode >> 10) & 0x1f;
- Rs = (opCode >> 16) & 0x1f;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeMemImm64.cs b/ChocolArm64/Decoders/OpCodeMemImm64.cs
deleted file mode 100644
index 01a62ef576..0000000000
--- a/ChocolArm64/Decoders/OpCodeMemImm64.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeMemImm64 : OpCodeMem64
- {
- public long Imm { get; protected set; }
- public bool WBack { get; protected set; }
- public bool PostIdx { get; protected set; }
- protected bool Unscaled { get; private set; }
-
- private enum MemOp
- {
- Unscaled = 0,
- PostIndexed = 1,
- Unprivileged = 2,
- PreIndexed = 3,
- Unsigned
- }
-
- public OpCodeMemImm64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Extend64 = ((opCode >> 22) & 3) == 2;
- WBack = ((opCode >> 24) & 1) == 0;
-
- // The type is not valid for the Unsigned Immediate 12-bits encoding,
- // because the bits 11:10 are used for the larger Immediate offset.
- MemOp type = WBack ? (MemOp)((opCode >> 10) & 3) : MemOp.Unsigned;
-
- PostIdx = type == MemOp.PostIndexed;
- Unscaled = type == MemOp.Unscaled ||
- type == MemOp.Unprivileged;
-
- // Unscaled and Unprivileged doesn't write back,
- // but they do use the 9-bits Signed Immediate.
- if (Unscaled)
- {
- WBack = false;
- }
-
- if (WBack || Unscaled)
- {
- // 9-bits Signed Immediate.
- Imm = (opCode << 11) >> 23;
- }
- else
- {
- // 12-bits Unsigned Immediate.
- Imm = ((opCode >> 10) & 0xfff) << Size;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeMemLit64.cs b/ChocolArm64/Decoders/OpCodeMemLit64.cs
deleted file mode 100644
index 29bfeee31f..0000000000
--- a/ChocolArm64/Decoders/OpCodeMemLit64.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeMemLit64 : OpCode64, IOpCodeLit64
- {
- public int Rt { get; private set; }
- public long Imm { get; private set; }
- public int Size { get; private set; }
- public bool Signed { get; private set; }
- public bool Prefetch { get; private set; }
-
- public OpCodeMemLit64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Rt = opCode & 0x1f;
-
- Imm = position + DecoderHelper.DecodeImmS19_2(opCode);
-
- switch ((opCode >> 30) & 3)
- {
- case 0: Size = 2; Signed = false; Prefetch = false; break;
- case 1: Size = 3; Signed = false; Prefetch = false; break;
- case 2: Size = 2; Signed = true; Prefetch = false; break;
- case 3: Size = 0; Signed = false; Prefetch = true; break;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeMemPair64.cs b/ChocolArm64/Decoders/OpCodeMemPair64.cs
deleted file mode 100644
index 5b81c75589..0000000000
--- a/ChocolArm64/Decoders/OpCodeMemPair64.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeMemPair64 : OpCodeMemImm64
- {
- public int Rt2 { get; private set; }
-
- public OpCodeMemPair64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Rt2 = (opCode >> 10) & 0x1f;
- WBack = ((opCode >> 23) & 0x1) != 0;
- PostIdx = ((opCode >> 23) & 0x3) == 1;
- Extend64 = ((opCode >> 30) & 0x3) == 1;
- Size = ((opCode >> 31) & 0x1) | 2;
-
- DecodeImm(opCode);
- }
-
- protected void DecodeImm(int opCode)
- {
- Imm = ((long)(opCode >> 15) << 57) >> (57 - Size);
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeMemReg64.cs b/ChocolArm64/Decoders/OpCodeMemReg64.cs
deleted file mode 100644
index 2eb734aa39..0000000000
--- a/ChocolArm64/Decoders/OpCodeMemReg64.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeMemReg64 : OpCodeMem64
- {
- public bool Shift { get; private set; }
- public int Rm { get; private set; }
-
- public IntType IntType { get; private set; }
-
- public OpCodeMemReg64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Shift = ((opCode >> 12) & 0x1) != 0;
- IntType = (IntType)((opCode >> 13) & 0x7);
- Rm = (opCode >> 16) & 0x1f;
- Extend64 = ((opCode >> 22) & 0x3) == 2;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeMov64.cs b/ChocolArm64/Decoders/OpCodeMov64.cs
deleted file mode 100644
index 7dbd92472b..0000000000
--- a/ChocolArm64/Decoders/OpCodeMov64.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeMov64 : OpCode64
- {
- public int Rd { get; private set; }
- public long Imm { get; private set; }
- public int Pos { get; private set; }
-
- public OpCodeMov64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- int p1 = (opCode >> 22) & 1;
- int sf = (opCode >> 31) & 1;
-
- if (sf == 0 && p1 != 0)
- {
- Emitter = InstEmit.Und;
-
- return;
- }
-
- Rd = (opCode >> 0) & 0x1f;
- Imm = (opCode >> 5) & 0xffff;
- Pos = (opCode >> 21) & 0x3;
-
- Pos <<= 4;
- Imm <<= Pos;
-
- RegisterSize = (opCode >> 31) != 0
- ? State.RegisterSize.Int64
- : State.RegisterSize.Int32;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeMul64.cs b/ChocolArm64/Decoders/OpCodeMul64.cs
deleted file mode 100644
index 176b7b93b5..0000000000
--- a/ChocolArm64/Decoders/OpCodeMul64.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeMul64 : OpCodeAlu64
- {
- public int Rm { get; private set; }
- public int Ra { get; private set; }
-
- public OpCodeMul64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Ra = (opCode >> 10) & 0x1f;
- Rm = (opCode >> 16) & 0x1f;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeSimd64.cs b/ChocolArm64/Decoders/OpCodeSimd64.cs
deleted file mode 100644
index a705e489cc..0000000000
--- a/ChocolArm64/Decoders/OpCodeSimd64.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using ChocolArm64.Instructions;
-using ChocolArm64.State;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeSimd64 : OpCode64, IOpCodeSimd64
- {
- public int Rd { get; private set; }
- public int Rn { get; private set; }
- public int Opc { get; private set; }
- public int Size { get; protected set; }
-
- public OpCodeSimd64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Rd = (opCode >> 0) & 0x1f;
- Rn = (opCode >> 5) & 0x1f;
- Opc = (opCode >> 15) & 0x3;
- Size = (opCode >> 22) & 0x3;
-
- RegisterSize = ((opCode >> 30) & 1) != 0
- ? RegisterSize.Simd128
- : RegisterSize.Simd64;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeSimdCvt64.cs b/ChocolArm64/Decoders/OpCodeSimdCvt64.cs
deleted file mode 100644
index 3181a85a34..0000000000
--- a/ChocolArm64/Decoders/OpCodeSimdCvt64.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeSimdCvt64 : OpCodeSimd64
- {
- public int FBits { get; private set; }
-
- public OpCodeSimdCvt64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- int scale = (opCode >> 10) & 0x3f;
- int sf = (opCode >> 31) & 0x1;
-
- FBits = 64 - scale;
-
- RegisterSize = sf != 0
- ? State.RegisterSize.Int64
- : State.RegisterSize.Int32;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeSimdExt64.cs b/ChocolArm64/Decoders/OpCodeSimdExt64.cs
deleted file mode 100644
index 1c57f19cc4..0000000000
--- a/ChocolArm64/Decoders/OpCodeSimdExt64.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeSimdExt64 : OpCodeSimdReg64
- {
- public int Imm4 { get; private set; }
-
- public OpCodeSimdExt64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Imm4 = (opCode >> 11) & 0xf;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeSimdFcond64.cs b/ChocolArm64/Decoders/OpCodeSimdFcond64.cs
deleted file mode 100644
index 47de231c2e..0000000000
--- a/ChocolArm64/Decoders/OpCodeSimdFcond64.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeSimdFcond64 : OpCodeSimdReg64, IOpCodeCond64
- {
- public int Nzcv { get; private set; }
-
- public Condition Cond { get; private set; }
-
- public OpCodeSimdFcond64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Nzcv = (opCode >> 0) & 0xf;
- Cond = (Condition)((opCode >> 12) & 0xf);
- }
- }
-}
diff --git a/ChocolArm64/Decoders/OpCodeSimdFmov64.cs b/ChocolArm64/Decoders/OpCodeSimdFmov64.cs
deleted file mode 100644
index 6752e185e5..0000000000
--- a/ChocolArm64/Decoders/OpCodeSimdFmov64.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeSimdFmov64 : OpCode64, IOpCodeSimd64
- {
- public int Rd { get; private set; }
- public long Imm { get; private set; }
- public int Size { get; private set; }
-
- public OpCodeSimdFmov64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- int imm5 = (opCode >> 5) & 0x1f;
- int type = (opCode >> 22) & 0x3;
-
- if (imm5 != 0b00000 || type > 1)
- {
- Emitter = InstEmit.Und;
-
- return;
- }
-
- Size = type;
-
- long imm;
-
- Rd = (opCode >> 0) & 0x1f;
- imm = (opCode >> 13) & 0xff;
-
- Imm = DecoderHelper.DecodeImm8Float(imm, type);
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeSimdImm64.cs b/ChocolArm64/Decoders/OpCodeSimdImm64.cs
deleted file mode 100644
index 27f586f108..0000000000
--- a/ChocolArm64/Decoders/OpCodeSimdImm64.cs
+++ /dev/null
@@ -1,100 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeSimdImm64 : OpCode64, IOpCodeSimd64
- {
- public int Rd { get; private set; }
- public long Imm { get; private set; }
- public int Size { get; private set; }
-
- public OpCodeSimdImm64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Rd = opCode & 0x1f;
-
- int cMode = (opCode >> 12) & 0xf;
- int op = (opCode >> 29) & 0x1;
-
- int modeLow = cMode & 1;
- int modeHigh = cMode >> 1;
-
- long imm;
-
- imm = ((uint)opCode >> 5) & 0x1f;
- imm |= ((uint)opCode >> 11) & 0xe0;
-
- if (modeHigh == 0b111)
- {
- Size = modeLow != 0 ? op : 3;
-
- switch (op | (modeLow << 1))
- {
- case 0:
- // 64-bits Immediate.
- // Transform abcd efgh into abcd efgh abcd efgh ...
- imm = (long)((ulong)imm * 0x0101010101010101);
- break;
-
- case 1:
- // 64-bits Immediate.
- // Transform abcd efgh into aaaa aaaa bbbb bbbb ...
- imm = (imm & 0xf0) >> 4 | (imm & 0x0f) << 4;
- imm = (imm & 0xcc) >> 2 | (imm & 0x33) << 2;
- imm = (imm & 0xaa) >> 1 | (imm & 0x55) << 1;
-
- imm = (long)((ulong)imm * 0x8040201008040201);
- imm = (long)((ulong)imm & 0x8080808080808080);
-
- imm |= imm >> 4;
- imm |= imm >> 2;
- imm |= imm >> 1;
- break;
-
- case 2:
- case 3:
- // Floating point Immediate.
- imm = DecoderHelper.DecodeImm8Float(imm, Size);
- break;
- }
- }
- else if ((modeHigh & 0b110) == 0b100)
- {
- // 16-bits shifted Immediate.
- Size = 1; imm <<= (modeHigh & 1) << 3;
- }
- else if ((modeHigh & 0b100) == 0b000)
- {
- // 32-bits shifted Immediate.
- Size = 2; imm <<= modeHigh << 3;
- }
- else if ((modeHigh & 0b111) == 0b110)
- {
- // 32-bits shifted Immediate (fill with ones).
- Size = 2; imm = ShlOnes(imm, 8 << modeLow);
- }
- else
- {
- // 8 bits without shift.
- Size = 0;
- }
-
- Imm = imm;
-
- RegisterSize = ((opCode >> 30) & 1) != 0
- ? State.RegisterSize.Simd128
- : State.RegisterSize.Simd64;
- }
-
- private static long ShlOnes(long value, int shift)
- {
- if (shift != 0)
- {
- return value << shift | (long)(ulong.MaxValue >> (64 - shift));
- }
- else
- {
- return value;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeSimdIns64.cs b/ChocolArm64/Decoders/OpCodeSimdIns64.cs
deleted file mode 100644
index 3b25faebfd..0000000000
--- a/ChocolArm64/Decoders/OpCodeSimdIns64.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeSimdIns64 : OpCodeSimd64
- {
- public int SrcIndex { get; private set; }
- public int DstIndex { get; private set; }
-
- public OpCodeSimdIns64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- int imm4 = (opCode >> 11) & 0xf;
- int imm5 = (opCode >> 16) & 0x1f;
-
- if (imm5 == 0b10000)
- {
- Emitter = InstEmit.Und;
-
- return;
- }
-
- Size = imm5 & -imm5;
-
- switch (Size)
- {
- case 1: Size = 0; break;
- case 2: Size = 1; break;
- case 4: Size = 2; break;
- case 8: Size = 3; break;
- }
-
- SrcIndex = imm4 >> Size;
- DstIndex = imm5 >> (Size + 1);
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeSimdMemImm64.cs b/ChocolArm64/Decoders/OpCodeSimdMemImm64.cs
deleted file mode 100644
index 9fbab5674f..0000000000
--- a/ChocolArm64/Decoders/OpCodeSimdMemImm64.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeSimdMemImm64 : OpCodeMemImm64, IOpCodeSimd64
- {
- public OpCodeSimdMemImm64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Size |= (opCode >> 21) & 4;
-
- if (!WBack && !Unscaled && Size >= 4)
- {
- Imm <<= 4;
- }
-
- Extend64 = false;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeSimdMemLit64.cs b/ChocolArm64/Decoders/OpCodeSimdMemLit64.cs
deleted file mode 100644
index c98ffd030b..0000000000
--- a/ChocolArm64/Decoders/OpCodeSimdMemLit64.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeSimdMemLit64 : OpCode64, IOpCodeSimd64, IOpCodeLit64
- {
- public int Rt { get; private set; }
- public long Imm { get; private set; }
- public int Size { get; private set; }
- public bool Signed => false;
- public bool Prefetch => false;
-
- public OpCodeSimdMemLit64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- int opc = (opCode >> 30) & 3;
-
- if (opc == 3)
- {
- Emitter = InstEmit.Und;
-
- return;
- }
-
- Rt = opCode & 0x1f;
-
- Imm = position + DecoderHelper.DecodeImmS19_2(opCode);
-
- Size = opc + 2;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeSimdMemMs64.cs b/ChocolArm64/Decoders/OpCodeSimdMemMs64.cs
deleted file mode 100644
index 83297c4146..0000000000
--- a/ChocolArm64/Decoders/OpCodeSimdMemMs64.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeSimdMemMs64 : OpCodeMemReg64, IOpCodeSimd64
- {
- public int Reps { get; private set; }
- public int SElems { get; private set; }
- public int Elems { get; private set; }
- public bool WBack { get; private set; }
-
- public OpCodeSimdMemMs64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- switch ((opCode >> 12) & 0xf)
- {
- case 0b0000: Reps = 1; SElems = 4; break;
- case 0b0010: Reps = 4; SElems = 1; break;
- case 0b0100: Reps = 1; SElems = 3; break;
- case 0b0110: Reps = 3; SElems = 1; break;
- case 0b0111: Reps = 1; SElems = 1; break;
- case 0b1000: Reps = 1; SElems = 2; break;
- case 0b1010: Reps = 2; SElems = 1; break;
-
- default: inst = Inst.Undefined; return;
- }
-
- Size = (opCode >> 10) & 3;
- WBack = ((opCode >> 23) & 1) != 0;
-
- bool q = ((opCode >> 30) & 1) != 0;
-
- if (!q && Size == 3 && SElems != 1)
- {
- inst = Inst.Undefined;
-
- return;
- }
-
- Extend64 = false;
-
- RegisterSize = q
- ? State.RegisterSize.Simd128
- : State.RegisterSize.Simd64;
-
- Elems = (GetBitsCount() >> 3) >> Size;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeSimdMemPair64.cs b/ChocolArm64/Decoders/OpCodeSimdMemPair64.cs
deleted file mode 100644
index 1b796742e3..0000000000
--- a/ChocolArm64/Decoders/OpCodeSimdMemPair64.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeSimdMemPair64 : OpCodeMemPair64, IOpCodeSimd64
- {
- public OpCodeSimdMemPair64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Size = ((opCode >> 30) & 3) + 2;
-
- Extend64 = false;
-
- DecodeImm(opCode);
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeSimdMemReg64.cs b/ChocolArm64/Decoders/OpCodeSimdMemReg64.cs
deleted file mode 100644
index 4ccbbed2da..0000000000
--- a/ChocolArm64/Decoders/OpCodeSimdMemReg64.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeSimdMemReg64 : OpCodeMemReg64, IOpCodeSimd64
- {
- public OpCodeSimdMemReg64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Size |= (opCode >> 21) & 4;
-
- Extend64 = false;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeSimdMemSs64.cs b/ChocolArm64/Decoders/OpCodeSimdMemSs64.cs
deleted file mode 100644
index 1b0ead3311..0000000000
--- a/ChocolArm64/Decoders/OpCodeSimdMemSs64.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeSimdMemSs64 : OpCodeMemReg64, IOpCodeSimd64
- {
- public int SElems { get; private set; }
- public int Index { get; private set; }
- public bool Replicate { get; private set; }
- public bool WBack { get; private set; }
-
- public OpCodeSimdMemSs64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- int size = (opCode >> 10) & 3;
- int s = (opCode >> 12) & 1;
- int sElems = (opCode >> 12) & 2;
- int scale = (opCode >> 14) & 3;
- int l = (opCode >> 22) & 1;
- int q = (opCode >> 30) & 1;
-
- sElems |= (opCode >> 21) & 1;
-
- sElems++;
-
- int index = (q << 3) | (s << 2) | size;
-
- switch (scale)
- {
- case 1:
- {
- if ((size & 1) != 0)
- {
- inst = Inst.Undefined;
-
- return;
- }
-
- index >>= 1;
-
- break;
- }
-
- case 2:
- {
- if ((size & 2) != 0 ||
- ((size & 1) != 0 && s != 0))
- {
- inst = Inst.Undefined;
-
- return;
- }
-
- if ((size & 1) != 0)
- {
- index >>= 3;
-
- scale = 3;
- }
- else
- {
- index >>= 2;
- }
-
- break;
- }
-
- case 3:
- {
- if (l == 0 || s != 0)
- {
- inst = Inst.Undefined;
-
- return;
- }
-
- scale = size;
-
- Replicate = true;
-
- break;
- }
- }
-
- Index = index;
- SElems = sElems;
- Size = scale;
-
- Extend64 = false;
-
- WBack = ((opCode >> 23) & 1) != 0;
-
- RegisterSize = q != 0
- ? State.RegisterSize.Simd128
- : State.RegisterSize.Simd64;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeSimdReg64.cs b/ChocolArm64/Decoders/OpCodeSimdReg64.cs
deleted file mode 100644
index 4bf462dee4..0000000000
--- a/ChocolArm64/Decoders/OpCodeSimdReg64.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeSimdReg64 : OpCodeSimd64
- {
- public bool Bit3 { get; private set; }
- public int Ra { get; private set; }
- public int Rm { get; protected set; }
-
- public OpCodeSimdReg64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Bit3 = ((opCode >> 3) & 0x1) != 0;
- Ra = (opCode >> 10) & 0x1f;
- Rm = (opCode >> 16) & 0x1f;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeSimdRegElem64.cs b/ChocolArm64/Decoders/OpCodeSimdRegElem64.cs
deleted file mode 100644
index 04e9586199..0000000000
--- a/ChocolArm64/Decoders/OpCodeSimdRegElem64.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeSimdRegElem64 : OpCodeSimdReg64
- {
- public int Index { get; private set; }
-
- public OpCodeSimdRegElem64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- switch (Size)
- {
- case 1:
- Index = (opCode >> 20) & 3 |
- (opCode >> 9) & 4;
-
- Rm &= 0xf;
-
- break;
-
- case 2:
- Index = (opCode >> 21) & 1 |
- (opCode >> 10) & 2;
-
- break;
-
- default: Emitter = InstEmit.Und; return;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeSimdRegElemF64.cs b/ChocolArm64/Decoders/OpCodeSimdRegElemF64.cs
deleted file mode 100644
index b5db7345ca..0000000000
--- a/ChocolArm64/Decoders/OpCodeSimdRegElemF64.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeSimdRegElemF64 : OpCodeSimdReg64
- {
- public int Index { get; private set; }
-
- public OpCodeSimdRegElemF64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- switch ((opCode >> 21) & 3) // sz:L
- {
- case 0: // H:0
- Index = (opCode >> 10) & 2; // 0, 2
-
- break;
-
- case 1: // H:1
- Index = (opCode >> 10) & 2;
- Index++; // 1, 3
-
- break;
-
- case 2: // H
- Index = (opCode >> 11) & 1; // 0, 1
-
- break;
-
- default: Emitter = InstEmit.Und; return;
- }
- }
- }
-}
diff --git a/ChocolArm64/Decoders/OpCodeSimdShImm64.cs b/ChocolArm64/Decoders/OpCodeSimdShImm64.cs
deleted file mode 100644
index d4cd88d13b..0000000000
--- a/ChocolArm64/Decoders/OpCodeSimdShImm64.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeSimdShImm64 : OpCodeSimd64
- {
- public int Imm { get; private set; }
-
- public OpCodeSimdShImm64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Imm = (opCode >> 16) & 0x7f;
-
- Size = BitUtils.HighestBitSetNibble(Imm >> 3);
- }
- }
-}
diff --git a/ChocolArm64/Decoders/OpCodeSimdTbl64.cs b/ChocolArm64/Decoders/OpCodeSimdTbl64.cs
deleted file mode 100644
index 13cc9090f5..0000000000
--- a/ChocolArm64/Decoders/OpCodeSimdTbl64.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeSimdTbl64 : OpCodeSimdReg64
- {
- public OpCodeSimdTbl64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Size = ((opCode >> 13) & 3) + 1;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeSystem64.cs b/ChocolArm64/Decoders/OpCodeSystem64.cs
deleted file mode 100644
index 41c51565d9..0000000000
--- a/ChocolArm64/Decoders/OpCodeSystem64.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeSystem64 : OpCode64
- {
- public int Rt { get; private set; }
- public int Op2 { get; private set; }
- public int CRm { get; private set; }
- public int CRn { get; private set; }
- public int Op1 { get; private set; }
- public int Op0 { get; private set; }
-
- public OpCodeSystem64(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Rt = (opCode >> 0) & 0x1f;
- Op2 = (opCode >> 5) & 0x7;
- CRm = (opCode >> 8) & 0xf;
- CRn = (opCode >> 12) & 0xf;
- Op1 = (opCode >> 16) & 0x7;
- Op0 = ((opCode >> 19) & 0x1) | 2;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeT16.cs b/ChocolArm64/Decoders/OpCodeT16.cs
deleted file mode 100644
index 005c470d1a..0000000000
--- a/ChocolArm64/Decoders/OpCodeT16.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeT16 : OpCode32
- {
- public OpCodeT16(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Cond = Condition.Al;
-
- OpCodeSizeInBytes = 2;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeT16AluImm8.cs b/ChocolArm64/Decoders/OpCodeT16AluImm8.cs
deleted file mode 100644
index 52c059f40e..0000000000
--- a/ChocolArm64/Decoders/OpCodeT16AluImm8.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeT16AluImm8 : OpCodeT16, IOpCode32Alu
- {
- private int _rdn;
-
- public int Rd => _rdn;
- public int Rn => _rdn;
-
- public bool SetFlags => false;
-
- public int Imm { get; private set; }
-
- public OpCodeT16AluImm8(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Imm = (opCode >> 0) & 0xff;
- _rdn = (opCode >> 8) & 0x7;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeT16BReg.cs b/ChocolArm64/Decoders/OpCodeT16BReg.cs
deleted file mode 100644
index 2951470055..0000000000
--- a/ChocolArm64/Decoders/OpCodeT16BReg.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using ChocolArm64.Instructions;
-
-namespace ChocolArm64.Decoders
-{
- class OpCodeT16BReg : OpCodeT16, IOpCode32BReg
- {
- public int Rm { get; private set; }
-
- public OpCodeT16BReg(Inst inst, long position, int opCode) : base(inst, position, opCode)
- {
- Rm = (opCode >> 3) & 0xf;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/ShiftType.cs b/ChocolArm64/Decoders/ShiftType.cs
deleted file mode 100644
index cad4310346..0000000000
--- a/ChocolArm64/Decoders/ShiftType.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace ChocolArm64.Decoders
-{
- enum ShiftType
- {
- Lsl = 0,
- Lsr = 1,
- Asr = 2,
- Ror = 3
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Events/CpuTraceEventArgs.cs b/ChocolArm64/Events/CpuTraceEventArgs.cs
deleted file mode 100644
index c12781ed86..0000000000
--- a/ChocolArm64/Events/CpuTraceEventArgs.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-
-namespace ChocolArm64.Events
-{
- public class CpuTraceEventArgs : EventArgs
- {
- public long Position { get; private set; }
-
- public CpuTraceEventArgs(long position)
- {
- Position = position;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Events/InstExceptionEventArgs.cs b/ChocolArm64/Events/InstExceptionEventArgs.cs
deleted file mode 100644
index e3cc0ba0e0..0000000000
--- a/ChocolArm64/Events/InstExceptionEventArgs.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-
-namespace ChocolArm64.Events
-{
- public class InstExceptionEventArgs : EventArgs
- {
- public long Position { get; private set; }
- public int Id { get; private set; }
-
- public InstExceptionEventArgs(long position, int id)
- {
- Position = position;
- Id = id;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Events/InstUndefinedEventArgs.cs b/ChocolArm64/Events/InstUndefinedEventArgs.cs
deleted file mode 100644
index 3ad7ea8b9e..0000000000
--- a/ChocolArm64/Events/InstUndefinedEventArgs.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-
-namespace ChocolArm64.Events
-{
- public class InstUndefinedEventArgs : EventArgs
- {
- public long Position { get; private set; }
- public int RawOpCode { get; private set; }
-
- public InstUndefinedEventArgs(long position, int rawOpCode)
- {
- Position = position;
- RawOpCode = rawOpCode;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Instructions/CryptoHelper.cs b/ChocolArm64/Instructions/CryptoHelper.cs
deleted file mode 100644
index e9b6ed5fb2..0000000000
--- a/ChocolArm64/Instructions/CryptoHelper.cs
+++ /dev/null
@@ -1,331 +0,0 @@
-// https://www.intel.com/content/dam/doc/white-paper/advanced-encryption-standard-new-instructions-set-paper.pdf
-
-using System;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace ChocolArm64.Instructions
-{
- static class CryptoHelper
- {
-#region "LookUp Tables"
- private static readonly byte[] _sBox = new byte[]
- {
- 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
- 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
- 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
- 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
- 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
- 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
- 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
- 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
- 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
- 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
- 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
- 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
- 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
- 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
- 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
- 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
- };
-
- private static readonly byte[] _invSBox = new byte[]
- {
- 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
- 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
- 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
- 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
- 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
- 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
- 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
- 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
- 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
- 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
- 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
- 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
- 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
- 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
- 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
- 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
- };
-
- private static readonly byte[] _gfMul02 = new byte[]
- {
- 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
- 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
- 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
- 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
- 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
- 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
- 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
- 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
- 0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
- 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25,
- 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45,
- 0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
- 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
- 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
- 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
- 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5
- };
-
- private static readonly byte[] _gfMul03 = new byte[]
- {
- 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
- 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
- 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
- 0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41,
- 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1,
- 0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
- 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1,
- 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81,
- 0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
- 0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba,
- 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea,
- 0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
- 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a,
- 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a,
- 0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
- 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a
- };
-
- private static readonly byte[] _gfMul09 = new byte[]
- {
- 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
- 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
- 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
- 0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc,
- 0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01,
- 0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
- 0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a,
- 0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa,
- 0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
- 0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b,
- 0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0,
- 0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
- 0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed,
- 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d,
- 0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
- 0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46
- };
-
- private static readonly byte[] _gfMul0B = new byte[]
- {
- 0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
- 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
- 0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
- 0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2,
- 0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f,
- 0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
- 0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4,
- 0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54,
- 0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
- 0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e,
- 0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5,
- 0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
- 0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68,
- 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8,
- 0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
- 0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3
- };
-
- private static readonly byte[] _gfMul0D = new byte[]
- {
- 0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
- 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
- 0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
- 0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20,
- 0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26,
- 0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
- 0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d,
- 0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d,
- 0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
- 0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41,
- 0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a,
- 0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
- 0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc,
- 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c,
- 0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
- 0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97
- };
-
- private static readonly byte[] _gfMul0E = new byte[]
- {
- 0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
- 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
- 0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
- 0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61,
- 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7,
- 0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
- 0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c,
- 0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc,
- 0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
- 0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb,
- 0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0,
- 0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
- 0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6,
- 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56,
- 0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
- 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d
- };
-
- private static readonly byte[] _srPerm = new byte[]
- {
- 0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3
- };
-
- private static readonly byte[] _isrPerm = new byte[]
- {
- 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11
- };
-#endregion
-
- public static Vector128 AesInvMixColumns(Vector128 op)
- {
- byte[] inState = new byte[16];
- byte[] outState = new byte[16];
-
- FromVectorToByteArray(op, inState);
-
- for (int columns = 0; columns <= 3; columns++)
- {
- int idx = columns << 2;
-
- byte row0 = inState[idx + 0]; // A, E, I, M: [row0, col0-col3]
- byte row1 = inState[idx + 1]; // B, F, J, N: [row1, col0-col3]
- byte row2 = inState[idx + 2]; // C, G, K, O: [row2, col0-col3]
- byte row3 = inState[idx + 3]; // D, H, L, P: [row3, col0-col3]
-
- outState[idx + 0] = (byte)((uint)_gfMul0E[row0] ^ _gfMul0B[row1] ^ _gfMul0D[row2] ^ _gfMul09[row3]);
- outState[idx + 1] = (byte)((uint)_gfMul09[row0] ^ _gfMul0E[row1] ^ _gfMul0B[row2] ^ _gfMul0D[row3]);
- outState[idx + 2] = (byte)((uint)_gfMul0D[row0] ^ _gfMul09[row1] ^ _gfMul0E[row2] ^ _gfMul0B[row3]);
- outState[idx + 3] = (byte)((uint)_gfMul0B[row0] ^ _gfMul0D[row1] ^ _gfMul09[row2] ^ _gfMul0E[row3]);
- }
-
- FromByteArrayToVector(outState, ref op);
-
- return op;
- }
-
- public static Vector128 AesInvShiftRows(Vector128 op)
- {
- byte[] inState = new byte[16];
- byte[] outState = new byte[16];
-
- FromVectorToByteArray(op, inState);
-
- for (int idx = 0; idx <= 15; idx++)
- {
- outState[_isrPerm[idx]] = inState[idx];
- }
-
- FromByteArrayToVector(outState, ref op);
-
- return op;
- }
-
- public static Vector128 AesInvSubBytes(Vector128 op)
- {
- byte[] inState = new byte[16];
- byte[] outState = new byte[16];
-
- FromVectorToByteArray(op, inState);
-
- for (int idx = 0; idx <= 15; idx++)
- {
- outState[idx] = _invSBox[inState[idx]];
- }
-
- FromByteArrayToVector(outState, ref op);
-
- return op;
- }
-
- public static Vector128 AesMixColumns(Vector128 op)
- {
- byte[] inState = new byte[16];
- byte[] outState = new byte[16];
-
- FromVectorToByteArray(op, inState);
-
- for (int columns = 0; columns <= 3; columns++)
- {
- int idx = columns << 2;
-
- byte row0 = inState[idx + 0]; // A, E, I, M: [row0, col0-col3]
- byte row1 = inState[idx + 1]; // B, F, J, N: [row1, col0-col3]
- byte row2 = inState[idx + 2]; // C, G, K, O: [row2, col0-col3]
- byte row3 = inState[idx + 3]; // D, H, L, P: [row3, col0-col3]
-
- outState[idx + 0] = (byte)((uint)_gfMul02[row0] ^ _gfMul03[row1] ^ row2 ^ row3);
- outState[idx + 1] = (byte)((uint)row0 ^ _gfMul02[row1] ^ _gfMul03[row2] ^ row3);
- outState[idx + 2] = (byte)((uint)row0 ^ row1 ^ _gfMul02[row2] ^ _gfMul03[row3]);
- outState[idx + 3] = (byte)((uint)_gfMul03[row0] ^ row1 ^ row2 ^ _gfMul02[row3]);
- }
-
- FromByteArrayToVector(outState, ref op);
-
- return op;
- }
-
- public static Vector128 AesShiftRows(Vector128 op)
- {
- byte[] inState = new byte[16];
- byte[] outState = new byte[16];
-
- FromVectorToByteArray(op, inState);
-
- for (int idx = 0; idx <= 15; idx++)
- {
- outState[_srPerm[idx]] = inState[idx];
- }
-
- FromByteArrayToVector(outState, ref op);
-
- return op;
- }
-
- public static Vector128 AesSubBytes(Vector128 op)
- {
- byte[] inState = new byte[16];
- byte[] outState = new byte[16];
-
- FromVectorToByteArray(op, inState);
-
- for (int idx = 0; idx <= 15; idx++)
- {
- outState[idx] = _sBox[inState[idx]];
- }
-
- FromByteArrayToVector(outState, ref op);
-
- return op;
- }
-
- private unsafe static void FromVectorToByteArray(Vector128 op, byte[] state)
- {
- if (!Sse2.IsSupported)
- {
- throw new PlatformNotSupportedException();
- }
-
- fixed (byte* ptr = &state[0])
- {
- Sse2.Store(ptr, Sse.StaticCast(op));
- }
- }
-
- private unsafe static void FromByteArrayToVector(byte[] state, ref Vector128 op)
- {
- if (!Sse2.IsSupported)
- {
- throw new PlatformNotSupportedException();
- }
-
- fixed (byte* ptr = &state[0])
- {
- op = Sse.StaticCast(Sse2.LoadVector128(ptr));
- }
- }
- }
-}
diff --git a/ChocolArm64/Instructions/Inst.cs b/ChocolArm64/Instructions/Inst.cs
deleted file mode 100644
index de9ec18b7a..0000000000
--- a/ChocolArm64/Instructions/Inst.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System;
-
-namespace ChocolArm64.Instructions
-{
- struct Inst
- {
- public InstEmitter Emitter { get; }
- public Type Type { get; }
-
- public static Inst Undefined => new Inst(InstEmit.Und, null);
-
- public Inst(InstEmitter emitter, Type type)
- {
- Emitter = emitter;
- Type = type;
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Instructions/InstEmit32Helper.cs b/ChocolArm64/Instructions/InstEmit32Helper.cs
deleted file mode 100644
index c5d08b8aee..0000000000
--- a/ChocolArm64/Instructions/InstEmit32Helper.cs
+++ /dev/null
@@ -1,146 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.IntermediateRepresentation;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System;
-using System.Reflection.Emit;
-
-namespace ChocolArm64.Instructions
-{
- static class InstEmit32Helper
- {
- public static bool IsThumb(OpCode64 op)
- {
- return op is OpCodeT16;
- }
-
- public static void EmitLoadFromRegister(ILEmitterCtx context, int register)
- {
- if (register == RegisterAlias.Aarch32Pc)
- {
- OpCode32 op = (OpCode32)context.CurrOp;
-
- context.EmitLdc_I4((int)op.GetPc());
- }
- else
- {
- context.EmitLdint(GetRegisterAlias(context.Mode, register));
- }
- }
-
- public static void EmitStoreToRegister(ILEmitterCtx context, int register)
- {
- if (register == RegisterAlias.Aarch32Pc)
- {
- context.EmitStoreContext();
-
- EmitBxWritePc(context);
- }
- else
- {
- context.EmitStint(GetRegisterAlias(context.Mode, register));
- }
- }
-
- public static void EmitBxWritePc(ILEmitterCtx context)
- {
- context.Emit(OpCodes.Dup);
-
- context.EmitLdc_I4(1);
-
- context.Emit(OpCodes.And);
- context.Emit(OpCodes.Dup);
-
- context.EmitStflg((int)PState.TBit);
-
- ILLabel lblArmMode = new ILLabel();
- ILLabel lblEnd = new ILLabel();
-
- context.Emit(OpCodes.Brtrue_S, lblArmMode);
-
- context.EmitLdc_I4(~1);
-
- context.Emit(OpCodes.Br_S, lblEnd);
-
- context.MarkLabel(lblArmMode);
-
- context.EmitLdc_I4(~3);
-
- context.MarkLabel(lblEnd);
-
- context.Emit(OpCodes.And);
- context.Emit(OpCodes.Conv_U8);
- context.Emit(OpCodes.Ret);
- }
-
- public static int GetRegisterAlias(Aarch32Mode mode, int register)
- {
- //Only registers >= 8 are banked, with registers in the range [8, 12] being
- //banked for the FIQ mode, and registers 13 and 14 being banked for all modes.
- if ((uint)register < 8)
- {
- return register;
- }
-
- return GetBankedRegisterAlias(mode, register);
- }
-
- public static int GetBankedRegisterAlias(Aarch32Mode mode, int register)
- {
- switch (register)
- {
- case 8: return mode == Aarch32Mode.Fiq
- ? RegisterAlias.R8Fiq
- : RegisterAlias.R8Usr;
-
- case 9: return mode == Aarch32Mode.Fiq
- ? RegisterAlias.R9Fiq
- : RegisterAlias.R9Usr;
-
- case 10: return mode == Aarch32Mode.Fiq
- ? RegisterAlias.R10Fiq
- : RegisterAlias.R10Usr;
-
- case 11: return mode == Aarch32Mode.Fiq
- ? RegisterAlias.R11Fiq
- : RegisterAlias.R11Usr;
-
- case 12: return mode == Aarch32Mode.Fiq
- ? RegisterAlias.R12Fiq
- : RegisterAlias.R12Usr;
-
- case 13:
- switch (mode)
- {
- case Aarch32Mode.User:
- case Aarch32Mode.System: return RegisterAlias.SpUsr;
- case Aarch32Mode.Fiq: return RegisterAlias.SpFiq;
- case Aarch32Mode.Irq: return RegisterAlias.SpIrq;
- case Aarch32Mode.Supervisor: return RegisterAlias.SpSvc;
- case Aarch32Mode.Abort: return RegisterAlias.SpAbt;
- case Aarch32Mode.Hypervisor: return RegisterAlias.SpHyp;
- case Aarch32Mode.Undefined: return RegisterAlias.SpUnd;
-
- default: throw new ArgumentException(nameof(mode));
- }
-
- case 14:
- switch (mode)
- {
- case Aarch32Mode.User:
- case Aarch32Mode.Hypervisor:
- case Aarch32Mode.System: return RegisterAlias.LrUsr;
- case Aarch32Mode.Fiq: return RegisterAlias.LrFiq;
- case Aarch32Mode.Irq: return RegisterAlias.LrIrq;
- case Aarch32Mode.Supervisor: return RegisterAlias.LrSvc;
- case Aarch32Mode.Abort: return RegisterAlias.LrAbt;
- case Aarch32Mode.Undefined: return RegisterAlias.LrUnd;
-
- default: throw new ArgumentException(nameof(mode));
- }
-
- default: throw new ArgumentOutOfRangeException(nameof(register));
- }
- }
- }
-}
diff --git a/ChocolArm64/Instructions/InstEmitAlu.cs b/ChocolArm64/Instructions/InstEmitAlu.cs
deleted file mode 100644
index 25bd8e6471..0000000000
--- a/ChocolArm64/Instructions/InstEmitAlu.cs
+++ /dev/null
@@ -1,422 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.IntermediateRepresentation;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System;
-using System.Reflection;
-using System.Reflection.Emit;
-using System.Runtime.Intrinsics.X86;
-
-using static ChocolArm64.Instructions.InstEmitAluHelper;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
- public static void Adc(ILEmitterCtx context) => EmitAdc(context, false);
- public static void Adcs(ILEmitterCtx context) => EmitAdc(context, true);
-
- private static void EmitAdc(ILEmitterCtx context, bool setFlags)
- {
- EmitAluLoadOpers(context);
-
- context.Emit(OpCodes.Add);
-
- context.EmitLdflg((int)PState.CBit);
-
- Type[] mthdTypes = new Type[] { typeof(bool) };
-
- MethodInfo mthdInfo = typeof(Convert).GetMethod(nameof(Convert.ToInt32), mthdTypes);
-
- context.EmitCall(mthdInfo);
-
- if (context.CurrOp.RegisterSize != RegisterSize.Int32)
- {
- context.Emit(OpCodes.Conv_U8);
- }
-
- context.Emit(OpCodes.Add);
-
- if (setFlags)
- {
- context.EmitZnFlagCheck();
-
- EmitAdcsCCheck(context);
- EmitAddsVCheck(context);
- }
-
- EmitAluStore(context);
- }
-
- public static void Add(ILEmitterCtx context) => EmitAluOp(context, OpCodes.Add);
-
- public static void Adds(ILEmitterCtx context)
- {
- context.TryOptMarkCondWithoutCmp();
-
- EmitAluLoadOpers(context);
-
- context.Emit(OpCodes.Add);
-
- context.EmitZnFlagCheck();
-
- EmitAddsCCheck(context);
- EmitAddsVCheck(context);
- EmitAluStoreS(context);
- }
-
- public static void And(ILEmitterCtx context) => EmitAluOp(context, OpCodes.And);
-
- public static void Ands(ILEmitterCtx context)
- {
- EmitAluLoadOpers(context);
-
- context.Emit(OpCodes.And);
-
- EmitZeroCvFlags(context);
-
- context.EmitZnFlagCheck();
-
- EmitAluStoreS(context);
- }
-
- public static void Asrv(ILEmitterCtx context) => EmitAluOpShift(context, OpCodes.Shr);
-
- public static void Bic(ILEmitterCtx context) => EmitBic(context, false);
- public static void Bics(ILEmitterCtx context) => EmitBic(context, true);
-
- private static void EmitBic(ILEmitterCtx context, bool setFlags)
- {
- EmitAluLoadOpers(context);
-
- context.Emit(OpCodes.Not);
- context.Emit(OpCodes.And);
-
- if (setFlags)
- {
- EmitZeroCvFlags(context);
-
- context.EmitZnFlagCheck();
- }
-
- EmitAluStore(context, setFlags);
- }
-
- public static void Cls(ILEmitterCtx context)
- {
- OpCodeAlu64 op = (OpCodeAlu64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
-
- context.EmitLdc_I4(op.RegisterSize == RegisterSize.Int32 ? 32 : 64);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.CountLeadingSigns));
-
- context.EmitStintzr(op.Rd);
- }
-
- public static void Clz(ILEmitterCtx context)
- {
- OpCodeAlu64 op = (OpCodeAlu64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
-
- if (Lzcnt.IsSupported)
- {
- Type tValue = op.RegisterSize == RegisterSize.Int32 ? typeof(uint) : typeof(ulong);
-
- context.EmitCall(typeof(Lzcnt).GetMethod(nameof(Lzcnt.LeadingZeroCount), new Type[] { tValue }));
- }
- else
- {
- context.EmitLdc_I4(op.RegisterSize == RegisterSize.Int32 ? 32 : 64);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.CountLeadingZeros));
- }
-
- context.EmitStintzr(op.Rd);
- }
-
- public static void Eon(ILEmitterCtx context)
- {
- EmitAluLoadOpers(context);
-
- context.Emit(OpCodes.Not);
- context.Emit(OpCodes.Xor);
-
- EmitAluStore(context);
- }
-
- public static void Eor(ILEmitterCtx context) => EmitAluOp(context, OpCodes.Xor);
-
- public static void Extr(ILEmitterCtx context)
- {
- // TODO: Ensure that the Shift is valid for the Is64Bits.
- OpCodeAluRs64 op = (OpCodeAluRs64)context.CurrOp;
-
- context.EmitLdintzr(op.Rm);
-
- if (op.Shift > 0)
- {
- context.EmitLdc_I4(op.Shift);
-
- context.Emit(OpCodes.Shr_Un);
-
- context.EmitLdintzr(op.Rn);
- context.EmitLdc_I4(op.GetBitsCount() - op.Shift);
-
- context.Emit(OpCodes.Shl);
- context.Emit(OpCodes.Or);
- }
-
- EmitAluStore(context);
- }
-
- public static void Lslv(ILEmitterCtx context) => EmitAluOpShift(context, OpCodes.Shl);
- public static void Lsrv(ILEmitterCtx context) => EmitAluOpShift(context, OpCodes.Shr_Un);
-
- public static void Sbc(ILEmitterCtx context) => EmitSbc(context, false);
- public static void Sbcs(ILEmitterCtx context) => EmitSbc(context, true);
-
- private static void EmitSbc(ILEmitterCtx context, bool setFlags)
- {
- EmitAluLoadOpers(context);
-
- context.Emit(OpCodes.Sub);
-
- context.EmitLdflg((int)PState.CBit);
-
- Type[] mthdTypes = new Type[] { typeof(bool) };
-
- MethodInfo mthdInfo = typeof(Convert).GetMethod(nameof(Convert.ToInt32), mthdTypes);
-
- context.EmitCall(mthdInfo);
-
- context.EmitLdc_I4(1);
-
- context.Emit(OpCodes.Xor);
-
- if (context.CurrOp.RegisterSize != RegisterSize.Int32)
- {
- context.Emit(OpCodes.Conv_U8);
- }
-
- context.Emit(OpCodes.Sub);
-
- if (setFlags)
- {
- context.EmitZnFlagCheck();
-
- EmitSbcsCCheck(context);
- EmitSubsVCheck(context);
- }
-
- EmitAluStore(context);
- }
-
- public static void Sub(ILEmitterCtx context) => EmitAluOp(context, OpCodes.Sub);
-
- public static void Subs(ILEmitterCtx context)
- {
- context.TryOptMarkCondWithoutCmp();
-
- EmitAluLoadOpers(context);
-
- context.Emit(OpCodes.Sub);
-
- context.EmitZnFlagCheck();
-
- EmitSubsCCheck(context);
- EmitSubsVCheck(context);
- EmitAluStoreS(context);
- }
-
- public static void Orn(ILEmitterCtx context)
- {
- EmitAluLoadOpers(context);
-
- context.Emit(OpCodes.Not);
- context.Emit(OpCodes.Or);
-
- EmitAluStore(context);
- }
-
- public static void Orr(ILEmitterCtx context) => EmitAluOp(context, OpCodes.Or);
-
- public static void Rbit(ILEmitterCtx context) => EmitFallback32_64(context,
- nameof(SoftFallback.ReverseBits32),
- nameof(SoftFallback.ReverseBits64));
-
- public static void Rev16(ILEmitterCtx context) => EmitFallback32_64(context,
- nameof(SoftFallback.ReverseBytes16_32),
- nameof(SoftFallback.ReverseBytes16_64));
-
- public static void Rev32(ILEmitterCtx context) => EmitFallback32_64(context,
- nameof(SoftFallback.ReverseBytes32_32),
- nameof(SoftFallback.ReverseBytes32_64));
-
- private static void EmitFallback32_64(ILEmitterCtx context, string name32, string name64)
- {
- OpCodeAlu64 op = (OpCodeAlu64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
-
- if (op.RegisterSize == RegisterSize.Int32)
- {
- SoftFallback.EmitCall(context, name32);
- }
- else
- {
- SoftFallback.EmitCall(context, name64);
- }
-
- context.EmitStintzr(op.Rd);
- }
-
- public static void Rev64(ILEmitterCtx context)
- {
- OpCodeAlu64 op = (OpCodeAlu64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.ReverseBytes64));
-
- context.EmitStintzr(op.Rd);
- }
-
- public static void Rorv(ILEmitterCtx context)
- {
- EmitAluLoadRn(context);
- EmitAluLoadShift(context);
-
- context.Emit(OpCodes.Shr_Un);
-
- EmitAluLoadRn(context);
-
- context.EmitLdc_I4(context.CurrOp.GetBitsCount());
-
- EmitAluLoadShift(context);
-
- context.Emit(OpCodes.Sub);
- context.Emit(OpCodes.Shl);
- context.Emit(OpCodes.Or);
-
- EmitAluStore(context);
- }
-
- public static void Sdiv(ILEmitterCtx context) => EmitDiv(context, OpCodes.Div);
- public static void Udiv(ILEmitterCtx context) => EmitDiv(context, OpCodes.Div_Un);
-
- private static void EmitDiv(ILEmitterCtx context, OpCode ilOp)
- {
- // If Rm == 0, Rd = 0 (division by zero).
- context.EmitLdc_I(0);
-
- EmitAluLoadRm(context);
-
- context.EmitLdc_I(0);
-
- ILLabel badDiv = new ILLabel();
-
- context.Emit(OpCodes.Beq_S, badDiv);
- context.Emit(OpCodes.Pop);
-
- if (ilOp == OpCodes.Div)
- {
- // If Rn == INT_MIN && Rm == -1, Rd = INT_MIN (overflow).
- long intMin = 1L << (context.CurrOp.GetBitsCount() - 1);
-
- context.EmitLdc_I(intMin);
-
- EmitAluLoadRn(context);
-
- context.EmitLdc_I(intMin);
-
- context.Emit(OpCodes.Ceq);
-
- EmitAluLoadRm(context);
-
- context.EmitLdc_I(-1);
-
- context.Emit(OpCodes.Ceq);
- context.Emit(OpCodes.And);
- context.Emit(OpCodes.Brtrue_S, badDiv);
- context.Emit(OpCodes.Pop);
- }
-
- EmitAluLoadRn(context);
- EmitAluLoadRm(context);
-
- context.Emit(ilOp);
-
- context.MarkLabel(badDiv);
-
- EmitAluStore(context);
- }
-
- private static void EmitAluOp(ILEmitterCtx context, OpCode ilOp)
- {
- EmitAluLoadOpers(context);
-
- context.Emit(ilOp);
-
- EmitAluStore(context);
- }
-
- private static void EmitAluOpShift(ILEmitterCtx context, OpCode ilOp)
- {
- EmitAluLoadRn(context);
- EmitAluLoadShift(context);
-
- context.Emit(ilOp);
-
- EmitAluStore(context);
- }
-
- private static void EmitAluLoadShift(ILEmitterCtx context)
- {
- EmitAluLoadRm(context);
-
- context.EmitLdc_I(context.CurrOp.GetBitsCount() - 1);
-
- context.Emit(OpCodes.And);
-
- // Note: Only 32-bits shift values are valid, so when the value is 64-bits
- // we need to cast it to a 32-bits integer. This is fine because we
- // AND the value and only keep the lower 5 or 6 bits anyway -- it
- // could very well fit on a byte.
- if (context.CurrOp.RegisterSize != RegisterSize.Int32)
- {
- context.Emit(OpCodes.Conv_I4);
- }
- }
-
- private static void EmitZeroCvFlags(ILEmitterCtx context)
- {
- context.EmitLdc_I4(0);
-
- context.EmitStflg((int)PState.VBit);
-
- context.EmitLdc_I4(0);
-
- context.EmitStflg((int)PState.CBit);
- }
-
- public static void EmitAluStore(ILEmitterCtx context) => EmitAluStore(context, false);
- public static void EmitAluStoreS(ILEmitterCtx context) => EmitAluStore(context, true);
-
- public static void EmitAluStore(ILEmitterCtx context, bool setFlags)
- {
- IOpCodeAlu64 op = (IOpCodeAlu64)context.CurrOp;
-
- if (setFlags || op is IOpCodeAluRs64)
- {
- context.EmitStintzr(op.Rd);
- }
- else
- {
- context.EmitStint(op.Rd);
- }
- }
- }
-}
diff --git a/ChocolArm64/Instructions/InstEmitAlu32.cs b/ChocolArm64/Instructions/InstEmitAlu32.cs
deleted file mode 100644
index 94a8c750d1..0000000000
--- a/ChocolArm64/Instructions/InstEmitAlu32.cs
+++ /dev/null
@@ -1,142 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.IntermediateRepresentation;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System.Reflection.Emit;
-
-using static ChocolArm64.Instructions.InstEmit32Helper;
-using static ChocolArm64.Instructions.InstEmitAluHelper;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit32
- {
- public static void Add(ILEmitterCtx context)
- {
- IOpCode32Alu op = (IOpCode32Alu)context.CurrOp;
-
- EmitAluLoadOpers(context, setCarry: false);
-
- context.Emit(OpCodes.Add);
-
- if (op.SetFlags)
- {
- context.EmitZnFlagCheck();
-
- EmitAddsCCheck(context);
- EmitAddsVCheck(context);
- }
-
- EmitAluStore(context);
- }
-
- public static void Cmp(ILEmitterCtx context)
- {
- IOpCode32Alu op = (IOpCode32Alu)context.CurrOp;
-
- EmitAluLoadOpers(context, setCarry: false);
-
- context.Emit(OpCodes.Sub);
-
- context.EmitZnFlagCheck();
-
- EmitSubsCCheck(context);
- EmitSubsVCheck(context);
-
- context.Emit(OpCodes.Pop);
- }
-
- public static void Mov(ILEmitterCtx context)
- {
- IOpCode32Alu op = (IOpCode32Alu)context.CurrOp;
-
- EmitAluLoadOper2(context);
-
- if (op.SetFlags)
- {
- context.EmitZnFlagCheck();
- }
-
- EmitAluStore(context);
- }
-
- public static void Sub(ILEmitterCtx context)
- {
- IOpCode32Alu op = (IOpCode32Alu)context.CurrOp;
-
- EmitAluLoadOpers(context, setCarry: false);
-
- context.Emit(OpCodes.Sub);
-
- if (op.SetFlags)
- {
- context.EmitZnFlagCheck();
-
- EmitSubsCCheck(context);
- EmitSubsVCheck(context);
- }
-
- EmitAluStore(context);
- }
-
- private static void EmitAluStore(ILEmitterCtx context)
- {
- IOpCode32Alu op = (IOpCode32Alu)context.CurrOp;
-
- if (op.Rd == RegisterAlias.Aarch32Pc)
- {
- if (op.SetFlags)
- {
- // TODO: Load SPSR etc.
-
- context.EmitLdflg((int)PState.TBit);
-
- ILLabel lblThumb = new ILLabel();
- ILLabel lblEnd = new ILLabel();
-
- context.Emit(OpCodes.Brtrue_S, lblThumb);
-
- context.EmitLdc_I4(~3);
-
- context.Emit(OpCodes.Br_S, lblEnd);
-
- context.MarkLabel(lblThumb);
-
- context.EmitLdc_I4(~1);
-
- context.MarkLabel(lblEnd);
-
- context.Emit(OpCodes.And);
- context.Emit(OpCodes.Conv_U8);
- context.Emit(OpCodes.Ret);
- }
- else
- {
- EmitAluWritePc(context);
- }
- }
- else
- {
- context.EmitStint(GetRegisterAlias(context.Mode, op.Rd));
- }
- }
-
- private static void EmitAluWritePc(ILEmitterCtx context)
- {
- context.EmitStoreContext();
-
- if (IsThumb(context.CurrOp))
- {
- context.EmitLdc_I4(~1);
-
- context.Emit(OpCodes.And);
- context.Emit(OpCodes.Conv_U8);
- context.Emit(OpCodes.Ret);
- }
- else
- {
- EmitBxWritePc(context);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Instructions/InstEmitAluHelper.cs b/ChocolArm64/Instructions/InstEmitAluHelper.cs
deleted file mode 100644
index 64822088ba..0000000000
--- a/ChocolArm64/Instructions/InstEmitAluHelper.cs
+++ /dev/null
@@ -1,462 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System;
-using System.Reflection.Emit;
-
-namespace ChocolArm64.Instructions
-{
- static class InstEmitAluHelper
- {
- public static void EmitAdcsCCheck(ILEmitterCtx context)
- {
- // C = (Rd == Rn && CIn) || Rd < Rn
- context.EmitSttmp();
- context.EmitLdtmp();
- context.EmitLdtmp();
-
- EmitAluLoadRn(context);
-
- context.Emit(OpCodes.Ceq);
-
- context.EmitLdflg((int)PState.CBit);
-
- context.Emit(OpCodes.And);
-
- context.EmitLdtmp();
-
- EmitAluLoadRn(context);
-
- context.Emit(OpCodes.Clt_Un);
- context.Emit(OpCodes.Or);
-
- context.EmitStflg((int)PState.CBit);
- }
-
- public static void EmitAddsCCheck(ILEmitterCtx context)
- {
- // C = Rd < Rn
- context.Emit(OpCodes.Dup);
-
- EmitAluLoadRn(context);
-
- context.Emit(OpCodes.Clt_Un);
-
- context.EmitStflg((int)PState.CBit);
- }
-
- public static void EmitAddsVCheck(ILEmitterCtx context)
- {
- // V = (Rd ^ Rn) & ~(Rn ^ Rm) < 0
- context.Emit(OpCodes.Dup);
-
- EmitAluLoadRn(context);
-
- context.Emit(OpCodes.Xor);
-
- EmitAluLoadOpers(context);
-
- context.Emit(OpCodes.Xor);
- context.Emit(OpCodes.Not);
- context.Emit(OpCodes.And);
-
- context.EmitLdc_I(0);
-
- context.Emit(OpCodes.Clt);
-
- context.EmitStflg((int)PState.VBit);
- }
-
- public static void EmitSbcsCCheck(ILEmitterCtx context)
- {
- // C = (Rn == Rm && CIn) || Rn > Rm
- EmitAluLoadOpers(context);
-
- context.Emit(OpCodes.Ceq);
-
- context.EmitLdflg((int)PState.CBit);
-
- context.Emit(OpCodes.And);
-
- EmitAluLoadOpers(context);
-
- context.Emit(OpCodes.Cgt_Un);
- context.Emit(OpCodes.Or);
-
- context.EmitStflg((int)PState.CBit);
- }
-
- public static void EmitSubsCCheck(ILEmitterCtx context)
- {
- // C = Rn == Rm || Rn > Rm = !(Rn < Rm)
- EmitAluLoadOpers(context);
-
- context.Emit(OpCodes.Clt_Un);
-
- context.EmitLdc_I4(1);
-
- context.Emit(OpCodes.Xor);
-
- context.EmitStflg((int)PState.CBit);
- }
-
- public static void EmitSubsVCheck(ILEmitterCtx context)
- {
- // V = (Rd ^ Rn) & (Rn ^ Rm) < 0
- context.Emit(OpCodes.Dup);
-
- EmitAluLoadRn(context);
-
- context.Emit(OpCodes.Xor);
-
- EmitAluLoadOpers(context);
-
- context.Emit(OpCodes.Xor);
- context.Emit(OpCodes.And);
-
- context.EmitLdc_I(0);
-
- context.Emit(OpCodes.Clt);
-
- context.EmitStflg((int)PState.VBit);
- }
-
- public static void EmitAluLoadRm(ILEmitterCtx context)
- {
- if (context.CurrOp is IOpCodeAluRs64 op)
- {
- context.EmitLdintzr(op.Rm);
- }
- else if (context.CurrOp is OpCode32AluRsImm op32)
- {
- InstEmit32Helper.EmitLoadFromRegister(context, op32.Rm);
- }
- else
- {
- throw new InvalidOperationException();
- }
- }
-
- public static void EmitAluLoadOpers(ILEmitterCtx context, bool setCarry = true)
- {
- EmitAluLoadRn(context);
- EmitAluLoadOper2(context, setCarry);
- }
-
- public static void EmitAluLoadRn(ILEmitterCtx context)
- {
- if (context.CurrOp is IOpCodeAlu64 op)
- {
- if (op.DataOp == DataOp.Logical || op is IOpCodeAluRs64)
- {
- context.EmitLdintzr(op.Rn);
- }
- else
- {
- context.EmitLdint(op.Rn);
- }
- }
- else if (context.CurrOp is IOpCode32Alu op32)
- {
- InstEmit32Helper.EmitLoadFromRegister(context, op32.Rn);
- }
- else
- {
- throw new InvalidOperationException();
- }
- }
-
- public static void EmitAluLoadOper2(ILEmitterCtx context, bool setCarry = true)
- {
- switch (context.CurrOp)
- {
- // ARM32.
- case OpCode32AluImm op:
- context.EmitLdc_I4(op.Imm);
-
- if (op.SetFlags && op.IsRotated)
- {
- context.EmitLdc_I4((int)((uint)op.Imm >> 31));
-
- context.EmitStflg((int)PState.CBit);
- }
- break;
-
- case OpCode32AluRsImm op:
- EmitLoadRmShiftedByImmediate(context, op, setCarry);
- break;
-
- case OpCodeT16AluImm8 op:
- context.EmitLdc_I4(op.Imm);
- break;
-
- // ARM64.
- case IOpCodeAluImm64 op:
- context.EmitLdc_I(op.Imm);
- break;
-
- case IOpCodeAluRs64 op:
- context.EmitLdintzr(op.Rm);
-
- switch (op.ShiftType)
- {
- case ShiftType.Lsl: context.EmitLsl(op.Shift); break;
- case ShiftType.Lsr: context.EmitLsr(op.Shift); break;
- case ShiftType.Asr: context.EmitAsr(op.Shift); break;
- case ShiftType.Ror: context.EmitRor(op.Shift); break;
- }
- break;
-
- case IOpCodeAluRx64 op:
- context.EmitLdintzr(op.Rm);
- context.EmitCast(op.IntType);
- context.EmitLsl(op.Shift);
- break;
-
- default: throw new InvalidOperationException();
- }
- }
-
- public static void EmitSetNzcv(ILEmitterCtx context)
- {
- context.Emit(OpCodes.Dup);
- context.Emit(OpCodes.Ldc_I4_1);
- context.Emit(OpCodes.And);
- context.EmitStflg((int)PState.VBit);
-
- context.Emit(OpCodes.Ldc_I4_1);
- context.Emit(OpCodes.Shr);
- context.Emit(OpCodes.Dup);
- context.Emit(OpCodes.Ldc_I4_1);
- context.Emit(OpCodes.And);
- context.EmitStflg((int)PState.CBit);
-
- context.Emit(OpCodes.Ldc_I4_1);
- context.Emit(OpCodes.Shr);
- context.Emit(OpCodes.Dup);
- context.Emit(OpCodes.Ldc_I4_1);
- context.Emit(OpCodes.And);
- context.EmitStflg((int)PState.ZBit);
-
- context.Emit(OpCodes.Ldc_I4_1);
- context.Emit(OpCodes.Shr);
- context.Emit(OpCodes.Ldc_I4_1);
- context.Emit(OpCodes.And);
- context.EmitStflg((int)PState.NBit);
- }
-
- // ARM32 helpers.
- private static void EmitLoadRmShiftedByImmediate(ILEmitterCtx context, OpCode32AluRsImm op, bool setCarry)
- {
- int shift = op.Imm;
-
- if (shift == 0)
- {
- switch (op.ShiftType)
- {
- case ShiftType.Lsr: shift = 32; break;
- case ShiftType.Asr: shift = 32; break;
- case ShiftType.Ror: shift = 1; break;
- }
- }
-
- context.EmitLdint(op.Rm);
-
- if (shift != 0)
- {
- setCarry &= op.SetFlags;
-
- switch (op.ShiftType)
- {
- case ShiftType.Lsl: EmitLslC(context, setCarry, shift); break;
- case ShiftType.Lsr: EmitLsrC(context, setCarry, shift); break;
- case ShiftType.Asr: EmitAsrC(context, setCarry, shift); break;
- case ShiftType.Ror:
- if (op.Imm != 0)
- {
- EmitRorC(context, setCarry, shift);
- }
- else
- {
- EmitRrxC(context, setCarry);
- }
- break;
- }
- }
- }
-
- private static void EmitLslC(ILEmitterCtx context, bool setCarry, int shift)
- {
- if ((uint)shift > 32)
- {
- EmitShiftByMoreThan32(context, setCarry);
- }
- else if (shift == 32)
- {
- if (setCarry)
- {
- context.EmitLdc_I4(1);
-
- context.Emit(OpCodes.And);
-
- context.EmitStflg((int)PState.CBit);
- }
- else
- {
- context.Emit(OpCodes.Pop);
- }
-
- context.EmitLdc_I4(0);
- }
- else
- {
- if (setCarry)
- {
- context.Emit(OpCodes.Dup);
-
- context.EmitLsr(32 - shift);
-
- context.EmitLdc_I4(1);
-
- context.Emit(OpCodes.And);
-
- context.EmitStflg((int)PState.CBit);
- }
-
- context.EmitLsl(shift);
- }
- }
-
- private static void EmitLsrC(ILEmitterCtx context, bool setCarry, int shift)
- {
- if ((uint)shift > 32)
- {
- EmitShiftByMoreThan32(context, setCarry);
- }
- else if (shift == 32)
- {
- if (setCarry)
- {
- context.EmitLsr(31);
-
- context.EmitStflg((int)PState.CBit);
- }
- else
- {
- context.Emit(OpCodes.Pop);
- }
-
- context.EmitLdc_I4(0);
- }
- else
- {
- context.Emit(OpCodes.Dup);
-
- context.EmitLsr(shift - 1);
-
- context.EmitLdc_I4(1);
-
- context.Emit(OpCodes.And);
-
- context.EmitStflg((int)PState.CBit);
-
- context.EmitLsr(shift);
- }
- }
-
- private static void EmitShiftByMoreThan32(ILEmitterCtx context, bool setCarry)
- {
- context.Emit(OpCodes.Pop);
-
- context.EmitLdc_I4(0);
-
- if (setCarry)
- {
- context.Emit(OpCodes.Dup);
-
- context.EmitStflg((int)PState.CBit);
- }
- }
-
- private static void EmitAsrC(ILEmitterCtx context, bool setCarry, int shift)
- {
- if ((uint)shift >= 32)
- {
- context.EmitAsr(31);
-
- if (setCarry)
- {
- context.Emit(OpCodes.Dup);
-
- context.EmitLdc_I4(1);
-
- context.Emit(OpCodes.And);
-
- context.EmitStflg((int)PState.CBit);
- }
- }
- else
- {
- if (setCarry)
- {
- context.Emit(OpCodes.Dup);
-
- context.EmitLsr(shift - 1);
-
- context.EmitLdc_I4(1);
-
- context.Emit(OpCodes.And);
-
- context.EmitStflg((int)PState.CBit);
- }
-
- context.EmitAsr(shift);
- }
- }
-
- private static void EmitRorC(ILEmitterCtx context, bool setCarry, int shift)
- {
- shift &= 0x1f;
-
- context.EmitRor(shift);
-
- if (setCarry)
- {
- context.Emit(OpCodes.Dup);
-
- context.EmitLsr(31);
-
- context.EmitStflg((int)PState.CBit);
- }
- }
-
- private static void EmitRrxC(ILEmitterCtx context, bool setCarry)
- {
- // Rotate right by 1 with carry.
- if (setCarry)
- {
- context.Emit(OpCodes.Dup);
-
- context.EmitLdc_I4(1);
-
- context.Emit(OpCodes.And);
-
- context.EmitSttmp();
- }
-
- context.EmitLsr(1);
-
- context.EmitLdflg((int)PState.CBit);
-
- context.EmitLsl(31);
-
- context.Emit(OpCodes.Or);
-
- if (setCarry)
- {
- context.EmitLdtmp();
- context.EmitStflg((int)PState.CBit);
- }
- }
- }
-}
diff --git a/ChocolArm64/Instructions/InstEmitBfm.cs b/ChocolArm64/Instructions/InstEmitBfm.cs
deleted file mode 100644
index 75e259c1b4..0000000000
--- a/ChocolArm64/Instructions/InstEmitBfm.cs
+++ /dev/null
@@ -1,243 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System.Reflection.Emit;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
- public static void Bfm(ILEmitterCtx context)
- {
- OpCodeBfm64 op = (OpCodeBfm64)context.CurrOp;
-
- if (op.Pos < op.Shift)
- {
- // BFI.
- context.EmitLdintzr(op.Rn);
-
- int shift = op.GetBitsCount() - op.Shift;
-
- int width = op.Pos + 1;
-
- long mask = (long)(ulong.MaxValue >> (64 - width));
-
- context.EmitLdc_I(mask);
-
- context.Emit(OpCodes.And);
-
- context.EmitLsl(shift);
-
- context.EmitLdintzr(op.Rd);
-
- context.EmitLdc_I(~(mask << shift));
-
- context.Emit(OpCodes.And);
- context.Emit(OpCodes.Or);
-
- context.EmitStintzr(op.Rd);
- }
- else
- {
- // BFXIL.
- context.EmitLdintzr(op.Rn);
-
- context.EmitLsr(op.Shift);
-
- int width = op.Pos - op.Shift + 1;
-
- long mask = (long)(ulong.MaxValue >> (64 - width));
-
- context.EmitLdc_I(mask);
-
- context.Emit(OpCodes.And);
-
- context.EmitLdintzr(op.Rd);
-
- context.EmitLdc_I(~mask);
-
- context.Emit(OpCodes.And);
- context.Emit(OpCodes.Or);
-
- context.EmitStintzr(op.Rd);
- }
- }
-
- public static void Sbfm(ILEmitterCtx context)
- {
- OpCodeBfm64 op = (OpCodeBfm64)context.CurrOp;
-
- int bitsCount = op.GetBitsCount();
-
- if (op.Pos + 1 == bitsCount)
- {
- EmitSbfmShift(context);
- }
- else if (op.Pos < op.Shift)
- {
- EmitSbfiz(context);
- }
- else if (op.Pos == 7 && op.Shift == 0)
- {
- EmitSbfmCast(context, OpCodes.Conv_I1);
- }
- else if (op.Pos == 15 && op.Shift == 0)
- {
- EmitSbfmCast(context, OpCodes.Conv_I2);
- }
- else if (op.Pos == 31 && op.Shift == 0)
- {
- EmitSbfmCast(context, OpCodes.Conv_I4);
- }
- else
- {
- EmitBfmLoadRn(context);
-
- context.EmitLdintzr(op.Rn);
-
- context.EmitLsl(bitsCount - 1 - op.Pos);
- context.EmitAsr(bitsCount - 1);
-
- context.EmitLdc_I(~op.TMask);
-
- context.Emit(OpCodes.And);
- context.Emit(OpCodes.Or);
-
- context.EmitStintzr(op.Rd);
- }
- }
-
- public static void Ubfm(ILEmitterCtx context)
- {
- OpCodeBfm64 op = (OpCodeBfm64)context.CurrOp;
-
- if (op.Pos + 1 == op.GetBitsCount())
- {
- EmitUbfmShift(context);
- }
- else if (op.Pos < op.Shift)
- {
- EmitUbfiz(context);
- }
- else if (op.Pos + 1 == op.Shift)
- {
- EmitBfmLsl(context);
- }
- else if (op.Pos == 7 && op.Shift == 0)
- {
- EmitUbfmCast(context, OpCodes.Conv_U1);
- }
- else if (op.Pos == 15 && op.Shift == 0)
- {
- EmitUbfmCast(context, OpCodes.Conv_U2);
- }
- else
- {
- EmitBfmLoadRn(context);
-
- context.EmitStintzr(op.Rd);
- }
- }
-
- private static void EmitSbfiz(ILEmitterCtx context) => EmitBfiz(context, true);
- private static void EmitUbfiz(ILEmitterCtx context) => EmitBfiz(context, false);
-
- private static void EmitBfiz(ILEmitterCtx context, bool signed)
- {
- OpCodeBfm64 op = (OpCodeBfm64)context.CurrOp;
-
- int width = op.Pos + 1;
-
- context.EmitLdintzr(op.Rn);
-
- context.EmitLsl(op.GetBitsCount() - width);
-
- if (signed)
- {
- context.EmitAsr(op.Shift - width);
- }
- else
- {
- context.EmitLsr(op.Shift - width);
- }
-
- context.EmitStintzr(op.Rd);
- }
-
- private static void EmitSbfmCast(ILEmitterCtx context, OpCode ilOp)
- {
- EmitBfmCast(context, ilOp, true);
- }
-
- private static void EmitUbfmCast(ILEmitterCtx context, OpCode ilOp)
- {
- EmitBfmCast(context, ilOp, false);
- }
-
- private static void EmitBfmCast(ILEmitterCtx context, OpCode ilOp, bool signed)
- {
- OpCodeBfm64 op = (OpCodeBfm64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
-
- context.Emit(ilOp);
-
- if (op.RegisterSize != RegisterSize.Int32)
- {
- context.Emit(signed
- ? OpCodes.Conv_I8
- : OpCodes.Conv_U8);
- }
-
- context.EmitStintzr(op.Rd);
- }
-
- private static void EmitSbfmShift(ILEmitterCtx context)
- {
- EmitBfmShift(context, true);
- }
-
- private static void EmitUbfmShift(ILEmitterCtx context)
- {
- EmitBfmShift(context, false);
- }
-
- private static void EmitBfmShift(ILEmitterCtx context, bool signed)
- {
- OpCodeBfm64 op = (OpCodeBfm64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
- context.EmitLdc_I4(op.Shift);
-
- context.Emit(signed
- ? OpCodes.Shr
- : OpCodes.Shr_Un);
-
- context.EmitStintzr(op.Rd);
- }
-
- private static void EmitBfmLsl(ILEmitterCtx context)
- {
- OpCodeBfm64 op = (OpCodeBfm64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
-
- context.EmitLsl(op.GetBitsCount() - op.Shift);
-
- context.EmitStintzr(op.Rd);
- }
-
- private static void EmitBfmLoadRn(ILEmitterCtx context)
- {
- OpCodeBfm64 op = (OpCodeBfm64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
-
- context.EmitRor(op.Shift);
-
- context.EmitLdc_I(op.WMask & op.TMask);
-
- context.Emit(OpCodes.And);
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Instructions/InstEmitCcmp.cs b/ChocolArm64/Instructions/InstEmitCcmp.cs
deleted file mode 100644
index e21dc69686..0000000000
--- a/ChocolArm64/Instructions/InstEmitCcmp.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.IntermediateRepresentation;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System;
-using System.Reflection.Emit;
-
-using static ChocolArm64.Instructions.InstEmitAluHelper;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
- private enum CcmpOp
- {
- Cmp,
- Cmn
- }
-
- public static void Ccmn(ILEmitterCtx context) => EmitCcmp(context, CcmpOp.Cmn);
- public static void Ccmp(ILEmitterCtx context) => EmitCcmp(context, CcmpOp.Cmp);
-
- private static void EmitCcmp(ILEmitterCtx context, CcmpOp cmpOp)
- {
- OpCodeCcmp64 op = (OpCodeCcmp64)context.CurrOp;
-
- ILLabel lblTrue = new ILLabel();
- ILLabel lblEnd = new ILLabel();
-
- context.EmitCondBranch(lblTrue, op.Cond);
-
- context.EmitLdc_I4((op.Nzcv >> 0) & 1);
-
- context.EmitStflg((int)PState.VBit);
-
- context.EmitLdc_I4((op.Nzcv >> 1) & 1);
-
- context.EmitStflg((int)PState.CBit);
-
- context.EmitLdc_I4((op.Nzcv >> 2) & 1);
-
- context.EmitStflg((int)PState.ZBit);
-
- context.EmitLdc_I4((op.Nzcv >> 3) & 1);
-
- context.EmitStflg((int)PState.NBit);
-
- context.Emit(OpCodes.Br_S, lblEnd);
-
- context.MarkLabel(lblTrue);
-
- EmitAluLoadOpers(context);
-
- if (cmpOp == CcmpOp.Cmp)
- {
- context.Emit(OpCodes.Sub);
-
- context.EmitZnFlagCheck();
-
- EmitSubsCCheck(context);
- EmitSubsVCheck(context);
- }
- else if (cmpOp == CcmpOp.Cmn)
- {
- context.Emit(OpCodes.Add);
-
- context.EmitZnFlagCheck();
-
- EmitAddsCCheck(context);
- EmitAddsVCheck(context);
- }
- else
- {
- throw new ArgumentException(nameof(cmpOp));
- }
-
- context.Emit(OpCodes.Pop);
-
- context.MarkLabel(lblEnd);
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Instructions/InstEmitCsel.cs b/ChocolArm64/Instructions/InstEmitCsel.cs
deleted file mode 100644
index 7008a8c7eb..0000000000
--- a/ChocolArm64/Instructions/InstEmitCsel.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.IntermediateRepresentation;
-using ChocolArm64.Translation;
-using System.Reflection.Emit;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
- private enum CselOperation
- {
- None,
- Increment,
- Invert,
- Negate
- }
-
- public static void Csel(ILEmitterCtx context) => EmitCsel(context, CselOperation.None);
- public static void Csinc(ILEmitterCtx context) => EmitCsel(context, CselOperation.Increment);
- public static void Csinv(ILEmitterCtx context) => EmitCsel(context, CselOperation.Invert);
- public static void Csneg(ILEmitterCtx context) => EmitCsel(context, CselOperation.Negate);
-
- private static void EmitCsel(ILEmitterCtx context, CselOperation cselOp)
- {
- OpCodeCsel64 op = (OpCodeCsel64)context.CurrOp;
-
- ILLabel lblTrue = new ILLabel();
- ILLabel lblEnd = new ILLabel();
-
- context.EmitCondBranch(lblTrue, op.Cond);
- context.EmitLdintzr(op.Rm);
-
- if (cselOp == CselOperation.Increment)
- {
- context.EmitLdc_I(1);
-
- context.Emit(OpCodes.Add);
- }
- else if (cselOp == CselOperation.Invert)
- {
- context.Emit(OpCodes.Not);
- }
- else if (cselOp == CselOperation.Negate)
- {
- context.Emit(OpCodes.Neg);
- }
-
- context.Emit(OpCodes.Br_S, lblEnd);
-
- context.MarkLabel(lblTrue);
-
- context.EmitLdintzr(op.Rn);
-
- context.MarkLabel(lblEnd);
-
- context.EmitStintzr(op.Rd);
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Instructions/InstEmitException.cs b/ChocolArm64/Instructions/InstEmitException.cs
deleted file mode 100644
index c835fb0d67..0000000000
--- a/ChocolArm64/Instructions/InstEmitException.cs
+++ /dev/null
@@ -1,87 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.IntermediateRepresentation;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System.Reflection.Emit;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
- public static void Brk(ILEmitterCtx context)
- {
- EmitExceptionCall(context, nameof(CpuThreadState.OnBreak));
- }
-
- public static void Svc(ILEmitterCtx context)
- {
- EmitExceptionCall(context, nameof(CpuThreadState.OnSvcCall));
- }
-
- private static void EmitExceptionCall(ILEmitterCtx context, string mthdName)
- {
- OpCodeException64 op = (OpCodeException64)context.CurrOp;
-
- context.EmitStoreContext();
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- context.EmitLdc_I8(op.Position);
- context.EmitLdc_I4(op.Id);
-
- context.EmitPrivateCall(typeof(CpuThreadState), mthdName);
-
- // Check if the thread should still be running, if it isn't then we return 0
- // to force a return to the dispatcher and then exit the thread.
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- context.EmitCallPropGet(typeof(CpuThreadState), nameof(CpuThreadState.Running));
-
- ILLabel lblEnd = new ILLabel();
-
- context.Emit(OpCodes.Brtrue_S, lblEnd);
-
- context.EmitLdc_I8(0);
-
- context.Emit(OpCodes.Ret);
-
- context.MarkLabel(lblEnd);
-
- if (context.CurrBlock.Next != null)
- {
- context.EmitLoadContext();
- }
- else
- {
- context.EmitLdc_I8(op.Position + 4);
-
- context.Emit(OpCodes.Ret);
- }
- }
-
- public static void Und(ILEmitterCtx context)
- {
- OpCode64 op = context.CurrOp;
-
- context.EmitStoreContext();
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- context.EmitLdc_I8(op.Position);
- context.EmitLdc_I4(op.RawOpCode);
-
- context.EmitPrivateCall(typeof(CpuThreadState), nameof(CpuThreadState.OnUndefined));
-
- if (context.CurrBlock.Next != null)
- {
- context.EmitLoadContext();
- }
- else
- {
- context.EmitLdc_I8(op.Position + 4);
-
- context.Emit(OpCodes.Ret);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Instructions/InstEmitFlow.cs b/ChocolArm64/Instructions/InstEmitFlow.cs
deleted file mode 100644
index 6355b8b4b2..0000000000
--- a/ChocolArm64/Instructions/InstEmitFlow.cs
+++ /dev/null
@@ -1,181 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.IntermediateRepresentation;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System.Reflection.Emit;
-
-using static ChocolArm64.Instructions.InstEmitFlowHelper;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
- public static void B(ILEmitterCtx context)
- {
- OpCodeBImmAl64 op = (OpCodeBImmAl64)context.CurrOp;
-
- if (context.CurrBlock.Branch != null)
- {
- context.Emit(OpCodes.Br, context.GetLabel(op.Imm));
- }
- else
- {
- context.EmitStoreContext();
- context.EmitLdc_I8(op.Imm);
-
- context.Emit(OpCodes.Ret);
- }
- }
-
- public static void B_Cond(ILEmitterCtx context)
- {
- OpCodeBImmCond64 op = (OpCodeBImmCond64)context.CurrOp;
-
- EmitBranch(context, op.Cond);
- }
-
- public static void Bl(ILEmitterCtx context)
- {
- OpCodeBImmAl64 op = (OpCodeBImmAl64)context.CurrOp;
-
- context.EmitLdc_I(op.Position + 4);
- context.EmitStint(RegisterAlias.Lr);
-
- EmitCall(context, op.Imm);
- }
-
- public static void Blr(ILEmitterCtx context)
- {
- OpCodeBReg64 op = (OpCodeBReg64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
- context.EmitLdc_I(op.Position + 4);
- context.EmitStint(RegisterAlias.Lr);
- context.EmitStoreContext();
-
- EmitVirtualCall(context);
- }
-
- public static void Br(ILEmitterCtx context)
- {
- OpCodeBReg64 op = (OpCodeBReg64)context.CurrOp;
-
- context.HasIndirectJump = true;
-
- context.EmitStoreContext();
- context.EmitLdintzr(op.Rn);
-
- EmitVirtualJump(context);
- }
-
- public static void Cbnz(ILEmitterCtx context) => EmitCb(context, OpCodes.Bne_Un);
- public static void Cbz(ILEmitterCtx context) => EmitCb(context, OpCodes.Beq);
-
- private static void EmitCb(ILEmitterCtx context, OpCode ilOp)
- {
- OpCodeBImmCmp64 op = (OpCodeBImmCmp64)context.CurrOp;
-
- context.EmitLdintzr(op.Rt);
- context.EmitLdc_I(0);
-
- EmitBranch(context, ilOp);
- }
-
- public static void Ret(ILEmitterCtx context)
- {
- context.EmitStoreContext();
- context.EmitLdint(RegisterAlias.Lr);
-
- context.Emit(OpCodes.Ret);
- }
-
- public static void Tbnz(ILEmitterCtx context) => EmitTb(context, OpCodes.Bne_Un);
- public static void Tbz(ILEmitterCtx context) => EmitTb(context, OpCodes.Beq);
-
- private static void EmitTb(ILEmitterCtx context, OpCode ilOp)
- {
- OpCodeBImmTest64 op = (OpCodeBImmTest64)context.CurrOp;
-
- context.EmitLdintzr(op.Rt);
- context.EmitLdc_I(1L << op.Pos);
-
- context.Emit(OpCodes.And);
-
- context.EmitLdc_I(0);
-
- EmitBranch(context, ilOp);
- }
-
- private static void EmitBranch(ILEmitterCtx context, Condition cond)
- {
- OpCodeBImm64 op = (OpCodeBImm64)context.CurrOp;
-
- if (context.CurrBlock.Branch != null)
- {
- context.EmitCondBranch(context.GetLabel(op.Imm), cond);
-
- if (context.CurrBlock.Next == null)
- {
- context.EmitStoreContext();
- context.EmitLdc_I8(op.Position + 4);
-
- context.Emit(OpCodes.Ret);
- }
- }
- else
- {
- context.EmitStoreContext();
-
- ILLabel lblTaken = new ILLabel();
-
- context.EmitCondBranch(lblTaken, cond);
-
- context.EmitLdc_I8(op.Position + 4);
-
- context.Emit(OpCodes.Ret);
-
- context.MarkLabel(lblTaken);
-
- context.EmitLdc_I8(op.Imm);
-
- context.Emit(OpCodes.Ret);
- }
- }
-
- private static void EmitBranch(ILEmitterCtx context, OpCode ilOp)
- {
- OpCodeBImm64 op = (OpCodeBImm64)context.CurrOp;
-
- if (context.CurrBlock.Branch != null)
- {
- context.Emit(ilOp, context.GetLabel(op.Imm));
-
- if (context.CurrBlock.Next == null)
- {
- context.EmitStoreContext();
- context.EmitLdc_I8(op.Position + 4);
-
- context.Emit(OpCodes.Ret);
- }
- }
- else
- {
- context.EmitStoreContext();
-
- ILLabel lblTaken = new ILLabel();
-
- context.Emit(ilOp, lblTaken);
-
- context.EmitLdc_I8(op.Position + 4);
-
- context.Emit(OpCodes.Ret);
-
- context.MarkLabel(lblTaken);
-
- context.EmitLdc_I8(op.Imm);
-
- context.Emit(OpCodes.Ret);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Instructions/InstEmitFlow32.cs b/ChocolArm64/Instructions/InstEmitFlow32.cs
deleted file mode 100644
index 133e278402..0000000000
--- a/ChocolArm64/Instructions/InstEmitFlow32.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System.Reflection.Emit;
-
-using static ChocolArm64.Instructions.InstEmit32Helper;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit32
- {
- public static void B(ILEmitterCtx context)
- {
- IOpCode32BImm op = (IOpCode32BImm)context.CurrOp;
-
- if (context.CurrBlock.Branch != null)
- {
- context.Emit(OpCodes.Br, context.GetLabel(op.Imm));
- }
- else
- {
- context.EmitStoreContext();
- context.EmitLdc_I8(op.Imm);
-
- context.Emit(OpCodes.Ret);
- }
- }
-
- public static void Bl(ILEmitterCtx context)
- {
- Blx(context, x: false);
- }
-
- public static void Blx(ILEmitterCtx context)
- {
- Blx(context, x: true);
- }
-
- public static void Bx(ILEmitterCtx context)
- {
- IOpCode32BReg op = (IOpCode32BReg)context.CurrOp;
-
- context.EmitStoreContext();
-
- EmitLoadFromRegister(context, op.Rm);
-
- EmitBxWritePc(context);
- }
-
- private static void Blx(ILEmitterCtx context, bool x)
- {
- IOpCode32BImm op = (IOpCode32BImm)context.CurrOp;
-
- uint pc = op.GetPc();
-
- bool isThumb = IsThumb(context.CurrOp);
-
- if (!isThumb)
- {
- context.EmitLdc_I(op.GetPc() - 4);
- }
- else
- {
- context.EmitLdc_I(op.GetPc() | 1);
- }
-
- context.EmitStint(GetBankedRegisterAlias(context.Mode, RegisterAlias.Aarch32Lr));
-
- // If x is true, then this is a branch with link and exchange.
- // In this case we need to swap the mode between Arm <-> Thumb.
- if (x)
- {
- context.EmitLdc_I4(isThumb ? 0 : 1);
-
- context.EmitStflg((int)PState.TBit);
- }
-
- InstEmitFlowHelper.EmitCall(context, op.Imm);
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Instructions/InstEmitFlowHelper.cs b/ChocolArm64/Instructions/InstEmitFlowHelper.cs
deleted file mode 100644
index f36fe5a1fe..0000000000
--- a/ChocolArm64/Instructions/InstEmitFlowHelper.cs
+++ /dev/null
@@ -1,144 +0,0 @@
-using ChocolArm64.IntermediateRepresentation;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System.Reflection;
-using System.Reflection.Emit;
-
-namespace ChocolArm64.Instructions
-{
- static class InstEmitFlowHelper
- {
- public static void EmitCall(ILEmitterCtx context, long imm)
- {
- if (context.Tier == TranslationTier.Tier0)
- {
- context.EmitStoreContext();
-
- context.TranslateAhead(imm);
-
- context.EmitLdc_I8(imm);
-
- context.Emit(OpCodes.Ret);
-
- return;
- }
-
- if (!context.TryOptEmitSubroutineCall())
- {
- context.HasSlowCall = true;
-
- context.EmitStoreContext();
-
- context.TranslateAhead(imm);
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- context.EmitLdfld(typeof(CpuThreadState).GetField(nameof(CpuThreadState.CurrentTranslator),
- BindingFlags.Instance |
- BindingFlags.NonPublic));
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
- context.EmitLdc_I8(imm);
- context.EmitLdc_I4((int)CallType.Call);
-
- context.EmitPrivateCall(typeof(Translator), nameof(Translator.GetOrTranslateSubroutine));
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
- context.EmitLdarg(TranslatedSub.MemoryArgIdx);
-
- context.EmitCall(typeof(TranslatedSub), nameof(TranslatedSub.Execute));
- }
-
- EmitContinueOrReturnCheck(context);
- }
-
- public static void EmitVirtualCall(ILEmitterCtx context)
- {
- EmitVirtualCallOrJump(context, isJump: false);
- }
-
- public static void EmitVirtualJump(ILEmitterCtx context)
- {
- EmitVirtualCallOrJump(context, isJump: true);
- }
-
- private static void EmitVirtualCallOrJump(ILEmitterCtx context, bool isJump)
- {
- if (context.Tier == TranslationTier.Tier0)
- {
- context.Emit(OpCodes.Ret);
- }
- else
- {
- context.EmitSttmp();
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- context.EmitLdfld(typeof(CpuThreadState).GetField(nameof(CpuThreadState.CurrentTranslator),
- BindingFlags.Instance |
- BindingFlags.NonPublic));
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
- context.EmitLdtmp();
- context.EmitLdc_I4(isJump
- ? (int)CallType.VirtualJump
- : (int)CallType.VirtualCall);
-
- context.EmitPrivateCall(typeof(Translator), nameof(Translator.GetOrTranslateSubroutine));
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
- context.EmitLdarg(TranslatedSub.MemoryArgIdx);
-
- if (isJump)
- {
- // The tail prefix allows the JIT to jump to the next function,
- // while releasing the stack space used by the current one.
- // This is ideal for BR ARM instructions, which are
- // basically indirect tail calls.
- context.Emit(OpCodes.Tailcall);
- }
-
- MethodInfo mthdInfo = typeof(ArmSubroutine).GetMethod("Invoke");
-
- context.EmitCall(mthdInfo, isVirtual: true);
-
- if (!isJump)
- {
- EmitContinueOrReturnCheck(context);
- }
- else
- {
- context.Emit(OpCodes.Ret);
- }
- }
- }
-
- private static void EmitContinueOrReturnCheck(ILEmitterCtx context)
- {
- // Note: The return value of the called method will be placed
- // at the Stack, the return value is always a Int64 with the
- // return address of the function. We check if the address is
- // correct, if it isn't we keep returning until we reach the dispatcher.
- if (context.CurrBlock.Next != null)
- {
- context.Emit(OpCodes.Dup);
-
- context.EmitLdc_I8(context.CurrOp.Position + 4);
-
- ILLabel lblContinue = new ILLabel();
-
- context.Emit(OpCodes.Beq_S, lblContinue);
- context.Emit(OpCodes.Ret);
-
- context.MarkLabel(lblContinue);
-
- context.Emit(OpCodes.Pop);
-
- context.EmitLoadContext();
- }
- else
- {
- context.Emit(OpCodes.Ret);
- }
- }
- }
-}
diff --git a/ChocolArm64/Instructions/InstEmitHash.cs b/ChocolArm64/Instructions/InstEmitHash.cs
deleted file mode 100644
index 7e21a88604..0000000000
--- a/ChocolArm64/Instructions/InstEmitHash.cs
+++ /dev/null
@@ -1,115 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System;
-using System.Reflection.Emit;
-using System.Runtime.Intrinsics.X86;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
- public static void Crc32b(ILEmitterCtx context)
- {
- EmitCrc32(context, nameof(SoftFallback.Crc32B));
- }
-
- public static void Crc32h(ILEmitterCtx context)
- {
- EmitCrc32(context, nameof(SoftFallback.Crc32H));
- }
-
- public static void Crc32w(ILEmitterCtx context)
- {
- EmitCrc32(context, nameof(SoftFallback.Crc32W));
- }
-
- public static void Crc32x(ILEmitterCtx context)
- {
- EmitCrc32(context, nameof(SoftFallback.Crc32X));
- }
-
- public static void Crc32cb(ILEmitterCtx context)
- {
- if (Optimizations.UseSse42)
- {
- EmitSse42Crc32(context, typeof(uint), typeof(byte));
- }
- else
- {
- EmitCrc32(context, nameof(SoftFallback.Crc32Cb));
- }
- }
-
- public static void Crc32ch(ILEmitterCtx context)
- {
- if (Optimizations.UseSse42)
- {
- EmitSse42Crc32(context, typeof(uint), typeof(ushort));
- }
- else
- {
- EmitCrc32(context, nameof(SoftFallback.Crc32Ch));
- }
- }
-
- public static void Crc32cw(ILEmitterCtx context)
- {
- if (Optimizations.UseSse42)
- {
- EmitSse42Crc32(context, typeof(uint), typeof(uint));
- }
- else
- {
- EmitCrc32(context, nameof(SoftFallback.Crc32Cw));
- }
- }
-
- public static void Crc32cx(ILEmitterCtx context)
- {
- if (Optimizations.UseSse42)
- {
- EmitSse42Crc32(context, typeof(ulong), typeof(ulong));
- }
- else
- {
- EmitCrc32(context, nameof(SoftFallback.Crc32Cx));
- }
- }
-
- private static void EmitSse42Crc32(ILEmitterCtx context, Type tCrc, Type tData)
- {
- OpCodeAluRs64 op = (OpCodeAluRs64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
- context.EmitLdintzr(op.Rm);
-
- context.EmitCall(typeof(Sse42).GetMethod(nameof(Sse42.Crc32), new Type[] { tCrc, tData }));
-
- context.EmitStintzr(op.Rd);
- }
-
- private static void EmitCrc32(ILEmitterCtx context, string name)
- {
- OpCodeAluRs64 op = (OpCodeAluRs64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
-
- if (op.RegisterSize != RegisterSize.Int32)
- {
- context.Emit(OpCodes.Conv_U4);
- }
-
- context.EmitLdintzr(op.Rm);
-
- SoftFallback.EmitCall(context, name);
-
- if (op.RegisterSize != RegisterSize.Int32)
- {
- context.Emit(OpCodes.Conv_U8);
- }
-
- context.EmitStintzr(op.Rd);
- }
- }
-}
diff --git a/ChocolArm64/Instructions/InstEmitMemory.cs b/ChocolArm64/Instructions/InstEmitMemory.cs
deleted file mode 100644
index 1328f3936c..0000000000
--- a/ChocolArm64/Instructions/InstEmitMemory.cs
+++ /dev/null
@@ -1,241 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.Translation;
-using System.Reflection.Emit;
-
-using static ChocolArm64.Instructions.InstEmitMemoryHelper;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
- public static void Adr(ILEmitterCtx context)
- {
- OpCodeAdr64 op = (OpCodeAdr64)context.CurrOp;
-
- context.EmitLdc_I(op.Position + op.Imm);
- context.EmitStintzr(op.Rd);
- }
-
- public static void Adrp(ILEmitterCtx context)
- {
- OpCodeAdr64 op = (OpCodeAdr64)context.CurrOp;
-
- context.EmitLdc_I((op.Position & ~0xfffL) + (op.Imm << 12));
- context.EmitStintzr(op.Rd);
- }
-
- public static void Ldr(ILEmitterCtx context) => EmitLdr(context, false);
- public static void Ldrs(ILEmitterCtx context) => EmitLdr(context, true);
-
- private static void EmitLdr(ILEmitterCtx context, bool signed)
- {
- OpCodeMem64 op = (OpCodeMem64)context.CurrOp;
-
- EmitLoadAddress(context);
-
- if (signed && op.Extend64)
- {
- EmitReadSx64Call(context, op.Size);
- }
- else if (signed)
- {
- EmitReadSx32Call(context, op.Size);
- }
- else
- {
- EmitReadZxCall(context, op.Size);
- }
-
- if (op is IOpCodeSimd64)
- {
- context.EmitStvec(op.Rt);
- }
- else
- {
- context.EmitStintzr(op.Rt);
- }
-
- EmitWBackIfNeeded(context);
- }
-
- public static void Ldr_Literal(ILEmitterCtx context)
- {
- IOpCodeLit64 op = (IOpCodeLit64)context.CurrOp;
-
- if (op.Prefetch)
- {
- return;
- }
-
- context.EmitLdc_I8(op.Imm);
-
- if (op.Signed)
- {
- EmitReadSx64Call(context, op.Size);
- }
- else
- {
- EmitReadZxCall(context, op.Size);
- }
-
- if (op is IOpCodeSimd64)
- {
- context.EmitStvec(op.Rt);
- }
- else
- {
- context.EmitStint(op.Rt);
- }
- }
-
- public static void Ldp(ILEmitterCtx context)
- {
- OpCodeMemPair64 op = (OpCodeMemPair64)context.CurrOp;
-
- void EmitReadAndStore(int rt)
- {
- if (op.Extend64)
- {
- EmitReadSx64Call(context, op.Size);
- }
- else
- {
- EmitReadZxCall(context, op.Size);
- }
-
- if (op is IOpCodeSimd64)
- {
- context.EmitStvec(rt);
- }
- else
- {
- context.EmitStintzr(rt);
- }
- }
-
- EmitLoadAddress(context);
-
- EmitReadAndStore(op.Rt);
-
- context.EmitLdtmp();
- context.EmitLdc_I8(1 << op.Size);
-
- context.Emit(OpCodes.Add);
-
- EmitReadAndStore(op.Rt2);
-
- EmitWBackIfNeeded(context);
- }
-
- public static void Str(ILEmitterCtx context)
- {
- OpCodeMem64 op = (OpCodeMem64)context.CurrOp;
-
- EmitLoadAddress(context);
-
- if (op is IOpCodeSimd64)
- {
- context.EmitLdvec(op.Rt);
- }
- else
- {
- context.EmitLdintzr(op.Rt);
- }
-
- EmitWriteCall(context, op.Size);
-
- EmitWBackIfNeeded(context);
- }
-
- public static void Stp(ILEmitterCtx context)
- {
- OpCodeMemPair64 op = (OpCodeMemPair64)context.CurrOp;
-
- EmitLoadAddress(context);
-
- if (op is IOpCodeSimd64)
- {
- context.EmitLdvec(op.Rt);
- }
- else
- {
- context.EmitLdintzr(op.Rt);
- }
-
- EmitWriteCall(context, op.Size);
-
- context.EmitLdtmp();
- context.EmitLdc_I8(1 << op.Size);
-
- context.Emit(OpCodes.Add);
-
- if (op is IOpCodeSimd64)
- {
- context.EmitLdvec(op.Rt2);
- }
- else
- {
- context.EmitLdintzr(op.Rt2);
- }
-
- EmitWriteCall(context, op.Size);
-
- EmitWBackIfNeeded(context);
- }
-
- private static void EmitLoadAddress(ILEmitterCtx context)
- {
- switch (context.CurrOp)
- {
- case OpCodeMemImm64 op:
- context.EmitLdint(op.Rn);
-
- if (!op.PostIdx)
- {
- // Pre-indexing.
- context.EmitLdc_I(op.Imm);
-
- context.Emit(OpCodes.Add);
- }
- break;
-
- case OpCodeMemReg64 op:
- context.EmitLdint(op.Rn);
- context.EmitLdintzr(op.Rm);
- context.EmitCast(op.IntType);
-
- if (op.Shift)
- {
- context.EmitLsl(op.Size);
- }
-
- context.Emit(OpCodes.Add);
- break;
- }
-
- // Save address to Scratch var since the register value may change.
- context.Emit(OpCodes.Dup);
-
- context.EmitSttmp();
- }
-
- private static void EmitWBackIfNeeded(ILEmitterCtx context)
- {
- // Check whenever the current OpCode has post-indexed write back, if so write it.
- // Note: AOpCodeMemPair inherits from AOpCodeMemImm, so this works for both.
- if (context.CurrOp is OpCodeMemImm64 op && op.WBack)
- {
- context.EmitLdtmp();
-
- if (op.PostIdx)
- {
- context.EmitLdc_I(op.Imm);
-
- context.Emit(OpCodes.Add);
- }
-
- context.EmitStint(op.Rn);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Instructions/InstEmitMemory32.cs b/ChocolArm64/Instructions/InstEmitMemory32.cs
deleted file mode 100644
index 807a65fe1d..0000000000
--- a/ChocolArm64/Instructions/InstEmitMemory32.cs
+++ /dev/null
@@ -1,320 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.IntermediateRepresentation;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System;
-using System.Reflection.Emit;
-
-using static ChocolArm64.Instructions.InstEmit32Helper;
-using static ChocolArm64.Instructions.InstEmitMemoryHelper;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit32
- {
- private const int ByteSizeLog2 = 0;
- private const int HWordSizeLog2 = 1;
- private const int WordSizeLog2 = 2;
- private const int DWordSizeLog2 = 3;
-
- [Flags]
- enum AccessType
- {
- Store = 0,
- Signed = 1,
- Load = 2,
-
- LoadZx = Load,
- LoadSx = Load | Signed,
- }
-
- public static void Ldm(ILEmitterCtx context)
- {
- OpCode32MemMult op = (OpCode32MemMult)context.CurrOp;
-
- EmitLoadFromRegister(context, op.Rn);
-
- bool writesToPc = (op.RegisterMask & (1 << RegisterAlias.Aarch32Pc)) != 0;
-
- bool writeBack = op.PostOffset != 0 && (op.Rn != RegisterAlias.Aarch32Pc || !writesToPc);
-
- if (writeBack)
- {
- context.Emit(OpCodes.Dup);
- }
-
- context.EmitLdc_I4(op.Offset);
-
- context.Emit(OpCodes.Add);
-
- context.EmitSttmp();
-
- if (writeBack)
- {
- context.EmitLdc_I4(op.PostOffset);
-
- context.Emit(OpCodes.Add);
-
- EmitStoreToRegister(context, op.Rn);
- }
-
- int mask = op.RegisterMask;
- int offset = 0;
-
- for (int register = 0; mask != 0; mask >>= 1, register++)
- {
- if ((mask & 1) != 0)
- {
- context.EmitLdtmp();
- context.EmitLdc_I4(offset);
-
- context.Emit(OpCodes.Add);
-
- EmitReadZxCall(context, WordSizeLog2);
-
- EmitStoreToRegister(context, register);
-
- offset += 4;
- }
- }
- }
-
- public static void Ldr(ILEmitterCtx context)
- {
- EmitLoadOrStore(context, WordSizeLog2, AccessType.LoadZx);
- }
-
- public static void Ldrb(ILEmitterCtx context)
- {
- EmitLoadOrStore(context, ByteSizeLog2, AccessType.LoadZx);
- }
-
- public static void Ldrd(ILEmitterCtx context)
- {
- EmitLoadOrStore(context, DWordSizeLog2, AccessType.LoadZx);
- }
-
- public static void Ldrh(ILEmitterCtx context)
- {
- EmitLoadOrStore(context, HWordSizeLog2, AccessType.LoadZx);
- }
-
- public static void Ldrsb(ILEmitterCtx context)
- {
- EmitLoadOrStore(context, ByteSizeLog2, AccessType.LoadSx);
- }
-
- public static void Ldrsh(ILEmitterCtx context)
- {
- EmitLoadOrStore(context, HWordSizeLog2, AccessType.LoadSx);
- }
-
- public static void Stm(ILEmitterCtx context)
- {
- OpCode32MemMult op = (OpCode32MemMult)context.CurrOp;
-
- EmitLoadFromRegister(context, op.Rn);
-
- context.EmitLdc_I4(op.Offset);
-
- context.Emit(OpCodes.Add);
-
- context.EmitSttmp();
-
- int mask = op.RegisterMask;
- int offset = 0;
-
- for (int register = 0; mask != 0; mask >>= 1, register++)
- {
- if ((mask & 1) != 0)
- {
- context.EmitLdtmp();
- context.EmitLdc_I4(offset);
-
- context.Emit(OpCodes.Add);
-
- EmitLoadFromRegister(context, register);
-
- EmitWriteCall(context, WordSizeLog2);
-
- // Note: If Rn is also specified on the register list,
- // and Rn is the first register on this list, then the
- // value that is written to memory is the unmodified value,
- // before the write back. If it is on the list, but it's
- // not the first one, then the value written to memory
- // varies between CPUs.
- if (offset == 0 && op.PostOffset != 0)
- {
- // Emit write back after the first write.
- EmitLoadFromRegister(context, op.Rn);
-
- context.EmitLdc_I4(op.PostOffset);
-
- context.Emit(OpCodes.Add);
-
- EmitStoreToRegister(context, op.Rn);
- }
-
- offset += 4;
- }
- }
- }
-
- public static void Str(ILEmitterCtx context)
- {
- EmitLoadOrStore(context, WordSizeLog2, AccessType.Store);
- }
-
- public static void Strb(ILEmitterCtx context)
- {
- EmitLoadOrStore(context, ByteSizeLog2, AccessType.Store);
- }
-
- public static void Strd(ILEmitterCtx context)
- {
- EmitLoadOrStore(context, DWordSizeLog2, AccessType.Store);
- }
-
- public static void Strh(ILEmitterCtx context)
- {
- EmitLoadOrStore(context, HWordSizeLog2, AccessType.Store);
- }
-
- private static void EmitLoadOrStore(ILEmitterCtx context, int size, AccessType accType)
- {
- OpCode32Mem op = (OpCode32Mem)context.CurrOp;
-
- if (op.Index || op.WBack)
- {
- EmitLoadFromRegister(context, op.Rn);
-
- context.EmitLdc_I4(op.Imm);
-
- context.Emit(op.Add ? OpCodes.Add : OpCodes.Sub);
-
- context.EmitSttmp();
- }
-
- if (op.Index)
- {
- context.EmitLdtmp();
- }
- else
- {
- EmitLoadFromRegister(context, op.Rn);
- }
-
- if ((accType & AccessType.Load) != 0)
- {
- if ((accType & AccessType.Signed) != 0)
- {
- EmitReadSx32Call(context, size);
- }
- else
- {
- EmitReadZxCall(context, size);
- }
-
- if (op.WBack)
- {
- context.EmitLdtmp();
-
- EmitStoreToRegister(context, op.Rn);
- }
-
- if (size == DWordSizeLog2)
- {
- context.Emit(OpCodes.Dup);
-
- context.EmitLdflg((int)PState.EBit);
-
- ILLabel lblBigEndian = new ILLabel();
- ILLabel lblEnd = new ILLabel();
-
- context.Emit(OpCodes.Brtrue_S, lblBigEndian);
-
- // Little endian mode.
- context.Emit(OpCodes.Conv_U4);
-
- EmitStoreToRegister(context, op.Rt);
-
- context.EmitLsr(32);
-
- context.Emit(OpCodes.Conv_U4);
-
- EmitStoreToRegister(context, op.Rt | 1);
-
- context.Emit(OpCodes.Br_S, lblEnd);
-
- // Big endian mode.
- context.MarkLabel(lblBigEndian);
-
- context.EmitLsr(32);
-
- context.Emit(OpCodes.Conv_U4);
-
- EmitStoreToRegister(context, op.Rt);
-
- context.Emit(OpCodes.Conv_U4);
-
- EmitStoreToRegister(context, op.Rt | 1);
-
- context.MarkLabel(lblEnd);
- }
- else
- {
- EmitStoreToRegister(context, op.Rt);
- }
- }
- else
- {
- if (op.WBack)
- {
- context.EmitLdtmp();
-
- EmitStoreToRegister(context, op.Rn);
- }
-
- EmitLoadFromRegister(context, op.Rt);
-
- if (size == DWordSizeLog2)
- {
- context.Emit(OpCodes.Conv_U8);
-
- context.EmitLdflg((int)PState.EBit);
-
- ILLabel lblBigEndian = new ILLabel();
- ILLabel lblEnd = new ILLabel();
-
- context.Emit(OpCodes.Brtrue_S, lblBigEndian);
-
- // Little endian mode.
- EmitLoadFromRegister(context, op.Rt | 1);
-
- context.Emit(OpCodes.Conv_U8);
-
- context.EmitLsl(32);
-
- context.Emit(OpCodes.Or);
-
- context.Emit(OpCodes.Br_S, lblEnd);
-
- // Big endian mode.
- context.MarkLabel(lblBigEndian);
-
- context.EmitLsl(32);
-
- EmitLoadFromRegister(context, op.Rt | 1);
-
- context.Emit(OpCodes.Conv_U8);
-
- context.Emit(OpCodes.Or);
-
- context.MarkLabel(lblEnd);
- }
-
- EmitWriteCall(context, size);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Instructions/InstEmitMemoryEx.cs b/ChocolArm64/Instructions/InstEmitMemoryEx.cs
deleted file mode 100644
index 5deb035d72..0000000000
--- a/ChocolArm64/Instructions/InstEmitMemoryEx.cs
+++ /dev/null
@@ -1,350 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.IntermediateRepresentation;
-using ChocolArm64.Memory;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System;
-using System.Reflection.Emit;
-using System.Threading;
-
-using static ChocolArm64.Instructions.InstEmitMemoryHelper;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
- [Flags]
- private enum AccessType
- {
- None = 0,
- Ordered = 1,
- Exclusive = 2,
- OrderedEx = Ordered | Exclusive
- }
-
- public static void Clrex(ILEmitterCtx context)
- {
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- context.EmitPrivateCall(typeof(CpuThreadState), nameof(CpuThreadState.ClearExclusiveAddress));
- }
-
- public static void Dmb(ILEmitterCtx context) => EmitBarrier(context);
- public static void Dsb(ILEmitterCtx context) => EmitBarrier(context);
-
- public static void Ldar(ILEmitterCtx context) => EmitLdr(context, AccessType.Ordered);
- public static void Ldaxr(ILEmitterCtx context) => EmitLdr(context, AccessType.OrderedEx);
- public static void Ldxr(ILEmitterCtx context) => EmitLdr(context, AccessType.Exclusive);
- public static void Ldxp(ILEmitterCtx context) => EmitLdp(context, AccessType.Exclusive);
- public static void Ldaxp(ILEmitterCtx context) => EmitLdp(context, AccessType.OrderedEx);
-
- private static void EmitLdr(ILEmitterCtx context, AccessType accType)
- {
- EmitLoad(context, accType, pair: false);
- }
-
- private static void EmitLdp(ILEmitterCtx context, AccessType accType)
- {
- EmitLoad(context, accType, pair: true);
- }
-
- private static void EmitLoad(ILEmitterCtx context, AccessType accType, bool pair)
- {
- OpCodeMemEx64 op = (OpCodeMemEx64)context.CurrOp;
-
- bool ordered = (accType & AccessType.Ordered) != 0;
- bool exclusive = (accType & AccessType.Exclusive) != 0;
-
- if (ordered)
- {
- EmitBarrier(context);
- }
-
- context.EmitLdint(op.Rn);
- context.EmitSttmp();
-
- if (exclusive)
- {
- context.EmitLdarg(TranslatedSub.StateArgIdx);
- context.EmitLdtmp();
-
- context.EmitPrivateCall(typeof(CpuThreadState), nameof(CpuThreadState.SetExclusiveAddress));
- }
-
- void WriteExclusiveValue(string propName)
- {
- context.Emit(OpCodes.Dup);
-
- if (op.Size < 3)
- {
- context.Emit(OpCodes.Conv_U8);
- }
-
- context.EmitSttmp2();
- context.EmitLdarg(TranslatedSub.StateArgIdx);
- context.EmitLdtmp2();
-
- context.EmitCallPrivatePropSet(typeof(CpuThreadState), propName);
- }
-
- if (pair)
- {
- // Exclusive loads should be atomic. For pairwise loads, we need to
- // read all the data at once. For a 32-bits pairwise load, we do a
- // simple 64-bits load, for a 128-bits load, we need to call a special
- // method to read 128-bits atomically.
- if (op.Size == 2)
- {
- context.EmitLdtmp();
-
- EmitReadZxCall(context, 3);
-
- context.Emit(OpCodes.Dup);
-
- // Mask low half.
- context.Emit(OpCodes.Conv_U4);
-
- if (exclusive)
- {
- WriteExclusiveValue(nameof(CpuThreadState.ExclusiveValueLow));
- }
-
- context.EmitStintzr(op.Rt);
-
- // Shift high half.
- context.EmitLsr(32);
- context.Emit(OpCodes.Conv_U4);
-
- if (exclusive)
- {
- WriteExclusiveValue(nameof(CpuThreadState.ExclusiveValueHigh));
- }
-
- context.EmitStintzr(op.Rt2);
- }
- else if (op.Size == 3)
- {
- context.EmitLdarg(TranslatedSub.MemoryArgIdx);
- context.EmitLdtmp();
-
- context.EmitPrivateCall(typeof(MemoryManager), nameof(MemoryManager.AtomicReadInt128));
-
- context.Emit(OpCodes.Dup);
-
- // Load low part of the vector.
- context.EmitLdc_I4(0);
- context.EmitLdc_I4(3);
-
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorExtractIntZx));
-
- if (exclusive)
- {
- WriteExclusiveValue(nameof(CpuThreadState.ExclusiveValueLow));
- }
-
- context.EmitStintzr(op.Rt);
-
- // Load high part of the vector.
- context.EmitLdc_I4(1);
- context.EmitLdc_I4(3);
-
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorExtractIntZx));
-
- if (exclusive)
- {
- WriteExclusiveValue(nameof(CpuThreadState.ExclusiveValueHigh));
- }
-
- context.EmitStintzr(op.Rt2);
- }
- else
- {
- throw new InvalidOperationException($"Invalid load size of {1 << op.Size} bytes.");
- }
- }
- else
- {
- // 8, 16, 32 or 64-bits (non-pairwise) load.
- context.EmitLdtmp();
-
- EmitReadZxCall(context, op.Size);
-
- if (exclusive)
- {
- WriteExclusiveValue(nameof(CpuThreadState.ExclusiveValueLow));
- }
-
- context.EmitStintzr(op.Rt);
- }
- }
-
- public static void Pfrm(ILEmitterCtx context)
- {
- // Memory Prefetch, execute as no-op.
- }
-
- public static void Stlr(ILEmitterCtx context) => EmitStr(context, AccessType.Ordered);
- public static void Stlxr(ILEmitterCtx context) => EmitStr(context, AccessType.OrderedEx);
- public static void Stxr(ILEmitterCtx context) => EmitStr(context, AccessType.Exclusive);
- public static void Stxp(ILEmitterCtx context) => EmitStp(context, AccessType.Exclusive);
- public static void Stlxp(ILEmitterCtx context) => EmitStp(context, AccessType.OrderedEx);
-
- private static void EmitStr(ILEmitterCtx context, AccessType accType)
- {
- EmitStore(context, accType, pair: false);
- }
-
- private static void EmitStp(ILEmitterCtx context, AccessType accType)
- {
- EmitStore(context, accType, pair: true);
- }
-
- private static void EmitStore(ILEmitterCtx context, AccessType accType, bool pair)
- {
- OpCodeMemEx64 op = (OpCodeMemEx64)context.CurrOp;
-
- bool ordered = (accType & AccessType.Ordered) != 0;
- bool exclusive = (accType & AccessType.Exclusive) != 0;
-
- if (ordered)
- {
- EmitBarrier(context);
- }
-
- if (exclusive)
- {
- ILLabel lblEx = new ILLabel();
- ILLabel lblEnd = new ILLabel();
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
- context.EmitLdint(op.Rn);
-
- context.EmitPrivateCall(typeof(CpuThreadState), nameof(CpuThreadState.CheckExclusiveAddress));
-
- context.Emit(OpCodes.Brtrue_S, lblEx);
-
- // Address check failed, set error right away and do not store anything.
- context.EmitLdc_I4(1);
- context.EmitStintzr(op.Rs);
-
- context.Emit(OpCodes.Br, lblEnd);
-
- // Address check passed.
- context.MarkLabel(lblEx);
-
- context.EmitLdarg(TranslatedSub.MemoryArgIdx);
- context.EmitLdint(op.Rn);
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- context.EmitCallPrivatePropGet(typeof(CpuThreadState), nameof(CpuThreadState.ExclusiveValueLow));
-
- void EmitCast()
- {
- // The input should be always int64.
- switch (op.Size)
- {
- case 0: context.Emit(OpCodes.Conv_U1); break;
- case 1: context.Emit(OpCodes.Conv_U2); break;
- case 2: context.Emit(OpCodes.Conv_U4); break;
- }
- }
-
- EmitCast();
-
- if (pair)
- {
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- context.EmitCallPrivatePropGet(typeof(CpuThreadState), nameof(CpuThreadState.ExclusiveValueHigh));
-
- EmitCast();
-
- context.EmitLdintzr(op.Rt);
-
- EmitCast();
-
- context.EmitLdintzr(op.Rt2);
-
- EmitCast();
-
- switch (op.Size)
- {
- case 2: context.EmitPrivateCall(typeof(MemoryManager), nameof(MemoryManager.AtomicCompareExchange2xInt32)); break;
- case 3: context.EmitPrivateCall(typeof(MemoryManager), nameof(MemoryManager.AtomicCompareExchangeInt128)); break;
-
- default: throw new InvalidOperationException($"Invalid store size of {1 << op.Size} bytes.");
- }
- }
- else
- {
- context.EmitLdintzr(op.Rt);
-
- EmitCast();
-
- switch (op.Size)
- {
- case 0: context.EmitCall(typeof(MemoryManager), nameof(MemoryManager.AtomicCompareExchangeByte)); break;
- case 1: context.EmitCall(typeof(MemoryManager), nameof(MemoryManager.AtomicCompareExchangeInt16)); break;
- case 2: context.EmitCall(typeof(MemoryManager), nameof(MemoryManager.AtomicCompareExchangeInt32)); break;
- case 3: context.EmitCall(typeof(MemoryManager), nameof(MemoryManager.AtomicCompareExchangeInt64)); break;
-
- default: throw new InvalidOperationException($"Invalid store size of {1 << op.Size} bytes.");
- }
- }
-
- // The value returned is a bool, true if the values compared
- // were equal and the new value was written, false otherwise.
- // We need to invert this result, as on ARM 1 indicates failure,
- // and 0 success on those instructions.
- context.EmitLdc_I4(1);
-
- context.Emit(OpCodes.Xor);
- context.Emit(OpCodes.Dup);
- context.Emit(OpCodes.Conv_U8);
-
- context.EmitStintzr(op.Rs);
-
- // Only clear the exclusive monitor if the store was successful (Rs = false).
- context.Emit(OpCodes.Brtrue_S, lblEnd);
-
- Clrex(context);
-
- context.MarkLabel(lblEnd);
- }
- else
- {
- void EmitWriteCall(int rt, long offset)
- {
- context.EmitLdint(op.Rn);
-
- if (offset != 0)
- {
- context.EmitLdc_I8(offset);
-
- context.Emit(OpCodes.Add);
- }
-
- context.EmitLdintzr(rt);
-
- InstEmitMemoryHelper.EmitWriteCall(context, op.Size);
- }
-
- EmitWriteCall(op.Rt, 0);
-
- if (pair)
- {
- EmitWriteCall(op.Rt2, 1 << op.Size);
- }
- }
- }
-
- private static void EmitBarrier(ILEmitterCtx context)
- {
- // Note: This barrier is most likely not necessary, and probably
- // doesn't make any difference since we need to do a ton of stuff
- // (software MMU emulation) to read or write anything anyway.
- context.EmitCall(typeof(Thread), nameof(Thread.MemoryBarrier));
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Instructions/InstEmitMemoryHelper.cs b/ChocolArm64/Instructions/InstEmitMemoryHelper.cs
deleted file mode 100644
index 08c8265b52..0000000000
--- a/ChocolArm64/Instructions/InstEmitMemoryHelper.cs
+++ /dev/null
@@ -1,475 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.IntermediateRepresentation;
-using ChocolArm64.Memory;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System;
-using System.Reflection.Emit;
-using System.Runtime.Intrinsics.X86;
-
-namespace ChocolArm64.Instructions
-{
- static class InstEmitMemoryHelper
- {
- private static int _tempIntAddress = ILEmitterCtx.GetIntTempIndex();
- private static int _tempIntValue = ILEmitterCtx.GetIntTempIndex();
- private static int _tempIntPtAddr = ILEmitterCtx.GetIntTempIndex();
- private static int _tempVecValue = ILEmitterCtx.GetVecTempIndex();
-
- private enum Extension
- {
- Zx,
- Sx32,
- Sx64
- }
-
- public static void EmitReadZxCall(ILEmitterCtx context, int size)
- {
- EmitReadCall(context, Extension.Zx, size);
- }
-
- public static void EmitReadSx32Call(ILEmitterCtx context, int size)
- {
- EmitReadCall(context, Extension.Sx32, size);
- }
-
- public static void EmitReadSx64Call(ILEmitterCtx context, int size)
- {
- EmitReadCall(context, Extension.Sx64, size);
- }
-
- private static void EmitReadCall(ILEmitterCtx context, Extension ext, int size)
- {
- // Save the address into a temp.
- context.EmitStint(_tempIntAddress);
-
- bool isSimd = IsSimd(context);
-
- if (size < 0 || size > (isSimd ? 4 : 3))
- {
- throw new ArgumentOutOfRangeException(nameof(size));
- }
-
- if (isSimd)
- {
- if (context.Tier == TranslationTier.Tier0 || !Sse2.IsSupported || size < 2)
- {
- EmitReadVectorFallback(context, size);
- }
- else
- {
- EmitReadVector(context, size);
- }
- }
- else
- {
- if (context.Tier == TranslationTier.Tier0)
- {
- EmitReadIntFallback(context, size);
- }
- else
- {
- EmitReadInt(context, size);
- }
- }
-
- if (!isSimd)
- {
- if (ext == Extension.Sx32 ||
- ext == Extension.Sx64)
- {
- switch (size)
- {
- case 0: context.Emit(OpCodes.Conv_I1); break;
- case 1: context.Emit(OpCodes.Conv_I2); break;
- case 2: context.Emit(OpCodes.Conv_I4); break;
- }
- }
-
- if (size < 3)
- {
- context.Emit(ext == Extension.Sx64
- ? OpCodes.Conv_I8
- : OpCodes.Conv_U8);
- }
- }
- }
-
- public static void EmitWriteCall(ILEmitterCtx context, int size)
- {
- bool isSimd = IsSimd(context);
-
- // Save the value into a temp.
- if (isSimd)
- {
- context.EmitStvec(_tempVecValue);
- }
- else
- {
- context.EmitStint(_tempIntValue);
- }
-
- // Save the address into a temp.
- context.EmitStint(_tempIntAddress);
-
- if (size < 0 || size > (isSimd ? 4 : 3))
- {
- throw new ArgumentOutOfRangeException(nameof(size));
- }
-
- if (isSimd)
- {
- if (context.Tier == TranslationTier.Tier0 || !Sse2.IsSupported || size < 2)
- {
- EmitWriteVectorFallback(context, size);
- }
- else
- {
- EmitWriteVector(context, size);
- }
- }
- else
- {
- if (context.Tier == TranslationTier.Tier0)
- {
- EmitWriteIntFallback(context, size);
- }
- else
- {
- EmitWriteInt(context, size);
- }
- }
- }
-
- private static bool IsSimd(ILEmitterCtx context)
- {
- return context.CurrOp is IOpCodeSimd64 &&
- !(context.CurrOp is OpCodeSimdMemMs64 ||
- context.CurrOp is OpCodeSimdMemSs64);
- }
-
- private static void EmitReadInt(ILEmitterCtx context, int size)
- {
- EmitAddressCheck(context, size);
-
- ILLabel lblFastPath = new ILLabel();
- ILLabel lblSlowPath = new ILLabel();
- ILLabel lblEnd = new ILLabel();
-
- context.Emit(OpCodes.Brfalse_S, lblFastPath);
-
- context.MarkLabel(lblSlowPath);
-
- EmitReadIntFallback(context, size);
-
- context.Emit(OpCodes.Br, lblEnd);
-
- context.MarkLabel(lblFastPath);
-
- EmitPtPointerLoad(context, lblSlowPath);
-
- switch (size)
- {
- case 0: context.Emit(OpCodes.Ldind_U1); break;
- case 1: context.Emit(OpCodes.Ldind_U2); break;
- case 2: context.Emit(OpCodes.Ldind_U4); break;
- case 3: context.Emit(OpCodes.Ldind_I8); break;
- }
-
- context.MarkLabel(lblEnd);
- }
-
- private static void EmitReadVector(ILEmitterCtx context, int size)
- {
- EmitAddressCheck(context, size);
-
- ILLabel lblFastPath = new ILLabel();
- ILLabel lblSlowPath = new ILLabel();
- ILLabel lblEnd = new ILLabel();
-
- context.Emit(OpCodes.Brfalse_S, lblFastPath);
-
- context.MarkLabel(lblSlowPath);
-
- EmitReadVectorFallback(context, size);
-
- context.Emit(OpCodes.Br, lblEnd);
-
- context.MarkLabel(lblFastPath);
-
- EmitPtPointerLoad(context, lblSlowPath);
-
- switch (size)
- {
- case 2: context.EmitCall(typeof(Sse), nameof(Sse.LoadScalarVector128)); break;
-
- case 3:
- {
- Type[] types = new Type[] { typeof(double*) };
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.LoadScalarVector128), types));
-
- break;
- }
-
- case 4: context.EmitCall(typeof(Sse), nameof(Sse.LoadAlignedVector128)); break;
-
- throw new InvalidOperationException($"Invalid vector load size of {1 << size} bytes.");
- }
-
- context.MarkLabel(lblEnd);
- }
-
- private static void EmitWriteInt(ILEmitterCtx context, int size)
- {
- EmitAddressCheck(context, size);
-
- ILLabel lblFastPath = new ILLabel();
- ILLabel lblSlowPath = new ILLabel();
- ILLabel lblEnd = new ILLabel();
-
- context.Emit(OpCodes.Brfalse_S, lblFastPath);
-
- context.MarkLabel(lblSlowPath);
-
- EmitWriteIntFallback(context, size);
-
- context.Emit(OpCodes.Br, lblEnd);
-
- context.MarkLabel(lblFastPath);
-
- EmitPtPointerLoad(context, lblSlowPath);
-
- context.EmitLdint(_tempIntValue);
-
- if (size < 3)
- {
- context.Emit(OpCodes.Conv_U4);
- }
-
- switch (size)
- {
- case 0: context.Emit(OpCodes.Stind_I1); break;
- case 1: context.Emit(OpCodes.Stind_I2); break;
- case 2: context.Emit(OpCodes.Stind_I4); break;
- case 3: context.Emit(OpCodes.Stind_I8); break;
- }
-
- context.MarkLabel(lblEnd);
- }
-
- private static void EmitWriteVector(ILEmitterCtx context, int size)
- {
- EmitAddressCheck(context, size);
-
- ILLabel lblFastPath = new ILLabel();
- ILLabel lblSlowPath = new ILLabel();
- ILLabel lblEnd = new ILLabel();
-
- context.Emit(OpCodes.Brfalse_S, lblFastPath);
-
- context.MarkLabel(lblSlowPath);
-
- EmitWriteVectorFallback(context, size);
-
- context.Emit(OpCodes.Br, lblEnd);
-
- context.MarkLabel(lblFastPath);
-
- EmitPtPointerLoad(context, lblSlowPath);
-
- context.EmitLdvec(_tempVecValue);
-
- switch (size)
- {
- case 2: context.EmitCall(typeof(Sse), nameof(Sse.StoreScalar)); break;
- case 3: context.EmitCall(typeof(Sse2), nameof(Sse2.StoreScalar)); break;
- case 4: context.EmitCall(typeof(Sse), nameof(Sse.StoreAligned)); break;
-
- default: throw new InvalidOperationException($"Invalid vector store size of {1 << size} bytes.");
- }
-
- context.MarkLabel(lblEnd);
- }
-
- private static void EmitAddressCheck(ILEmitterCtx context, int size)
- {
- long addressCheckMask = ~(context.Memory.AddressSpaceSize - 1);
-
- addressCheckMask |= (1u << size) - 1;
-
- context.EmitLdint(_tempIntAddress);
-
- context.EmitLdc_I(addressCheckMask);
-
- context.Emit(OpCodes.And);
- }
-
- private static void EmitPtPointerLoad(ILEmitterCtx context, ILLabel lblFallbackPath)
- {
- context.EmitLdc_I8(context.Memory.PageTable.ToInt64());
-
- context.Emit(OpCodes.Conv_I);
-
- int bit = MemoryManager.PageBits;
-
- do
- {
- context.EmitLdint(_tempIntAddress);
-
- if (context.CurrOp.RegisterSize == RegisterSize.Int32)
- {
- context.Emit(OpCodes.Conv_U8);
- }
-
- context.EmitLsr(bit);
-
- bit += context.Memory.PtLevelBits;
-
- if (bit < context.Memory.AddressSpaceBits)
- {
- context.EmitLdc_I8(context.Memory.PtLevelMask);
-
- context.Emit(OpCodes.And);
- }
-
- context.EmitLdc_I8(IntPtr.Size);
-
- context.Emit(OpCodes.Mul);
- context.Emit(OpCodes.Conv_I);
- context.Emit(OpCodes.Add);
- context.Emit(OpCodes.Ldind_I);
- }
- while (bit < context.Memory.AddressSpaceBits);
-
- if (!context.Memory.HasWriteWatchSupport)
- {
- context.Emit(OpCodes.Conv_U8);
-
- context.EmitStint(_tempIntPtAddr);
- context.EmitLdint(_tempIntPtAddr);
-
- context.EmitLdc_I8(MemoryManager.PteFlagsMask);
-
- context.Emit(OpCodes.And);
-
- context.Emit(OpCodes.Brtrue, lblFallbackPath);
-
- context.EmitLdint(_tempIntPtAddr);
-
- context.Emit(OpCodes.Conv_I);
- }
-
- context.EmitLdint(_tempIntAddress);
-
- context.EmitLdc_I(MemoryManager.PageMask);
-
- context.Emit(OpCodes.And);
- context.Emit(OpCodes.Conv_I);
- context.Emit(OpCodes.Add);
- }
-
- private static void EmitReadIntFallback(ILEmitterCtx context, int size)
- {
- context.EmitLdarg(TranslatedSub.MemoryArgIdx);
- context.EmitLdint(_tempIntAddress);
-
- if (context.CurrOp.RegisterSize == RegisterSize.Int32)
- {
- context.Emit(OpCodes.Conv_U8);
- }
-
- string fallbackMethodName = null;
-
- switch (size)
- {
- case 0: fallbackMethodName = nameof(MemoryManager.ReadByte); break;
- case 1: fallbackMethodName = nameof(MemoryManager.ReadUInt16); break;
- case 2: fallbackMethodName = nameof(MemoryManager.ReadUInt32); break;
- case 3: fallbackMethodName = nameof(MemoryManager.ReadUInt64); break;
- }
-
- context.EmitCall(typeof(MemoryManager), fallbackMethodName);
- }
-
- private static void EmitReadVectorFallback(ILEmitterCtx context, int size)
- {
- context.EmitLdarg(TranslatedSub.MemoryArgIdx);
- context.EmitLdint(_tempIntAddress);
-
- if (context.CurrOp.RegisterSize == RegisterSize.Int32)
- {
- context.Emit(OpCodes.Conv_U8);
- }
-
- string fallbackMethodName = null;
-
- switch (size)
- {
- case 0: fallbackMethodName = nameof(MemoryManager.ReadVector8); break;
- case 1: fallbackMethodName = nameof(MemoryManager.ReadVector16); break;
- case 2: fallbackMethodName = nameof(MemoryManager.ReadVector32); break;
- case 3: fallbackMethodName = nameof(MemoryManager.ReadVector64); break;
- case 4: fallbackMethodName = nameof(MemoryManager.ReadVector128); break;
- }
-
- context.EmitCall(typeof(MemoryManager), fallbackMethodName);
- }
-
- private static void EmitWriteIntFallback(ILEmitterCtx context, int size)
- {
- context.EmitLdarg(TranslatedSub.MemoryArgIdx);
- context.EmitLdint(_tempIntAddress);
-
- if (context.CurrOp.RegisterSize == RegisterSize.Int32)
- {
- context.Emit(OpCodes.Conv_U8);
- }
-
- context.EmitLdint(_tempIntValue);
-
- if (size < 3)
- {
- context.Emit(OpCodes.Conv_U4);
- }
-
- string fallbackMethodName = null;
-
- switch (size)
- {
- case 0: fallbackMethodName = nameof(MemoryManager.WriteByte); break;
- case 1: fallbackMethodName = nameof(MemoryManager.WriteUInt16); break;
- case 2: fallbackMethodName = nameof(MemoryManager.WriteUInt32); break;
- case 3: fallbackMethodName = nameof(MemoryManager.WriteUInt64); break;
- }
-
- context.EmitCall(typeof(MemoryManager), fallbackMethodName);
- }
-
- private static void EmitWriteVectorFallback(ILEmitterCtx context, int size)
- {
- context.EmitLdarg(TranslatedSub.MemoryArgIdx);
- context.EmitLdint(_tempIntAddress);
-
- if (context.CurrOp.RegisterSize == RegisterSize.Int32)
- {
- context.Emit(OpCodes.Conv_U8);
- }
-
- context.EmitLdvec(_tempVecValue);
-
- string fallbackMethodName = null;
-
- switch (size)
- {
- case 0: fallbackMethodName = nameof(MemoryManager.WriteVector8); break;
- case 1: fallbackMethodName = nameof(MemoryManager.WriteVector16); break;
- case 2: fallbackMethodName = nameof(MemoryManager.WriteVector32); break;
- case 3: fallbackMethodName = nameof(MemoryManager.WriteVector64); break;
- case 4: fallbackMethodName = nameof(MemoryManager.WriteVector128Internal); break;
- }
-
- context.EmitCall(typeof(MemoryManager), fallbackMethodName);
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Instructions/InstEmitMove.cs b/ChocolArm64/Instructions/InstEmitMove.cs
deleted file mode 100644
index be3e8e2d31..0000000000
--- a/ChocolArm64/Instructions/InstEmitMove.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.Translation;
-using System.Reflection.Emit;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
- public static void Movk(ILEmitterCtx context)
- {
- OpCodeMov64 op = (OpCodeMov64)context.CurrOp;
-
- context.EmitLdintzr(op.Rd);
- context.EmitLdc_I(~(0xffffL << op.Pos));
-
- context.Emit(OpCodes.And);
-
- context.EmitLdc_I(op.Imm);
-
- context.Emit(OpCodes.Or);
-
- context.EmitStintzr(op.Rd);
- }
-
- public static void Movn(ILEmitterCtx context)
- {
- OpCodeMov64 op = (OpCodeMov64)context.CurrOp;
-
- context.EmitLdc_I(~op.Imm);
- context.EmitStintzr(op.Rd);
- }
-
- public static void Movz(ILEmitterCtx context)
- {
- OpCodeMov64 op = (OpCodeMov64)context.CurrOp;
-
- context.EmitLdc_I(op.Imm);
- context.EmitStintzr(op.Rd);
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Instructions/InstEmitMul.cs b/ChocolArm64/Instructions/InstEmitMul.cs
deleted file mode 100644
index b7418e6922..0000000000
--- a/ChocolArm64/Instructions/InstEmitMul.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.Translation;
-using System.Reflection.Emit;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
- public static void Madd(ILEmitterCtx context) => EmitMul(context, OpCodes.Add);
- public static void Msub(ILEmitterCtx context) => EmitMul(context, OpCodes.Sub);
-
- private static void EmitMul(ILEmitterCtx context, OpCode ilOp)
- {
- OpCodeMul64 op = (OpCodeMul64)context.CurrOp;
-
- context.EmitLdintzr(op.Ra);
- context.EmitLdintzr(op.Rn);
- context.EmitLdintzr(op.Rm);
-
- context.Emit(OpCodes.Mul);
- context.Emit(ilOp);
-
- context.EmitStintzr(op.Rd);
- }
-
- public static void Smaddl(ILEmitterCtx context) => EmitMull(context, OpCodes.Add, true);
- public static void Smsubl(ILEmitterCtx context) => EmitMull(context, OpCodes.Sub, true);
- public static void Umaddl(ILEmitterCtx context) => EmitMull(context, OpCodes.Add, false);
- public static void Umsubl(ILEmitterCtx context) => EmitMull(context, OpCodes.Sub, false);
-
- private static void EmitMull(ILEmitterCtx context, OpCode addSubOp, bool signed)
- {
- OpCodeMul64 op = (OpCodeMul64)context.CurrOp;
-
- OpCode castOp = signed
- ? OpCodes.Conv_I8
- : OpCodes.Conv_U8;
-
- context.EmitLdintzr(op.Ra);
- context.EmitLdintzr(op.Rn);
-
- context.Emit(OpCodes.Conv_I4);
- context.Emit(castOp);
-
- context.EmitLdintzr(op.Rm);
-
- context.Emit(OpCodes.Conv_I4);
- context.Emit(castOp);
- context.Emit(OpCodes.Mul);
-
- context.Emit(addSubOp);
-
- context.EmitStintzr(op.Rd);
- }
-
- public static void Smulh(ILEmitterCtx context)
- {
- OpCodeMul64 op = (OpCodeMul64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
- context.EmitLdintzr(op.Rm);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.SMulHi128));
-
- context.EmitStintzr(op.Rd);
- }
-
- public static void Umulh(ILEmitterCtx context)
- {
- OpCodeMul64 op = (OpCodeMul64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
- context.EmitLdintzr(op.Rm);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.UMulHi128));
-
- context.EmitStintzr(op.Rd);
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Instructions/InstEmitSimdArithmetic.cs b/ChocolArm64/Instructions/InstEmitSimdArithmetic.cs
deleted file mode 100644
index fa9666eb5f..0000000000
--- a/ChocolArm64/Instructions/InstEmitSimdArithmetic.cs
+++ /dev/null
@@ -1,3797 +0,0 @@
-// https://github.com/intel/ARM_NEON_2_x86_SSE/blob/master/NEON_2_SSE.h
-// https://www.agner.org/optimize/#vectorclass @ vectori128.h
-
-using ChocolArm64.Decoders;
-using ChocolArm64.IntermediateRepresentation;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System;
-using System.Reflection;
-using System.Reflection.Emit;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-using static ChocolArm64.Instructions.InstEmitSimdHelper;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
- public static void Abs_S(ILEmitterCtx context)
- {
- EmitScalarUnaryOpSx(context, () => EmitAbs(context));
- }
-
- public static void Abs_V(ILEmitterCtx context)
- {
- EmitVectorUnaryOpSx(context, () => EmitAbs(context));
- }
-
- public static void Add_S(ILEmitterCtx context)
- {
- EmitScalarBinaryOpZx(context, () => context.Emit(OpCodes.Add));
- }
-
- public static void Add_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse2)
- {
- EmitSse2Op(context, nameof(Sse2.Add));
- }
- else
- {
- EmitVectorBinaryOpZx(context, () => context.Emit(OpCodes.Add));
- }
- }
-
- public static void Addhn_V(ILEmitterCtx context)
- {
- EmitHighNarrow(context, () => context.Emit(OpCodes.Add), round: false);
- }
-
- public static void Addp_S(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- EmitVectorExtractZx(context, op.Rn, 0, op.Size);
- EmitVectorExtractZx(context, op.Rn, 1, op.Size);
-
- context.Emit(OpCodes.Add);
-
- EmitScalarSet(context, op.Rd, op.Size);
- }
-
- public static void Addp_V(ILEmitterCtx context)
- {
- EmitVectorPairwiseOpZx(context, () => context.Emit(OpCodes.Add));
- }
-
- public static void Addv_V(ILEmitterCtx context)
- {
- EmitVectorAcrossVectorOpZx(context, () => context.Emit(OpCodes.Add));
- }
-
- public static void Cls_V(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> op.Size;
-
- int eSize = 8 << op.Size;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractZx(context, op.Rn, index, op.Size);
-
- context.EmitLdc_I4(eSize);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.CountLeadingSigns));
-
- EmitVectorInsert(context, op.Rd, index, op.Size);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void Clz_V(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> op.Size;
-
- int eSize = 8 << op.Size;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractZx(context, op.Rn, index, op.Size);
-
- if (Lzcnt.IsSupported && eSize == 32)
- {
- context.Emit(OpCodes.Conv_U4);
-
- context.EmitCall(typeof(Lzcnt).GetMethod(nameof(Lzcnt.LeadingZeroCount), new Type[] { typeof(uint) }));
-
- context.Emit(OpCodes.Conv_U8);
- }
- else
- {
- context.EmitLdc_I4(eSize);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.CountLeadingZeros));
- }
-
- EmitVectorInsert(context, op.Rd, index, op.Size);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void Cnt_V(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int elems = op.RegisterSize == RegisterSize.Simd128 ? 16 : 8;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractZx(context, op.Rn, index, 0);
-
- if (Popcnt.IsSupported)
- {
- context.EmitCall(typeof(Popcnt).GetMethod(nameof(Popcnt.PopCount), new Type[] { typeof(ulong) }));
- }
- else
- {
- SoftFallback.EmitCall(context, nameof(SoftFallback.CountSetBits8));
- }
-
- EmitVectorInsert(context, op.Rd, index, 0);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void Fabd_S(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (sizeF == 0)
- {
- Type[] typesSsv = new Type[] { typeof(float) };
- Type[] typesSubAnt = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdc_R4(-0f);
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.SetScalarVector128), typesSsv));
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.SubtractScalar), typesSubAnt));
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.AndNot), typesSubAnt));
-
- context.EmitStvec(op.Rd);
-
- EmitVectorZero32_128(context, op.Rd);
- }
- else /* if (sizeF == 1) */
- {
- Type[] typesSsv = new Type[] { typeof(double) };
- Type[] typesSubAnt = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdc_R8(-0d);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetScalarVector128), typesSsv));
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SubtractScalar), typesSubAnt));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesSubAnt));
-
- context.EmitStvec(op.Rd);
-
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitScalarBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub));
-
- EmitUnaryMathCall(context, nameof(Math.Abs));
- });
- }
- }
-
- public static void Fabd_V(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (sizeF == 0)
- {
- Type[] typesSav = new Type[] { typeof(float) };
- Type[] typesSubAnt = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdc_R4(-0f);
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.SetAllVector128), typesSav));
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Subtract), typesSubAnt));
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.AndNot), typesSubAnt));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else /* if (sizeF == 1) */
- {
- Type[] typesSav = new Type[] { typeof(double) };
- Type[] typesSubAnt = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdc_R8(-0d);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSubAnt));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesSubAnt));
-
- context.EmitStvec(op.Rd);
- }
- }
- else
- {
- EmitVectorBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub));
-
- EmitUnaryMathCall(context, nameof(Math.Abs));
- });
- }
- }
-
- public static void Fabs_S(ILEmitterCtx context)
- {
- if (Optimizations.UseSse2)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- if (op.Size == 0)
- {
- Type[] typesSsv = new Type[] { typeof(float) };
- Type[] typesAnt = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdc_R4(-0f);
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.SetScalarVector128), typesSsv));
-
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.AndNot), typesAnt));
-
- context.EmitStvec(op.Rd);
-
- EmitVectorZero32_128(context, op.Rd);
- }
- else /* if (op.Size == 1) */
- {
- Type[] typesSsv = new Type[] { typeof(double) };
- Type[] typesAnt = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdc_R8(-0d);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetScalarVector128), typesSsv));
-
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAnt));
-
- context.EmitStvec(op.Rd);
-
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitScalarUnaryOpF(context, () =>
- {
- EmitUnaryMathCall(context, nameof(Math.Abs));
- });
- }
- }
-
- public static void Fabs_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse2)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (sizeF == 0)
- {
- Type[] typesSav = new Type[] { typeof(float) };
- Type[] typesAnt = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdc_R4(-0f);
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.SetAllVector128), typesSav));
-
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.AndNot), typesAnt));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else /* if (sizeF == 1) */
- {
- Type[] typesSav = new Type[] { typeof(double) };
- Type[] typesAnt = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdc_R8(-0d);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAnt));
-
- context.EmitStvec(op.Rd);
- }
- }
- else
- {
- EmitVectorUnaryOpF(context, () =>
- {
- EmitUnaryMathCall(context, nameof(Math.Abs));
- });
- }
- }
-
- public static void Fadd_S(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitScalarSseOrSse2OpF(context, nameof(Sse.AddScalar));
- }
- else
- {
- EmitScalarBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPAdd));
- });
- }
- }
-
- public static void Fadd_V(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitVectorSseOrSse2OpF(context, nameof(Sse.Add));
- }
- else
- {
- EmitVectorBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPAdd));
- });
- }
- }
-
- public static void Faddp_S(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (Optimizations.FastFP && Optimizations.UseSse3)
- {
- if (sizeF == 0)
- {
- Type[] typesAddH = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse3).GetMethod(nameof(Sse3.HorizontalAdd), typesAddH));
-
- context.EmitStvec(op.Rd);
-
- EmitVectorZero32_128(context, op.Rd);
- }
- else /* if (sizeF == 1) */
- {
- Type[] typesAddH = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse3).GetMethod(nameof(Sse3.HorizontalAdd), typesAddH));
-
- context.EmitStvec(op.Rd);
-
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorExtractF(context, op.Rn, 0, sizeF);
- EmitVectorExtractF(context, op.Rn, 1, sizeF);
-
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPAdd));
-
- EmitScalarSetF(context, op.Rd, sizeF);
- }
- }
-
- public static void Faddp_V(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitVectorPairwiseSseOrSse2OpF(context, nameof(Sse.Add));
- }
- else
- {
- EmitVectorPairwiseOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPAdd));
- });
- }
- }
-
- public static void Fdiv_S(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitScalarSseOrSse2OpF(context, nameof(Sse.DivideScalar));
- }
- else
- {
- EmitScalarBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPDiv));
- });
- }
- }
-
- public static void Fdiv_V(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitVectorSseOrSse2OpF(context, nameof(Sse.Divide));
- }
- else
- {
- EmitVectorBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPDiv));
- });
- }
- }
-
- public static void Fmadd_S(ILEmitterCtx context) // Fused.
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- if (op.Size == 0)
- {
- Type[] typesMulAdd = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Ra);
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MultiplyScalar), typesMulAdd));
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.AddScalar), typesMulAdd));
-
- context.EmitStvec(op.Rd);
-
- EmitVectorZero32_128(context, op.Rd);
- }
- else /* if (op.Size == 1) */
- {
- Type[] typesMulAdd = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Ra);
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.MultiplyScalar), typesMulAdd));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AddScalar), typesMulAdd));
-
- context.EmitStvec(op.Rd);
-
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitScalarTernaryRaOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulAdd));
- });
- }
- }
-
- public static void Fmax_S(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitScalarSseOrSse2OpF(context, nameof(Sse.MaxScalar));
- }
- else
- {
- EmitScalarBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMax));
- });
- }
- }
-
- public static void Fmax_V(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitVectorSseOrSse2OpF(context, nameof(Sse.Max));
- }
- else
- {
- EmitVectorBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMax));
- });
- }
- }
-
- public static void Fmaxnm_S(ILEmitterCtx context)
- {
- EmitScalarBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMaxNum));
- });
- }
-
- public static void Fmaxnm_V(ILEmitterCtx context)
- {
- EmitVectorBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMaxNum));
- });
- }
-
- public static void Fmaxp_V(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitVectorPairwiseSseOrSse2OpF(context, nameof(Sse.Max));
- }
- else
- {
- EmitVectorPairwiseOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMax));
- });
- }
- }
-
- public static void Fmin_S(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitScalarSseOrSse2OpF(context, nameof(Sse.MinScalar));
- }
- else
- {
- EmitScalarBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMin));
- });
- }
- }
-
- public static void Fmin_V(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitVectorSseOrSse2OpF(context, nameof(Sse.Min));
- }
- else
- {
- EmitVectorBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMin));
- });
- }
- }
-
- public static void Fminnm_S(ILEmitterCtx context)
- {
- EmitScalarBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMinNum));
- });
- }
-
- public static void Fminnm_V(ILEmitterCtx context)
- {
- EmitVectorBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMinNum));
- });
- }
-
- public static void Fminp_V(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitVectorPairwiseSseOrSse2OpF(context, nameof(Sse.Min));
- }
- else
- {
- EmitVectorPairwiseOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMin));
- });
- }
- }
-
- public static void Fmla_Se(ILEmitterCtx context)
- {
- EmitScalarTernaryOpByElemF(context, () =>
- {
- context.Emit(OpCodes.Mul);
- context.Emit(OpCodes.Add);
- });
- }
-
- public static void Fmla_V(ILEmitterCtx context) // Fused.
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (sizeF == 0)
- {
- Type[] typesMulAdd = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesMulAdd));
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Add), typesMulAdd));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else /* if (sizeF == 1) */
- {
- Type[] typesMulAdd = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulAdd));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesMulAdd));
-
- context.EmitStvec(op.Rd);
- }
- }
- else
- {
- EmitVectorTernaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulAdd));
- });
- }
- }
-
- public static void Fmla_Ve(ILEmitterCtx context) // Fused.
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- OpCodeSimdRegElemF64 op = (OpCodeSimdRegElemF64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (sizeF == 0)
- {
- Type[] typesSfl = new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) };
- Type[] typesMulAdd = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
-
- context.EmitLdvec(op.Rm);
- context.EmitLdvec(op.Rm);
-
- context.EmitLdc_I4(op.Index | op.Index << 2 | op.Index << 4 | op.Index << 6);
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Shuffle), typesSfl));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesMulAdd));
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Add), typesMulAdd));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else /* if (sizeF == 1) */
- {
- Type[] typesSfl = new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) };
- Type[] typesMulAdd = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
-
- context.EmitLdvec(op.Rm);
- context.EmitLdvec(op.Rm);
-
- context.EmitLdc_I4(op.Index | op.Index << 1);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Shuffle), typesSfl));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulAdd));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesMulAdd));
-
- context.EmitStvec(op.Rd);
- }
- }
- else
- {
- EmitVectorTernaryOpByElemF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulAdd));
- });
- }
- }
-
- public static void Fmls_Se(ILEmitterCtx context)
- {
- EmitScalarTernaryOpByElemF(context, () =>
- {
- context.Emit(OpCodes.Mul);
- context.Emit(OpCodes.Sub);
- });
- }
-
- public static void Fmls_V(ILEmitterCtx context) // Fused.
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (sizeF == 0)
- {
- Type[] typesMulSub = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesMulSub));
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Subtract), typesMulSub));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else /* if (sizeF == 1) */
- {
- Type[] typesMulSub = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulSub));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesMulSub));
-
- context.EmitStvec(op.Rd);
- }
- }
- else
- {
- EmitVectorTernaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulSub));
- });
- }
- }
-
- public static void Fmls_Ve(ILEmitterCtx context) // Fused.
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- OpCodeSimdRegElemF64 op = (OpCodeSimdRegElemF64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (sizeF == 0)
- {
- Type[] typesSfl = new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) };
- Type[] typesMulSub = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
-
- context.EmitLdvec(op.Rm);
- context.EmitLdvec(op.Rm);
-
- context.EmitLdc_I4(op.Index | op.Index << 2 | op.Index << 4 | op.Index << 6);
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Shuffle), typesSfl));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesMulSub));
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Subtract), typesMulSub));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else /* if (sizeF == 1) */
- {
- Type[] typesSfl = new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) };
- Type[] typesMulSub = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
-
- context.EmitLdvec(op.Rm);
- context.EmitLdvec(op.Rm);
-
- context.EmitLdc_I4(op.Index | op.Index << 1);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Shuffle), typesSfl));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulSub));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesMulSub));
-
- context.EmitStvec(op.Rd);
- }
- }
- else
- {
- EmitVectorTernaryOpByElemF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulSub));
- });
- }
- }
-
- public static void Fmsub_S(ILEmitterCtx context) // Fused.
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- if (op.Size == 0)
- {
- Type[] typesMulSub = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Ra);
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MultiplyScalar), typesMulSub));
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.SubtractScalar), typesMulSub));
-
- context.EmitStvec(op.Rd);
-
- EmitVectorZero32_128(context, op.Rd);
- }
- else /* if (op.Size == 1) */
- {
- Type[] typesMulSub = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Ra);
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.MultiplyScalar), typesMulSub));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SubtractScalar), typesMulSub));
-
- context.EmitStvec(op.Rd);
-
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitScalarTernaryRaOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulSub));
- });
- }
- }
-
- public static void Fmul_S(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitScalarSseOrSse2OpF(context, nameof(Sse.MultiplyScalar));
- }
- else
- {
- EmitScalarBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMul));
- });
- }
- }
-
- public static void Fmul_Se(ILEmitterCtx context)
- {
- EmitScalarBinaryOpByElemF(context, () => context.Emit(OpCodes.Mul));
- }
-
- public static void Fmul_V(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitVectorSseOrSse2OpF(context, nameof(Sse.Multiply));
- }
- else
- {
- EmitVectorBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMul));
- });
- }
- }
-
- public static void Fmul_Ve(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- OpCodeSimdRegElemF64 op = (OpCodeSimdRegElemF64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (sizeF == 0)
- {
- Type[] typesSfl = new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) };
- Type[] typesMul = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rn);
-
- context.EmitLdvec(op.Rm);
- context.EmitLdvec(op.Rm);
-
- context.EmitLdc_I4(op.Index | op.Index << 2 | op.Index << 4 | op.Index << 6);
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Shuffle), typesSfl));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesMul));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else /* if (sizeF == 1) */
- {
- Type[] typesSfl = new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) };
- Type[] typesMul = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rn);
-
- context.EmitLdvec(op.Rm);
- context.EmitLdvec(op.Rm);
-
- context.EmitLdc_I4(op.Index | op.Index << 1);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Shuffle), typesSfl));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMul));
-
- context.EmitStvec(op.Rd);
- }
- }
- else
- {
- EmitVectorBinaryOpByElemF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMul));
- });
- }
- }
-
- public static void Fmulx_S(ILEmitterCtx context)
- {
- EmitScalarBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulX));
- });
- }
-
- public static void Fmulx_Se(ILEmitterCtx context)
- {
- EmitScalarBinaryOpByElemF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulX));
- });
- }
-
- public static void Fmulx_V(ILEmitterCtx context)
- {
- EmitVectorBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulX));
- });
- }
-
- public static void Fmulx_Ve(ILEmitterCtx context)
- {
- EmitVectorBinaryOpByElemF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulX));
- });
- }
-
- public static void Fneg_S(ILEmitterCtx context)
- {
- if (Optimizations.UseSse2)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- if (op.Size == 0)
- {
- Type[] typesSsv = new Type[] { typeof(float) };
- Type[] typesXor = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdc_R4(-0f);
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.SetScalarVector128), typesSsv));
-
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Xor), typesXor));
-
- context.EmitStvec(op.Rd);
-
- EmitVectorZero32_128(context, op.Rd);
- }
- else /* if (op.Size == 1) */
- {
- Type[] typesSsv = new Type[] { typeof(double) };
- Type[] typesXor = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdc_R8(-0d);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetScalarVector128), typesSsv));
-
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), typesXor));
-
- context.EmitStvec(op.Rd);
-
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitScalarUnaryOpF(context, () => context.Emit(OpCodes.Neg));
- }
- }
-
- public static void Fneg_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse2)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (sizeF == 0)
- {
- Type[] typesSav = new Type[] { typeof(float) };
- Type[] typesXor = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdc_R4(-0f);
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.SetAllVector128), typesSav));
-
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Xor), typesXor));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else /* if (sizeF == 1) */
- {
- Type[] typesSav = new Type[] { typeof(double) };
- Type[] typesXor = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdc_R8(-0d);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), typesXor));
-
- context.EmitStvec(op.Rd);
- }
- }
- else
- {
- EmitVectorUnaryOpF(context, () => context.Emit(OpCodes.Neg));
- }
- }
-
- public static void Fnmadd_S(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- EmitVectorExtractF(context, op.Rn, 0, sizeF);
-
- context.Emit(OpCodes.Neg);
-
- EmitVectorExtractF(context, op.Rm, 0, sizeF);
-
- context.Emit(OpCodes.Mul);
-
- EmitVectorExtractF(context, op.Ra, 0, sizeF);
-
- context.Emit(OpCodes.Sub);
-
- EmitScalarSetF(context, op.Rd, sizeF);
- }
-
- public static void Fnmsub_S(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- EmitVectorExtractF(context, op.Rn, 0, sizeF);
- EmitVectorExtractF(context, op.Rm, 0, sizeF);
-
- context.Emit(OpCodes.Mul);
-
- EmitVectorExtractF(context, op.Ra, 0, sizeF);
-
- context.Emit(OpCodes.Sub);
-
- EmitScalarSetF(context, op.Rd, sizeF);
- }
-
- public static void Fnmul_S(ILEmitterCtx context)
- {
- EmitScalarBinaryOpF(context, () =>
- {
- context.Emit(OpCodes.Mul);
- context.Emit(OpCodes.Neg);
- });
- }
-
- public static void Frecpe_S(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (Optimizations.FastFP && Optimizations.UseSse && sizeF == 0)
- {
- EmitScalarSseOrSse2OpF(context, nameof(Sse.ReciprocalScalar));
- }
- else
- {
- EmitScalarUnaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPRecipEstimate));
- });
- }
- }
-
- public static void Frecpe_V(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (Optimizations.FastFP && Optimizations.UseSse && sizeF == 0)
- {
- EmitVectorSseOrSse2OpF(context, nameof(Sse.Reciprocal));
- }
- else
- {
- EmitVectorUnaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPRecipEstimate));
- });
- }
- }
-
- public static void Frecps_S(ILEmitterCtx context) // Fused.
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (sizeF == 0)
- {
- Type[] typesSsv = new Type[] { typeof(float) };
- Type[] typesMulSub = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdc_R4(2f);
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.SetScalarVector128), typesSsv));
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MultiplyScalar), typesMulSub));
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.SubtractScalar), typesMulSub));
-
- context.EmitStvec(op.Rd);
-
- EmitVectorZero32_128(context, op.Rd);
- }
- else /* if (sizeF == 1) */
- {
- Type[] typesSsv = new Type[] { typeof(double) };
- Type[] typesMulSub = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdc_R8(2d);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetScalarVector128), typesSsv));
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.MultiplyScalar), typesMulSub));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SubtractScalar), typesMulSub));
-
- context.EmitStvec(op.Rd);
-
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitScalarBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPRecipStepFused));
- });
- }
- }
-
- public static void Frecps_V(ILEmitterCtx context) // Fused.
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (sizeF == 0)
- {
- Type[] typesSav = new Type[] { typeof(float) };
- Type[] typesMulSub = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdc_R4(2f);
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.SetAllVector128), typesSav));
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesMulSub));
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Subtract), typesMulSub));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else /* if (sizeF == 1) */
- {
- Type[] typesSav = new Type[] { typeof(double) };
- Type[] typesMulSub = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdc_R8(2d);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulSub));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesMulSub));
-
- context.EmitStvec(op.Rd);
- }
- }
- else
- {
- EmitVectorBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPRecipStepFused));
- });
- }
- }
-
- public static void Frecpx_S(ILEmitterCtx context)
- {
- EmitScalarUnaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPRecpX));
- });
- }
-
- public static void Frinta_S(ILEmitterCtx context)
- {
- EmitScalarUnaryOpF(context, () =>
- {
- EmitRoundMathCall(context, MidpointRounding.AwayFromZero);
- });
- }
-
- public static void Frinta_V(ILEmitterCtx context)
- {
- EmitVectorUnaryOpF(context, () =>
- {
- EmitRoundMathCall(context, MidpointRounding.AwayFromZero);
- });
- }
-
- public static void Frinti_S(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- if (Optimizations.UseSse41)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
- context.EmitLdvec(op.Rn);
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- if (op.Size == 0)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.Sse41ScalarRoundF));
- }
- else /* if (op.Size == 1) */
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.Sse41ScalarRound));
- }
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitScalarUnaryOpF(context, () =>
- {
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- if (op.Size == 0)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.RoundF));
- }
- else /* if (op.Size == 1) */
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.Round));
- }
- });
- }
- }
-
- public static void Frinti_V(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (Optimizations.UseSse41)
- {
- context.EmitLdvec(op.Rn);
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- if (sizeF == 0)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.Sse41VectorRoundF));
- }
- else /* if (sizeF == 1) */
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.Sse41VectorRound));
- }
-
- context.EmitStvec(op.Rd);
-
- if (sizeF == 0 && op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorUnaryOpF(context, () =>
- {
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- if (sizeF == 0)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.RoundF));
- }
- else /* if (sizeF == 1) */
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.Round));
- }
- });
- }
- }
-
- public static void Frintm_S(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- EmitSse41Frint(context, RoundMode.TowardsMinusInfinity, scalar: true);
- }
- else
- {
- EmitScalarUnaryOpF(context, () =>
- {
- EmitUnaryMathCall(context, nameof(Math.Floor));
- });
- }
- }
-
- public static void Frintm_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- EmitSse41Frint(context, RoundMode.TowardsMinusInfinity, scalar: false);
- }
- else
- {
- EmitVectorUnaryOpF(context, () =>
- {
- EmitUnaryMathCall(context, nameof(Math.Floor));
- });
- }
- }
-
- public static void Frintn_S(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- EmitSse41Frint(context, RoundMode.ToNearest, scalar: true);
- }
- else
- {
- EmitScalarUnaryOpF(context, () =>
- {
- EmitRoundMathCall(context, MidpointRounding.ToEven);
- });
- }
- }
-
- public static void Frintn_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- EmitSse41Frint(context, RoundMode.ToNearest, scalar: false);
- }
- else
- {
- EmitVectorUnaryOpF(context, () =>
- {
- EmitRoundMathCall(context, MidpointRounding.ToEven);
- });
- }
- }
-
- public static void Frintp_S(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- EmitSse41Frint(context, RoundMode.TowardsPlusInfinity, scalar: true);
- }
- else
- {
- EmitScalarUnaryOpF(context, () =>
- {
- EmitUnaryMathCall(context, nameof(Math.Ceiling));
- });
- }
- }
-
- public static void Frintp_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- EmitSse41Frint(context, RoundMode.TowardsPlusInfinity, scalar: false);
- }
- else
- {
- EmitVectorUnaryOpF(context, () =>
- {
- EmitUnaryMathCall(context, nameof(Math.Ceiling));
- });
- }
- }
-
- public static void Frintx_S(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- if (Optimizations.UseSse41)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
- context.EmitLdvec(op.Rn);
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- if (op.Size == 0)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.Sse41ScalarRoundF));
- }
- else /* if (op.Size == 1) */
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.Sse41ScalarRound));
- }
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitScalarUnaryOpF(context, () =>
- {
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- if (op.Size == 0)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.RoundF));
- }
- else /* if (op.Size == 1) */
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.Round));
- }
- });
- }
- }
-
- public static void Frintx_V(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (Optimizations.UseSse41)
- {
- context.EmitLdvec(op.Rn);
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- if (sizeF == 0)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.Sse41VectorRoundF));
- }
- else /* if (sizeF == 1) */
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.Sse41VectorRound));
- }
-
- context.EmitStvec(op.Rd);
-
- if (sizeF == 0 && op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorUnaryOpF(context, () =>
- {
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- if (sizeF == 0)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.RoundF));
- }
- else /* if (sizeF == 1) */
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.Round));
- }
- });
- }
- }
-
- public static void Frintz_S(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- EmitSse41Frint(context, RoundMode.TowardsZero, scalar: true);
- }
- else
- {
- EmitScalarUnaryOpF(context, () =>
- {
- EmitUnaryMathCall(context, nameof(Math.Truncate));
- });
- }
- }
-
- public static void Frintz_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- EmitSse41Frint(context, RoundMode.TowardsZero, scalar: false);
- }
- else
- {
- EmitVectorUnaryOpF(context, () =>
- {
- EmitUnaryMathCall(context, nameof(Math.Truncate));
- });
- }
- }
-
- public static void Frsqrte_S(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (Optimizations.FastFP && Optimizations.UseSse && sizeF == 0)
- {
- EmitScalarSseOrSse2OpF(context, nameof(Sse.ReciprocalSqrtScalar));
- }
- else
- {
- EmitScalarUnaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPRSqrtEstimate));
- });
- }
- }
-
- public static void Frsqrte_V(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (Optimizations.FastFP && Optimizations.UseSse && sizeF == 0)
- {
- EmitVectorSseOrSse2OpF(context, nameof(Sse.ReciprocalSqrt));
- }
- else
- {
- EmitVectorUnaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPRSqrtEstimate));
- });
- }
- }
-
- public static void Frsqrts_S(ILEmitterCtx context) // Fused.
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (sizeF == 0)
- {
- Type[] typesSsv = new Type[] { typeof(float) };
- Type[] typesMulSub = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdc_R4(0.5f);
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.SetScalarVector128), typesSsv));
-
- context.EmitLdc_R4(3f);
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.SetScalarVector128), typesSsv));
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MultiplyScalar), typesMulSub));
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.SubtractScalar), typesMulSub));
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MultiplyScalar), typesMulSub));
-
- context.EmitStvec(op.Rd);
-
- EmitVectorZero32_128(context, op.Rd);
- }
- else /* if (sizeF == 1) */
- {
- Type[] typesSsv = new Type[] { typeof(double) };
- Type[] typesMulSub = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdc_R8(0.5d);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetScalarVector128), typesSsv));
-
- context.EmitLdc_R8(3d);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetScalarVector128), typesSsv));
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.MultiplyScalar), typesMulSub));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SubtractScalar), typesMulSub));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.MultiplyScalar), typesMulSub));
-
- context.EmitStvec(op.Rd);
-
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitScalarBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPRSqrtStepFused));
- });
- }
- }
-
- public static void Frsqrts_V(ILEmitterCtx context) // Fused.
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (sizeF == 0)
- {
- Type[] typesSav = new Type[] { typeof(float) };
- Type[] typesMulSub = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdc_R4(0.5f);
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.SetAllVector128), typesSav));
-
- context.EmitLdc_R4(3f);
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.SetAllVector128), typesSav));
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesMulSub));
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Subtract), typesMulSub));
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesMulSub));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else /* if (sizeF == 1) */
- {
- Type[] typesSav = new Type[] { typeof(double) };
- Type[] typesMulSub = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdc_R8(0.5d);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitLdc_R8(3d);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulSub));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesMulSub));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulSub));
-
- context.EmitStvec(op.Rd);
- }
- }
- else
- {
- EmitVectorBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPRSqrtStepFused));
- });
- }
- }
-
- public static void Fsqrt_S(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitScalarSseOrSse2OpF(context, nameof(Sse.SqrtScalar));
- }
- else
- {
- EmitScalarUnaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPSqrt));
- });
- }
- }
-
- public static void Fsqrt_V(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitVectorSseOrSse2OpF(context, nameof(Sse.Sqrt));
- }
- else
- {
- EmitVectorUnaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPSqrt));
- });
- }
- }
-
- public static void Fsub_S(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitScalarSseOrSse2OpF(context, nameof(Sse.SubtractScalar));
- }
- else
- {
- EmitScalarBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub));
- });
- }
- }
-
- public static void Fsub_V(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitVectorSseOrSse2OpF(context, nameof(Sse.Subtract));
- }
- else
- {
- EmitVectorBinaryOpF(context, () =>
- {
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub));
- });
- }
- }
-
- public static void Mla_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- EmitSse41Mul_AddSub(context, nameof(Sse2.Add));
- }
- else
- {
- EmitVectorTernaryOpZx(context, () =>
- {
- context.Emit(OpCodes.Mul);
- context.Emit(OpCodes.Add);
- });
- }
- }
-
- public static void Mla_Ve(ILEmitterCtx context)
- {
- EmitVectorTernaryOpByElemZx(context, () =>
- {
- context.Emit(OpCodes.Mul);
- context.Emit(OpCodes.Add);
- });
- }
-
- public static void Mls_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- EmitSse41Mul_AddSub(context, nameof(Sse2.Subtract));
- }
- else
- {
- EmitVectorTernaryOpZx(context, () =>
- {
- context.Emit(OpCodes.Mul);
- context.Emit(OpCodes.Sub);
- });
- }
- }
-
- public static void Mls_Ve(ILEmitterCtx context)
- {
- EmitVectorTernaryOpByElemZx(context, () =>
- {
- context.Emit(OpCodes.Mul);
- context.Emit(OpCodes.Sub);
- });
- }
-
- public static void Mul_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- EmitSse41Mul_AddSub(context);
- }
- else
- {
- EmitVectorBinaryOpZx(context, () => context.Emit(OpCodes.Mul));
- }
- }
-
- public static void Mul_Ve(ILEmitterCtx context)
- {
- EmitVectorBinaryOpByElemZx(context, () => context.Emit(OpCodes.Mul));
- }
-
- public static void Neg_S(ILEmitterCtx context)
- {
- EmitScalarUnaryOpSx(context, () => context.Emit(OpCodes.Neg));
- }
-
- public static void Neg_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse2)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- Type[] typesSub = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
-
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSub));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorUnaryOpSx(context, () => context.Emit(OpCodes.Neg));
- }
- }
-
- public static void Raddhn_V(ILEmitterCtx context)
- {
- EmitHighNarrow(context, () => context.Emit(OpCodes.Add), round: true);
- }
-
- public static void Rsubhn_V(ILEmitterCtx context)
- {
- EmitHighNarrow(context, () => context.Emit(OpCodes.Sub), round: true);
- }
-
- public static void Saba_V(ILEmitterCtx context)
- {
- EmitVectorTernaryOpSx(context, () =>
- {
- context.Emit(OpCodes.Sub);
- EmitAbs(context);
-
- context.Emit(OpCodes.Add);
- });
- }
-
- public static void Sabal_V(ILEmitterCtx context)
- {
- EmitVectorWidenRnRmTernaryOpSx(context, () =>
- {
- context.Emit(OpCodes.Sub);
- EmitAbs(context);
-
- context.Emit(OpCodes.Add);
- });
- }
-
- public static void Sabd_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse2)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- Type[] typesCmpSub = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
- Type[] typesAndOr = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThan), typesCmpSub));
-
- context.EmitStvectmp(); // Cmp mask
- context.EmitLdvectmp(); // Cmp mask
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesCmpSub));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.And), typesAndOr));
-
- context.EmitLdvectmp(); // Cmp mask
-
- context.EmitLdvec(op.Rm);
- context.EmitLdvec(op.Rn);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesCmpSub));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAndOr));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Or), typesAndOr));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorBinaryOpSx(context, () =>
- {
- context.Emit(OpCodes.Sub);
- EmitAbs(context);
- });
- }
- }
-
- public static void Sabdl_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- if (Optimizations.UseSse41 && op.Size < 2)
- {
- Type[] typesCmpSub = new Type[] { VectorIntTypesPerSizeLog2[op.Size + 1],
- VectorIntTypesPerSizeLog2[op.Size + 1] };
- Type[] typesSrl = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesAndOr = new Type[] { typeof(Vector128), typeof(Vector128) };
- Type[] typesCvt = new Type[] { VectorIntTypesPerSizeLog2[op.Size] };
-
- string nameCvt = op.Size == 0
- ? nameof(Sse41.ConvertToVector128Int16)
- : nameof(Sse41.ConvertToVector128Int32);
-
- context.EmitLdvec(op.Rn);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(nameCvt, typesCvt));
-
- context.EmitLdvec(op.Rm);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(nameCvt, typesCvt));
-
- context.EmitStvectmp2(); // Long Rm
- context.EmitStvectmp(); // Long Rn
-
- context.EmitLdvectmp(); // Long Rn
- context.EmitLdvectmp2(); // Long Rm
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThan), typesCmpSub));
-
- context.EmitStvectmp3(); // Cmp mask
- context.EmitLdvectmp3(); // Cmp mask
-
- context.EmitLdvectmp(); // Long Rn
- context.EmitLdvectmp2(); // Long Rm
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesCmpSub));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.And), typesAndOr));
-
- context.EmitLdvectmp3(); // Cmp mask
-
- context.EmitLdvectmp2(); // Long Rm
- context.EmitLdvectmp(); // Long Rn
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesCmpSub));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAndOr));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Or), typesAndOr));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitVectorWidenRnRmBinaryOpSx(context, () =>
- {
- context.Emit(OpCodes.Sub);
- EmitAbs(context);
- });
- }
- }
-
- public static void Sadalp_V(ILEmitterCtx context)
- {
- EmitAddLongPairwise(context, signed: true, accumulate: true);
- }
-
- public static void Saddl_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- Type[] typesSrl = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesCvt = new Type[] { VectorIntTypesPerSizeLog2[op.Size] };
- Type[] typesAdd = new Type[] { VectorIntTypesPerSizeLog2[op.Size + 1],
- VectorIntTypesPerSizeLog2[op.Size + 1] };
-
- string[] namesCvt = new string[] { nameof(Sse41.ConvertToVector128Int16),
- nameof(Sse41.ConvertToVector128Int32),
- nameof(Sse41.ConvertToVector128Int64) };
-
- context.EmitLdvec(op.Rn);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt));
-
- context.EmitLdvec(op.Rm);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitVectorWidenRnRmBinaryOpSx(context, () => context.Emit(OpCodes.Add));
- }
- }
-
- public static void Saddlp_V(ILEmitterCtx context)
- {
- EmitAddLongPairwise(context, signed: true, accumulate: false);
- }
-
- public static void Saddlv_V(ILEmitterCtx context)
- {
- EmitVectorLongAcrossVectorOpSx(context, () => context.Emit(OpCodes.Add));
- }
-
- public static void Saddw_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- Type[] typesSrl = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesCvt = new Type[] { VectorIntTypesPerSizeLog2[op.Size] };
- Type[] typesAdd = new Type[] { VectorIntTypesPerSizeLog2[op.Size + 1],
- VectorIntTypesPerSizeLog2[op.Size + 1] };
-
- string[] namesCvt = new string[] { nameof(Sse41.ConvertToVector128Int16),
- nameof(Sse41.ConvertToVector128Int32),
- nameof(Sse41.ConvertToVector128Int64) };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitVectorWidenRmBinaryOpSx(context, () => context.Emit(OpCodes.Add));
- }
- }
-
- public static void Shadd_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- if (Optimizations.UseSse2 && op.Size > 0)
- {
- Type[] typesSra = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesAndXorAdd = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.And), typesAndXorAdd));
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), typesAndXorAdd));
-
- context.Emit(OpCodes.Ldc_I4_1);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), typesSra));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAndXorAdd));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorBinaryOpSx(context, () =>
- {
- context.Emit(OpCodes.Add);
-
- context.Emit(OpCodes.Ldc_I4_1);
- context.Emit(OpCodes.Shr);
- });
- }
- }
-
- public static void Shsub_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- if (Optimizations.UseSse2 && op.Size < 2)
- {
- Type[] typesSav = new Type[] { IntTypesPerSizeLog2[op.Size] };
- Type[] typesAddSub = new Type[] { VectorIntTypesPerSizeLog2 [op.Size], VectorIntTypesPerSizeLog2 [op.Size] };
- Type[] typesAvg = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], VectorUIntTypesPerSizeLog2[op.Size] };
-
- context.EmitLdc_I4(op.Size == 0 ? sbyte.MinValue : short.MinValue);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitStvectmp();
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvectmp();
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAddSub));
-
- context.Emit(OpCodes.Dup);
-
- context.EmitLdvec(op.Rm);
- context.EmitLdvectmp();
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAddSub));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Average), typesAvg));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesAddSub));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorBinaryOpSx(context, () =>
- {
- context.Emit(OpCodes.Sub);
-
- context.Emit(OpCodes.Ldc_I4_1);
- context.Emit(OpCodes.Shr);
- });
- }
- }
-
- public static void Smax_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- Type[] typesMax = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
-
- Type typeSse = op.Size == 1 ? typeof(Sse2) : typeof(Sse41);
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeSse.GetMethod(nameof(Sse2.Max), typesMax));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- Type[] types = new Type[] { typeof(long), typeof(long) };
-
- MethodInfo mthdInfo = typeof(Math).GetMethod(nameof(Math.Max), types);
-
- EmitVectorBinaryOpSx(context, () => context.EmitCall(mthdInfo));
- }
- }
-
- public static void Smaxp_V(ILEmitterCtx context)
- {
- Type[] types = new Type[] { typeof(long), typeof(long) };
-
- MethodInfo mthdInfo = typeof(Math).GetMethod(nameof(Math.Max), types);
-
- EmitVectorPairwiseOpSx(context, () => context.EmitCall(mthdInfo));
- }
-
- public static void Smaxv_V(ILEmitterCtx context)
- {
- Type[] types = new Type[] { typeof(long), typeof(long) };
-
- MethodInfo mthdInfo = typeof(Math).GetMethod(nameof(Math.Max), types);
-
- EmitVectorAcrossVectorOpSx(context, () => context.EmitCall(mthdInfo));
- }
-
- public static void Smin_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- Type[] typesMin = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
-
- Type typeSse = op.Size == 1 ? typeof(Sse2) : typeof(Sse41);
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeSse.GetMethod(nameof(Sse2.Min), typesMin));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- Type[] types = new Type[] { typeof(long), typeof(long) };
-
- MethodInfo mthdInfo = typeof(Math).GetMethod(nameof(Math.Min), types);
-
- EmitVectorBinaryOpSx(context, () => context.EmitCall(mthdInfo));
- }
- }
-
- public static void Sminp_V(ILEmitterCtx context)
- {
- Type[] types = new Type[] { typeof(long), typeof(long) };
-
- MethodInfo mthdInfo = typeof(Math).GetMethod(nameof(Math.Min), types);
-
- EmitVectorPairwiseOpSx(context, () => context.EmitCall(mthdInfo));
- }
-
- public static void Sminv_V(ILEmitterCtx context)
- {
- Type[] types = new Type[] { typeof(long), typeof(long) };
-
- MethodInfo mthdInfo = typeof(Math).GetMethod(nameof(Math.Min), types);
-
- EmitVectorAcrossVectorOpSx(context, () => context.EmitCall(mthdInfo));
- }
-
- public static void Smlal_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- if (Optimizations.UseSse41 && op.Size < 2)
- {
- Type[] typesSrl = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesCvt = new Type[] { VectorIntTypesPerSizeLog2[op.Size] };
- Type[] typesMulAdd = new Type[] { VectorIntTypesPerSizeLog2[op.Size + 1],
- VectorIntTypesPerSizeLog2[op.Size + 1] };
-
- Type typeSse = op.Size == 0 ? typeof(Sse2) : typeof(Sse41);
-
- string nameCvt = op.Size == 0
- ? nameof(Sse41.ConvertToVector128Int16)
- : nameof(Sse41.ConvertToVector128Int32);
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(nameCvt, typesCvt));
-
- context.EmitLdvec(op.Rm);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(nameCvt, typesCvt));
-
- context.EmitCall(typeSse.GetMethod(nameof(Sse2.MultiplyLow), typesMulAdd));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesMulAdd));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitVectorWidenRnRmTernaryOpSx(context, () =>
- {
- context.Emit(OpCodes.Mul);
- context.Emit(OpCodes.Add);
- });
- }
- }
-
- public static void Smlal_Ve(ILEmitterCtx context)
- {
- EmitVectorWidenTernaryOpByElemSx(context, () =>
- {
- context.Emit(OpCodes.Mul);
- context.Emit(OpCodes.Add);
- });
- }
-
- public static void Smlsl_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- if (Optimizations.UseSse41 && op.Size < 2)
- {
- Type[] typesSrl = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesCvt = new Type[] { VectorIntTypesPerSizeLog2[op.Size] };
- Type[] typesMulSub = new Type[] { VectorIntTypesPerSizeLog2[op.Size + 1],
- VectorIntTypesPerSizeLog2[op.Size + 1] };
-
- Type typeSse = op.Size == 0 ? typeof(Sse2) : typeof(Sse41);
-
- string nameCvt = op.Size == 0
- ? nameof(Sse41.ConvertToVector128Int16)
- : nameof(Sse41.ConvertToVector128Int32);
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(nameCvt, typesCvt));
-
- context.EmitLdvec(op.Rm);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(nameCvt, typesCvt));
-
- context.EmitCall(typeSse.GetMethod(nameof(Sse2.MultiplyLow), typesMulSub));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesMulSub));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitVectorWidenRnRmTernaryOpSx(context, () =>
- {
- context.Emit(OpCodes.Mul);
- context.Emit(OpCodes.Sub);
- });
- }
- }
-
- public static void Smlsl_Ve(ILEmitterCtx context)
- {
- EmitVectorWidenTernaryOpByElemSx(context, () =>
- {
- context.Emit(OpCodes.Mul);
- context.Emit(OpCodes.Sub);
- });
- }
-
- public static void Smull_V(ILEmitterCtx context)
- {
- EmitVectorWidenRnRmBinaryOpSx(context, () => context.Emit(OpCodes.Mul));
- }
-
- public static void Smull_Ve(ILEmitterCtx context)
- {
- EmitVectorWidenBinaryOpByElemSx(context, () => context.Emit(OpCodes.Mul));
- }
-
- public static void Sqabs_S(ILEmitterCtx context)
- {
- EmitScalarSaturatingUnaryOpSx(context, () => EmitAbs(context));
- }
-
- public static void Sqabs_V(ILEmitterCtx context)
- {
- EmitVectorSaturatingUnaryOpSx(context, () => EmitAbs(context));
- }
-
- public static void Sqadd_S(ILEmitterCtx context)
- {
- EmitScalarSaturatingBinaryOpSx(context, SaturatingFlags.Add);
- }
-
- public static void Sqadd_V(ILEmitterCtx context)
- {
- EmitVectorSaturatingBinaryOpSx(context, SaturatingFlags.Add);
- }
-
- public static void Sqdmulh_S(ILEmitterCtx context)
- {
- EmitSaturatingBinaryOp(context, () => EmitDoublingMultiplyHighHalf(context, round: false), SaturatingFlags.ScalarSx);
- }
-
- public static void Sqdmulh_V(ILEmitterCtx context)
- {
- EmitSaturatingBinaryOp(context, () => EmitDoublingMultiplyHighHalf(context, round: false), SaturatingFlags.VectorSx);
- }
-
- public static void Sqneg_S(ILEmitterCtx context)
- {
- EmitScalarSaturatingUnaryOpSx(context, () => context.Emit(OpCodes.Neg));
- }
-
- public static void Sqneg_V(ILEmitterCtx context)
- {
- EmitVectorSaturatingUnaryOpSx(context, () => context.Emit(OpCodes.Neg));
- }
-
- public static void Sqrdmulh_S(ILEmitterCtx context)
- {
- EmitSaturatingBinaryOp(context, () => EmitDoublingMultiplyHighHalf(context, round: true), SaturatingFlags.ScalarSx);
- }
-
- public static void Sqrdmulh_V(ILEmitterCtx context)
- {
- EmitSaturatingBinaryOp(context, () => EmitDoublingMultiplyHighHalf(context, round: true), SaturatingFlags.VectorSx);
- }
-
- public static void Sqsub_S(ILEmitterCtx context)
- {
- EmitScalarSaturatingBinaryOpSx(context, SaturatingFlags.Sub);
- }
-
- public static void Sqsub_V(ILEmitterCtx context)
- {
- EmitVectorSaturatingBinaryOpSx(context, SaturatingFlags.Sub);
- }
-
- public static void Sqxtn_S(ILEmitterCtx context)
- {
- EmitSaturatingNarrowOp(context, SaturatingNarrowFlags.ScalarSxSx);
- }
-
- public static void Sqxtn_V(ILEmitterCtx context)
- {
- EmitSaturatingNarrowOp(context, SaturatingNarrowFlags.VectorSxSx);
- }
-
- public static void Sqxtun_S(ILEmitterCtx context)
- {
- EmitSaturatingNarrowOp(context, SaturatingNarrowFlags.ScalarSxZx);
- }
-
- public static void Sqxtun_V(ILEmitterCtx context)
- {
- EmitSaturatingNarrowOp(context, SaturatingNarrowFlags.VectorSxZx);
- }
-
- public static void Srhadd_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- if (Optimizations.UseSse2 && op.Size < 2)
- {
- Type[] typesSav = new Type[] { IntTypesPerSizeLog2[op.Size] };
- Type[] typesSubAdd = new Type[] { VectorIntTypesPerSizeLog2 [op.Size], VectorIntTypesPerSizeLog2 [op.Size] };
- Type[] typesAvg = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], VectorUIntTypesPerSizeLog2[op.Size] };
-
- context.EmitLdc_I4(op.Size == 0 ? sbyte.MinValue : short.MinValue);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitStvectmp();
- context.EmitLdvectmp();
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvectmp();
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSubAdd));
-
- context.EmitLdvec(op.Rm);
- context.EmitLdvectmp();
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSubAdd));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Average), typesAvg));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesSubAdd));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorBinaryOpSx(context, () =>
- {
- context.Emit(OpCodes.Add);
-
- context.Emit(OpCodes.Ldc_I4_1);
- context.Emit(OpCodes.Add);
-
- context.Emit(OpCodes.Ldc_I4_1);
- context.Emit(OpCodes.Shr);
- });
- }
- }
-
- public static void Ssubl_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- Type[] typesSrl = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesCvt = new Type[] { VectorIntTypesPerSizeLog2[op.Size] };
- Type[] typesSub = new Type[] { VectorIntTypesPerSizeLog2[op.Size + 1],
- VectorIntTypesPerSizeLog2[op.Size + 1] };
-
- string[] namesCvt = new string[] { nameof(Sse41.ConvertToVector128Int16),
- nameof(Sse41.ConvertToVector128Int32),
- nameof(Sse41.ConvertToVector128Int64) };
-
- context.EmitLdvec(op.Rn);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt));
-
- context.EmitLdvec(op.Rm);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSub));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitVectorWidenRnRmBinaryOpSx(context, () => context.Emit(OpCodes.Sub));
- }
- }
-
- public static void Ssubw_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- Type[] typesSrl = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesCvt = new Type[] { VectorIntTypesPerSizeLog2[op.Size] };
- Type[] typesSub = new Type[] { VectorIntTypesPerSizeLog2[op.Size + 1],
- VectorIntTypesPerSizeLog2[op.Size + 1] };
-
- string[] namesCvt = new string[] { nameof(Sse41.ConvertToVector128Int16),
- nameof(Sse41.ConvertToVector128Int32),
- nameof(Sse41.ConvertToVector128Int64) };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSub));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitVectorWidenRmBinaryOpSx(context, () => context.Emit(OpCodes.Sub));
- }
- }
-
- public static void Sub_S(ILEmitterCtx context)
- {
- EmitScalarBinaryOpZx(context, () => context.Emit(OpCodes.Sub));
- }
-
- public static void Sub_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse2)
- {
- EmitSse2Op(context, nameof(Sse2.Subtract));
- }
- else
- {
- EmitVectorBinaryOpZx(context, () => context.Emit(OpCodes.Sub));
- }
- }
-
- public static void Subhn_V(ILEmitterCtx context)
- {
- EmitHighNarrow(context, () => context.Emit(OpCodes.Sub), round: false);
- }
-
- public static void Suqadd_S(ILEmitterCtx context)
- {
- EmitScalarSaturatingBinaryOpSx(context, SaturatingFlags.Accumulate);
- }
-
- public static void Suqadd_V(ILEmitterCtx context)
- {
- EmitVectorSaturatingBinaryOpSx(context, SaturatingFlags.Accumulate);
- }
-
- public static void Uaba_V(ILEmitterCtx context)
- {
- EmitVectorTernaryOpZx(context, () =>
- {
- context.Emit(OpCodes.Sub);
- EmitAbs(context);
-
- context.Emit(OpCodes.Add);
- });
- }
-
- public static void Uabal_V(ILEmitterCtx context)
- {
- EmitVectorWidenRnRmTernaryOpZx(context, () =>
- {
- context.Emit(OpCodes.Sub);
- EmitAbs(context);
-
- context.Emit(OpCodes.Add);
- });
- }
-
- public static void Uabd_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- Type[] typesMax = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], VectorUIntTypesPerSizeLog2[op.Size] };
- Type[] typesCmpSub = new Type[] { VectorIntTypesPerSizeLog2 [op.Size], VectorIntTypesPerSizeLog2 [op.Size] };
- Type[] typesAndOr = new Type[] { typeof(Vector128), typeof(Vector128) };
- Type[] typesSav = new Type[] { typeof(long) };
-
- Type typeSse = op.Size == 0 ? typeof(Sse2) : typeof(Sse41);
-
- context.EmitLdvec(op.Rm);
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeSse.GetMethod(nameof(Sse2.Max), typesMax));
-
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), typesCmpSub));
-
- context.EmitLdc_I8(-1L);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAndOr));
-
- context.EmitStvectmp(); // Cmp mask
- context.EmitLdvectmp(); // Cmp mask
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesCmpSub));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.And), typesAndOr));
-
- context.EmitLdvectmp(); // Cmp mask
-
- context.EmitLdvec(op.Rm);
- context.EmitLdvec(op.Rn);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesCmpSub));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAndOr));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Or), typesAndOr));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorBinaryOpZx(context, () =>
- {
- context.Emit(OpCodes.Sub);
- EmitAbs(context);
- });
- }
- }
-
- public static void Uabdl_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- if (Optimizations.UseSse41 && op.Size < 2)
- {
- Type[] typesMax = new Type[] { VectorUIntTypesPerSizeLog2[op.Size + 1],
- VectorUIntTypesPerSizeLog2[op.Size + 1] };
- Type[] typesCmpSub = new Type[] { VectorIntTypesPerSizeLog2 [op.Size + 1],
- VectorIntTypesPerSizeLog2 [op.Size + 1] };
- Type[] typesSrl = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesAndOr = new Type[] { typeof(Vector128), typeof(Vector128) };
- Type[] typesCvt = new Type[] { VectorUIntTypesPerSizeLog2[op.Size] };
- Type[] typesSav = new Type[] { typeof(long) };
-
- string nameCvt = op.Size == 0
- ? nameof(Sse41.ConvertToVector128Int16)
- : nameof(Sse41.ConvertToVector128Int32);
-
- context.EmitLdvec(op.Rn);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(nameCvt, typesCvt));
-
- context.EmitLdvec(op.Rm);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(nameCvt, typesCvt));
-
- context.EmitStvectmp2(); // Long Rm
- context.EmitStvectmp(); // Long Rn
-
- context.EmitLdvectmp2(); // Long Rm
- context.EmitLdvectmp(); // Long Rn
-
- context.EmitCall(typeof(Sse41).GetMethod(nameof(Sse41.Max), typesMax));
-
- context.EmitLdvectmp2(); // Long Rm
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), typesCmpSub));
-
- context.EmitLdc_I8(-1L);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAndOr));
-
- context.EmitStvectmp3(); // Cmp mask
- context.EmitLdvectmp3(); // Cmp mask
-
- context.EmitLdvectmp(); // Long Rn
- context.EmitLdvectmp2(); // Long Rm
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesCmpSub));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.And), typesAndOr));
-
- context.EmitLdvectmp3(); // Cmp mask
-
- context.EmitLdvectmp2(); // Long Rm
- context.EmitLdvectmp(); // Long Rn
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesCmpSub));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAndOr));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Or), typesAndOr));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitVectorWidenRnRmBinaryOpZx(context, () =>
- {
- context.Emit(OpCodes.Sub);
- EmitAbs(context);
- });
- }
- }
-
- public static void Uadalp_V(ILEmitterCtx context)
- {
- EmitAddLongPairwise(context, signed: false, accumulate: true);
- }
-
- public static void Uaddl_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- Type[] typesSrl = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesCvt = new Type[] { VectorUIntTypesPerSizeLog2[op.Size] };
- Type[] typesAdd = new Type[] { VectorUIntTypesPerSizeLog2[op.Size + 1],
- VectorUIntTypesPerSizeLog2[op.Size + 1] };
-
- string[] namesCvt = new string[] { nameof(Sse41.ConvertToVector128Int16),
- nameof(Sse41.ConvertToVector128Int32),
- nameof(Sse41.ConvertToVector128Int64) };
-
- context.EmitLdvec(op.Rn);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt));
-
- context.EmitLdvec(op.Rm);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitVectorWidenRnRmBinaryOpZx(context, () => context.Emit(OpCodes.Add));
- }
- }
-
- public static void Uaddlp_V(ILEmitterCtx context)
- {
- EmitAddLongPairwise(context, signed: false, accumulate: false);
- }
-
- public static void Uaddlv_V(ILEmitterCtx context)
- {
- EmitVectorLongAcrossVectorOpZx(context, () => context.Emit(OpCodes.Add));
- }
-
- public static void Uaddw_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- Type[] typesSrl = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesCvt = new Type[] { VectorUIntTypesPerSizeLog2[op.Size] };
- Type[] typesAdd = new Type[] { VectorUIntTypesPerSizeLog2[op.Size + 1],
- VectorUIntTypesPerSizeLog2[op.Size + 1] };
-
- string[] namesCvt = new string[] { nameof(Sse41.ConvertToVector128Int16),
- nameof(Sse41.ConvertToVector128Int32),
- nameof(Sse41.ConvertToVector128Int64) };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitVectorWidenRmBinaryOpZx(context, () => context.Emit(OpCodes.Add));
- }
- }
-
- public static void Uhadd_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- if (Optimizations.UseSse2 && op.Size > 0)
- {
- Type[] typesSrl = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesAndXorAdd = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], VectorUIntTypesPerSizeLog2[op.Size] };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.And), typesAndXorAdd));
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), typesAndXorAdd));
-
- context.Emit(OpCodes.Ldc_I4_1);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), typesSrl));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAndXorAdd));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorBinaryOpZx(context, () =>
- {
- context.Emit(OpCodes.Add);
-
- context.Emit(OpCodes.Ldc_I4_1);
- context.Emit(OpCodes.Shr_Un);
- });
- }
- }
-
- public static void Uhsub_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- if (Optimizations.UseSse2 && op.Size < 2)
- {
- Type[] typesAvgSub = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], VectorUIntTypesPerSizeLog2[op.Size] };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Average), typesAvgSub));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesAvgSub));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorBinaryOpZx(context, () =>
- {
- context.Emit(OpCodes.Sub);
-
- context.Emit(OpCodes.Ldc_I4_1);
- context.Emit(OpCodes.Shr_Un);
- });
- }
- }
-
- public static void Umax_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- Type[] typesMax = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], VectorUIntTypesPerSizeLog2[op.Size] };
-
- Type typeSse = op.Size == 0 ? typeof(Sse2) : typeof(Sse41);
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeSse.GetMethod(nameof(Sse2.Max), typesMax));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- Type[] types = new Type[] { typeof(ulong), typeof(ulong) };
-
- MethodInfo mthdInfo = typeof(Math).GetMethod(nameof(Math.Max), types);
-
- EmitVectorBinaryOpZx(context, () => context.EmitCall(mthdInfo));
- }
- }
-
- public static void Umaxp_V(ILEmitterCtx context)
- {
- Type[] types = new Type[] { typeof(ulong), typeof(ulong) };
-
- MethodInfo mthdInfo = typeof(Math).GetMethod(nameof(Math.Max), types);
-
- EmitVectorPairwiseOpZx(context, () => context.EmitCall(mthdInfo));
- }
-
- public static void Umaxv_V(ILEmitterCtx context)
- {
- Type[] types = new Type[] { typeof(ulong), typeof(ulong) };
-
- MethodInfo mthdInfo = typeof(Math).GetMethod(nameof(Math.Max), types);
-
- EmitVectorAcrossVectorOpZx(context, () => context.EmitCall(mthdInfo));
- }
-
- public static void Umin_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- Type[] typesMin = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], VectorUIntTypesPerSizeLog2[op.Size] };
-
- Type typeSse = op.Size == 0 ? typeof(Sse2) : typeof(Sse41);
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeSse.GetMethod(nameof(Sse2.Min), typesMin));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- Type[] types = new Type[] { typeof(ulong), typeof(ulong) };
-
- MethodInfo mthdInfo = typeof(Math).GetMethod(nameof(Math.Min), types);
-
- EmitVectorBinaryOpZx(context, () => context.EmitCall(mthdInfo));
- }
- }
-
- public static void Uminp_V(ILEmitterCtx context)
- {
- Type[] types = new Type[] { typeof(ulong), typeof(ulong) };
-
- MethodInfo mthdInfo = typeof(Math).GetMethod(nameof(Math.Min), types);
-
- EmitVectorPairwiseOpZx(context, () => context.EmitCall(mthdInfo));
- }
-
- public static void Uminv_V(ILEmitterCtx context)
- {
- Type[] types = new Type[] { typeof(ulong), typeof(ulong) };
-
- MethodInfo mthdInfo = typeof(Math).GetMethod(nameof(Math.Min), types);
-
- EmitVectorAcrossVectorOpZx(context, () => context.EmitCall(mthdInfo));
- }
-
- public static void Umlal_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- if (Optimizations.UseSse41 && op.Size < 2)
- {
- Type[] typesSrl = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesCvt = new Type[] { VectorUIntTypesPerSizeLog2[op.Size] };
- Type[] typesMulAdd = new Type[] { VectorIntTypesPerSizeLog2 [op.Size + 1],
- VectorIntTypesPerSizeLog2 [op.Size + 1] };
-
- Type typeSse = op.Size == 0 ? typeof(Sse2) : typeof(Sse41);
-
- string nameCvt = op.Size == 0
- ? nameof(Sse41.ConvertToVector128Int16)
- : nameof(Sse41.ConvertToVector128Int32);
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(nameCvt, typesCvt));
-
- context.EmitLdvec(op.Rm);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(nameCvt, typesCvt));
-
- context.EmitCall(typeSse.GetMethod(nameof(Sse2.MultiplyLow), typesMulAdd));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesMulAdd));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitVectorWidenRnRmTernaryOpZx(context, () =>
- {
- context.Emit(OpCodes.Mul);
- context.Emit(OpCodes.Add);
- });
- }
- }
-
- public static void Umlal_Ve(ILEmitterCtx context)
- {
- EmitVectorWidenTernaryOpByElemZx(context, () =>
- {
- context.Emit(OpCodes.Mul);
- context.Emit(OpCodes.Add);
- });
- }
-
- public static void Umlsl_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- if (Optimizations.UseSse41 && op.Size < 2)
- {
- Type[] typesSrl = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesCvt = new Type[] { VectorUIntTypesPerSizeLog2[op.Size] };
- Type[] typesMulSub = new Type[] { VectorIntTypesPerSizeLog2 [op.Size + 1],
- VectorIntTypesPerSizeLog2 [op.Size + 1] };
-
- Type typeSse = op.Size == 0 ? typeof(Sse2) : typeof(Sse41);
-
- string nameCvt = op.Size == 0
- ? nameof(Sse41.ConvertToVector128Int16)
- : nameof(Sse41.ConvertToVector128Int32);
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(nameCvt, typesCvt));
-
- context.EmitLdvec(op.Rm);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(nameCvt, typesCvt));
-
- context.EmitCall(typeSse.GetMethod(nameof(Sse2.MultiplyLow), typesMulSub));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesMulSub));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitVectorWidenRnRmTernaryOpZx(context, () =>
- {
- context.Emit(OpCodes.Mul);
- context.Emit(OpCodes.Sub);
- });
- }
- }
-
- public static void Umlsl_Ve(ILEmitterCtx context)
- {
- EmitVectorWidenTernaryOpByElemZx(context, () =>
- {
- context.Emit(OpCodes.Mul);
- context.Emit(OpCodes.Sub);
- });
- }
-
- public static void Umull_V(ILEmitterCtx context)
- {
- EmitVectorWidenRnRmBinaryOpZx(context, () => context.Emit(OpCodes.Mul));
- }
-
- public static void Umull_Ve(ILEmitterCtx context)
- {
- EmitVectorWidenBinaryOpByElemZx(context, () => context.Emit(OpCodes.Mul));
- }
-
- public static void Uqadd_S(ILEmitterCtx context)
- {
- EmitScalarSaturatingBinaryOpZx(context, SaturatingFlags.Add);
- }
-
- public static void Uqadd_V(ILEmitterCtx context)
- {
- EmitVectorSaturatingBinaryOpZx(context, SaturatingFlags.Add);
- }
-
- public static void Uqsub_S(ILEmitterCtx context)
- {
- EmitScalarSaturatingBinaryOpZx(context, SaturatingFlags.Sub);
- }
-
- public static void Uqsub_V(ILEmitterCtx context)
- {
- EmitVectorSaturatingBinaryOpZx(context, SaturatingFlags.Sub);
- }
-
- public static void Uqxtn_S(ILEmitterCtx context)
- {
- EmitSaturatingNarrowOp(context, SaturatingNarrowFlags.ScalarZxZx);
- }
-
- public static void Uqxtn_V(ILEmitterCtx context)
- {
- EmitSaturatingNarrowOp(context, SaturatingNarrowFlags.VectorZxZx);
- }
-
- public static void Urhadd_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- if (Optimizations.UseSse2 && op.Size < 2)
- {
- Type[] typesAvg = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], VectorUIntTypesPerSizeLog2[op.Size] };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Average), typesAvg));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorBinaryOpZx(context, () =>
- {
- context.Emit(OpCodes.Add);
-
- context.Emit(OpCodes.Ldc_I4_1);
- context.Emit(OpCodes.Add);
-
- context.Emit(OpCodes.Ldc_I4_1);
- context.Emit(OpCodes.Shr_Un);
- });
- }
- }
-
- public static void Usqadd_S(ILEmitterCtx context)
- {
- EmitScalarSaturatingBinaryOpZx(context, SaturatingFlags.Accumulate);
- }
-
- public static void Usqadd_V(ILEmitterCtx context)
- {
- EmitVectorSaturatingBinaryOpZx(context, SaturatingFlags.Accumulate);
- }
-
- public static void Usubl_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- Type[] typesSrl = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesCvt = new Type[] { VectorUIntTypesPerSizeLog2[op.Size] };
- Type[] typesSub = new Type[] { VectorUIntTypesPerSizeLog2[op.Size + 1],
- VectorUIntTypesPerSizeLog2[op.Size + 1] };
-
- string[] namesCvt = new string[] { nameof(Sse41.ConvertToVector128Int16),
- nameof(Sse41.ConvertToVector128Int32),
- nameof(Sse41.ConvertToVector128Int64) };
-
- context.EmitLdvec(op.Rn);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt));
-
- context.EmitLdvec(op.Rm);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSub));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitVectorWidenRnRmBinaryOpZx(context, () => context.Emit(OpCodes.Sub));
- }
- }
-
- public static void Usubw_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- Type[] typesSrl = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesCvt = new Type[] { VectorUIntTypesPerSizeLog2[op.Size] };
- Type[] typesSub = new Type[] { VectorUIntTypesPerSizeLog2[op.Size + 1],
- VectorUIntTypesPerSizeLog2[op.Size + 1] };
-
- string[] namesCvt = new string[] { nameof(Sse41.ConvertToVector128Int16),
- nameof(Sse41.ConvertToVector128Int32),
- nameof(Sse41.ConvertToVector128Int64) };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSub));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitVectorWidenRmBinaryOpZx(context, () => context.Emit(OpCodes.Sub));
- }
- }
-
- private static void EmitAbs(ILEmitterCtx context)
- {
- ILLabel lblTrue = new ILLabel();
-
- context.Emit(OpCodes.Dup);
- context.Emit(OpCodes.Ldc_I4_0);
- context.Emit(OpCodes.Bge_S, lblTrue);
-
- context.Emit(OpCodes.Neg);
-
- context.MarkLabel(lblTrue);
- }
-
- private static void EmitAddLongPairwise(ILEmitterCtx context, bool signed, bool accumulate)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int words = op.GetBitsCount() >> 4;
- int pairs = words >> op.Size;
-
- for (int index = 0; index < pairs; index++)
- {
- int idx = index << 1;
-
- EmitVectorExtract(context, op.Rn, idx, op.Size, signed);
- EmitVectorExtract(context, op.Rn, idx + 1, op.Size, signed);
-
- context.Emit(OpCodes.Add);
-
- if (accumulate)
- {
- EmitVectorExtract(context, op.Rd, index, op.Size + 1, signed);
-
- context.Emit(OpCodes.Add);
- }
-
- EmitVectorInsertTmp(context, index, op.Size + 1);
- }
-
- context.EmitLdvectmp();
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- private static void EmitDoublingMultiplyHighHalf(ILEmitterCtx context, bool round)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int eSize = 8 << op.Size;
-
- context.Emit(OpCodes.Mul);
-
- if (!round)
- {
- context.EmitAsr(eSize - 1);
- }
- else
- {
- long roundConst = 1L << (eSize - 1);
-
- ILLabel lblTrue = new ILLabel();
-
- context.EmitLsl(1);
-
- context.EmitLdc_I8(roundConst);
-
- context.Emit(OpCodes.Add);
-
- context.EmitAsr(eSize);
-
- context.Emit(OpCodes.Dup);
- context.EmitLdc_I8((long)int.MinValue);
- context.Emit(OpCodes.Bne_Un_S, lblTrue);
-
- context.Emit(OpCodes.Neg);
-
- context.MarkLabel(lblTrue);
- }
- }
-
- private static void EmitHighNarrow(ILEmitterCtx context, Action emit, bool round)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int elems = 8 >> op.Size;
-
- int eSize = 8 << op.Size;
-
- int part = op.RegisterSize == RegisterSize.Simd128 ? elems : 0;
-
- long roundConst = 1L << (eSize - 1);
-
- if (part != 0)
- {
- context.EmitLdvec(op.Rd);
- context.EmitStvectmp();
- }
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractZx(context, op.Rn, index, op.Size + 1);
- EmitVectorExtractZx(context, op.Rm, index, op.Size + 1);
-
- emit();
-
- if (round)
- {
- context.EmitLdc_I8(roundConst);
-
- context.Emit(OpCodes.Add);
- }
-
- context.EmitLsr(eSize);
-
- EmitVectorInsertTmp(context, part + index, op.Size);
- }
-
- context.EmitLdvectmp();
- context.EmitStvec(op.Rd);
-
- if (part == 0)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- private static void EmitSse41Frint(ILEmitterCtx context, RoundMode roundMode, bool scalar)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- if (scalar)
- {
- Type[] typesRnd = op.Size == 0
- ? new Type[] { typeof(Vector128), typeof(Vector128) }
- : new Type[] { typeof(Vector128), typeof(Vector128) };
-
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse41).GetMethod(GetScalarSse41NameRnd(roundMode), typesRnd));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- int sizeF = op.Size & 1;
-
- Type[] typesRnd = sizeF == 0
- ? new Type[] { typeof(Vector128) }
- : new Type[] { typeof(Vector128) };
-
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse41).GetMethod(GetVectorSse41NameRnd(roundMode), typesRnd));
-
- context.EmitStvec(op.Rd);
-
- if (sizeF == 0 && op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- }
-
- private static void EmitSse41Mul_AddSub(ILEmitterCtx context, string nameAddSub = null)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- if (nameAddSub != null)
- {
- context.EmitLdvec(op.Rd);
- }
-
- if (op.Size == 0)
- {
- Type[] typesBle = new Type[] { typeof(Vector128), typeof(Vector128), typeof(Vector128) };
- Type[] typesMul = new Type[] { typeof(Vector128), typeof(Vector128) };
- Type[] typesShs = new Type[] { typeof(Vector128), typeof(byte) };
- Type[] typesSav = new Type[] { typeof(int) };
-
- context.EmitLdvec(op.Rn);
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), typesShs));
-
- context.EmitLdvec(op.Rm);
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), typesShs));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.MultiplyLow), typesMul));
-
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), typesShs));
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.MultiplyLow), typesMul));
-
- context.EmitLdc_I4(0x00FF00FF);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitCall(typeof(Sse41).GetMethod(nameof(Sse41.BlendVariable), typesBle));
- }
- else if (op.Size == 1)
- {
- Type[] typesMul = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.MultiplyLow), typesMul));
- }
- else /* if (op.Size == 2) */
- {
- Type[] typesMul = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse41).GetMethod(nameof(Sse41.MultiplyLow), typesMul));
- }
-
- if (nameAddSub != null)
- {
- Type[] typesAddSub = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
-
- context.EmitCall(typeof(Sse2).GetMethod(nameAddSub, typesAddSub));
- }
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- }
-}
diff --git a/ChocolArm64/Instructions/InstEmitSimdCmp.cs b/ChocolArm64/Instructions/InstEmitSimdCmp.cs
deleted file mode 100644
index b29250068e..0000000000
--- a/ChocolArm64/Instructions/InstEmitSimdCmp.cs
+++ /dev/null
@@ -1,862 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.IntermediateRepresentation;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System;
-using System.Reflection.Emit;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-using static ChocolArm64.Instructions.InstEmitAluHelper;
-using static ChocolArm64.Instructions.InstEmitSimdHelper;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
- public static void Cmeq_S(ILEmitterCtx context)
- {
- EmitCmpOp(context, OpCodes.Beq_S, scalar: true);
- }
-
- public static void Cmeq_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- Type[] typesCmp = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
-
- Type typeSse = op.Size != 3 ? typeof(Sse2) : typeof(Sse41);
-
- context.EmitLdvec(op.Rn);
-
- if (op is OpCodeSimdReg64 binOp)
- {
- context.EmitLdvec(binOp.Rm);
- }
- else
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
- }
-
- context.EmitCall(typeSse.GetMethod(nameof(Sse2.CompareEqual), typesCmp));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitCmpOp(context, OpCodes.Beq_S, scalar: false);
- }
- }
-
- public static void Cmge_S(ILEmitterCtx context)
- {
- EmitCmpOp(context, OpCodes.Bge_S, scalar: true);
- }
-
- public static void Cmge_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse42)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- Type[] typesCmp = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
- Type[] typesAnt = new Type[] { typeof(Vector128), typeof(Vector128) };
- Type[] typesSav = new Type[] { typeof(long) };
-
- Type typeSse = op.Size != 3 ? typeof(Sse2) : typeof(Sse42);
-
- if (op is OpCodeSimdReg64 binOp)
- {
- context.EmitLdvec(binOp.Rm);
- }
- else
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
- }
-
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeSse.GetMethod(nameof(Sse2.CompareGreaterThan), typesCmp));
-
- context.EmitLdc_I8(-1L);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAnt));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitCmpOp(context, OpCodes.Bge_S, scalar: false);
- }
- }
-
- public static void Cmgt_S(ILEmitterCtx context)
- {
- EmitCmpOp(context, OpCodes.Bgt_S, scalar: true);
- }
-
- public static void Cmgt_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse42)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- Type[] typesCmp = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
-
- Type typeSse = op.Size != 3 ? typeof(Sse2) : typeof(Sse42);
-
- context.EmitLdvec(op.Rn);
-
- if (op is OpCodeSimdReg64 binOp)
- {
- context.EmitLdvec(binOp.Rm);
- }
- else
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
- }
-
- context.EmitCall(typeSse.GetMethod(nameof(Sse2.CompareGreaterThan), typesCmp));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitCmpOp(context, OpCodes.Bgt_S, scalar: false);
- }
- }
-
- public static void Cmhi_S(ILEmitterCtx context)
- {
- EmitCmpOp(context, OpCodes.Bgt_Un_S, scalar: true);
- }
-
- public static void Cmhi_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- if (Optimizations.UseSse41 && op.Size < 3)
- {
- Type[] typesMax = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], VectorUIntTypesPerSizeLog2[op.Size] };
- Type[] typesCmp = new Type[] { VectorIntTypesPerSizeLog2 [op.Size], VectorIntTypesPerSizeLog2 [op.Size] };
- Type[] typesAnt = new Type[] { typeof(Vector128), typeof(Vector128) };
- Type[] typesSav = new Type[] { typeof(long) };
-
- Type typeSse = op.Size == 0 ? typeof(Sse2) : typeof(Sse41);
-
- context.EmitLdvec(op.Rm);
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeSse.GetMethod(nameof(Sse2.Max), typesMax));
-
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), typesCmp));
-
- context.EmitLdc_I8(-1L);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAnt));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitCmpOp(context, OpCodes.Bgt_Un_S, scalar: false);
- }
- }
-
- public static void Cmhs_S(ILEmitterCtx context)
- {
- EmitCmpOp(context, OpCodes.Bge_Un_S, scalar: true);
- }
-
- public static void Cmhs_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- if (Optimizations.UseSse41 && op.Size < 3)
- {
- Type[] typesMax = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], VectorUIntTypesPerSizeLog2[op.Size] };
- Type[] typesCmp = new Type[] { VectorIntTypesPerSizeLog2 [op.Size], VectorIntTypesPerSizeLog2 [op.Size] };
-
- Type typeSse = op.Size == 0 ? typeof(Sse2) : typeof(Sse41);
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeSse.GetMethod(nameof(Sse2.Max), typesMax));
-
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), typesCmp));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitCmpOp(context, OpCodes.Bge_Un_S, scalar: false);
- }
- }
-
- public static void Cmle_S(ILEmitterCtx context)
- {
- EmitCmpOp(context, OpCodes.Ble_S, scalar: true);
- }
-
- public static void Cmle_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse42)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- Type[] typesCmp = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
- Type[] typesAnt = new Type[] { typeof(Vector128), typeof(Vector128) };
- Type[] typesSav = new Type[] { typeof(long) };
-
- Type typeSse = op.Size != 3 ? typeof(Sse2) : typeof(Sse42);
-
- context.EmitLdvec(op.Rn);
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
-
- context.EmitCall(typeSse.GetMethod(nameof(Sse2.CompareGreaterThan), typesCmp));
-
- context.EmitLdc_I8(-1L);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAnt));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitCmpOp(context, OpCodes.Ble_S, scalar: false);
- }
- }
-
- public static void Cmlt_S(ILEmitterCtx context)
- {
- EmitCmpOp(context, OpCodes.Blt_S, scalar: true);
- }
-
- public static void Cmlt_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse42)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- Type[] typesCmp = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
-
- Type typeSse = op.Size != 3 ? typeof(Sse2) : typeof(Sse42);
-
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeSse.GetMethod(nameof(Sse2.CompareGreaterThan), typesCmp));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitCmpOp(context, OpCodes.Blt_S, scalar: false);
- }
- }
-
- public static void Cmtst_S(ILEmitterCtx context)
- {
- EmitCmtstOp(context, scalar: true);
- }
-
- public static void Cmtst_V(ILEmitterCtx context)
- {
- EmitCmtstOp(context, scalar: false);
- }
-
- public static void Fccmp_S(ILEmitterCtx context)
- {
- OpCodeSimdFcond64 op = (OpCodeSimdFcond64)context.CurrOp;
-
- ILLabel lblTrue = new ILLabel();
- ILLabel lblEnd = new ILLabel();
-
- context.EmitCondBranch(lblTrue, op.Cond);
-
- context.EmitLdc_I4(op.Nzcv);
- EmitSetNzcv(context);
-
- context.Emit(OpCodes.Br, lblEnd);
-
- context.MarkLabel(lblTrue);
-
- EmitFcmpOrFcmpe(context, signalNaNs: false);
-
- context.MarkLabel(lblEnd);
- }
-
- public static void Fccmpe_S(ILEmitterCtx context)
- {
- OpCodeSimdFcond64 op = (OpCodeSimdFcond64)context.CurrOp;
-
- ILLabel lblTrue = new ILLabel();
- ILLabel lblEnd = new ILLabel();
-
- context.EmitCondBranch(lblTrue, op.Cond);
-
- context.EmitLdc_I4(op.Nzcv);
- EmitSetNzcv(context);
-
- context.Emit(OpCodes.Br, lblEnd);
-
- context.MarkLabel(lblTrue);
-
- EmitFcmpOrFcmpe(context, signalNaNs: true);
-
- context.MarkLabel(lblEnd);
- }
-
- public static void Fcmeq_S(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitCmpSseOrSse2OpF(context, nameof(Sse.CompareEqualScalar), scalar: true);
- }
- else
- {
- EmitCmpOpF(context, nameof(SoftFloat32.FPCompareEQ), scalar: true);
- }
- }
-
- public static void Fcmeq_V(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitCmpSseOrSse2OpF(context, nameof(Sse.CompareEqual), scalar: false);
- }
- else
- {
- EmitCmpOpF(context, nameof(SoftFloat32.FPCompareEQ), scalar: false);
- }
- }
-
- public static void Fcmge_S(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitCmpSseOrSse2OpF(context, nameof(Sse.CompareGreaterThanOrEqualScalar), scalar: true);
- }
- else
- {
- EmitCmpOpF(context, nameof(SoftFloat32.FPCompareGE), scalar: true);
- }
- }
-
- public static void Fcmge_V(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitCmpSseOrSse2OpF(context, nameof(Sse.CompareGreaterThanOrEqual), scalar: false);
- }
- else
- {
- EmitCmpOpF(context, nameof(SoftFloat32.FPCompareGE), scalar: false);
- }
- }
-
- public static void Fcmgt_S(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitCmpSseOrSse2OpF(context, nameof(Sse.CompareGreaterThanScalar), scalar: true);
- }
- else
- {
- EmitCmpOpF(context, nameof(SoftFloat32.FPCompareGT), scalar: true);
- }
- }
-
- public static void Fcmgt_V(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitCmpSseOrSse2OpF(context, nameof(Sse.CompareGreaterThan), scalar: false);
- }
- else
- {
- EmitCmpOpF(context, nameof(SoftFloat32.FPCompareGT), scalar: false);
- }
- }
-
- public static void Fcmle_S(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitCmpSseOrSse2OpF(context, nameof(Sse.CompareGreaterThanOrEqualScalar), scalar: true, isLeOrLt: true);
- }
- else
- {
- EmitCmpOpF(context, nameof(SoftFloat32.FPCompareLE), scalar: true);
- }
- }
-
- public static void Fcmle_V(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitCmpSseOrSse2OpF(context, nameof(Sse.CompareGreaterThanOrEqual), scalar: false, isLeOrLt: true);
- }
- else
- {
- EmitCmpOpF(context, nameof(SoftFloat32.FPCompareLE), scalar: false);
- }
- }
-
- public static void Fcmlt_S(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitCmpSseOrSse2OpF(context, nameof(Sse.CompareGreaterThanScalar), scalar: true, isLeOrLt: true);
- }
- else
- {
- EmitCmpOpF(context, nameof(SoftFloat32.FPCompareLT), scalar: true);
- }
- }
-
- public static void Fcmlt_V(ILEmitterCtx context)
- {
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- EmitCmpSseOrSse2OpF(context, nameof(Sse.CompareGreaterThan), scalar: false, isLeOrLt: true);
- }
- else
- {
- EmitCmpOpF(context, nameof(SoftFloat32.FPCompareLT), scalar: false);
- }
- }
-
- public static void Fcmp_S(ILEmitterCtx context)
- {
- EmitFcmpOrFcmpe(context, signalNaNs: false);
- }
-
- public static void Fcmpe_S(ILEmitterCtx context)
- {
- EmitFcmpOrFcmpe(context, signalNaNs: true);
- }
-
- private static void EmitFcmpOrFcmpe(ILEmitterCtx context, bool signalNaNs)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- bool cmpWithZero = !(op is OpCodeSimdFcond64) ? op.Bit3 : false;
-
- if (Optimizations.FastFP && Optimizations.UseSse2)
- {
- if (op.Size == 0)
- {
- Type[] typesCmp = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- ILLabel lblNaN = new ILLabel();
- ILLabel lblEnd = new ILLabel();
-
- context.EmitLdvec(op.Rn);
-
- if (cmpWithZero)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
- }
- else
- {
- context.EmitLdvec(op.Rm);
- }
-
- context.EmitStvectmp();
- context.EmitLdvectmp();
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.CompareOrderedScalar), typesCmp));
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.CompareEqualOrderedScalar), typesCmp));
-
- context.Emit(OpCodes.Brtrue_S, lblNaN);
-
- context.Emit(OpCodes.Ldc_I4_0);
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvectmp();
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.CompareGreaterThanOrEqualOrderedScalar), typesCmp));
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvectmp();
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.CompareEqualOrderedScalar), typesCmp));
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvectmp();
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.CompareLessThanOrderedScalar), typesCmp));
-
- context.EmitStflg((int)PState.NBit);
- context.EmitStflg((int)PState.ZBit);
- context.EmitStflg((int)PState.CBit);
- context.EmitStflg((int)PState.VBit);
-
- context.Emit(OpCodes.Br_S, lblEnd);
-
- context.MarkLabel(lblNaN);
-
- context.Emit(OpCodes.Ldc_I4_1);
- context.Emit(OpCodes.Ldc_I4_1);
- context.Emit(OpCodes.Ldc_I4_0);
- context.Emit(OpCodes.Ldc_I4_0);
-
- context.EmitStflg((int)PState.NBit);
- context.EmitStflg((int)PState.ZBit);
- context.EmitStflg((int)PState.CBit);
- context.EmitStflg((int)PState.VBit);
-
- context.MarkLabel(lblEnd);
- }
- else /* if (op.Size == 1) */
- {
- Type[] typesCmp = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- ILLabel lblNaN = new ILLabel();
- ILLabel lblEnd = new ILLabel();
-
- context.EmitLdvec(op.Rn);
-
- if (cmpWithZero)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
- }
- else
- {
- context.EmitLdvec(op.Rm);
- }
-
- context.EmitStvectmp();
- context.EmitLdvectmp();
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareOrderedScalar), typesCmp));
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareEqualOrderedScalar), typesCmp));
-
- context.Emit(OpCodes.Brtrue_S, lblNaN);
-
- context.Emit(OpCodes.Ldc_I4_0);
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvectmp();
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanOrEqualOrderedScalar), typesCmp));
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvectmp();
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareEqualOrderedScalar), typesCmp));
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvectmp();
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanOrderedScalar), typesCmp));
-
- context.EmitStflg((int)PState.NBit);
- context.EmitStflg((int)PState.ZBit);
- context.EmitStflg((int)PState.CBit);
- context.EmitStflg((int)PState.VBit);
-
- context.Emit(OpCodes.Br_S, lblEnd);
-
- context.MarkLabel(lblNaN);
-
- context.Emit(OpCodes.Ldc_I4_1);
- context.Emit(OpCodes.Ldc_I4_1);
- context.Emit(OpCodes.Ldc_I4_0);
- context.Emit(OpCodes.Ldc_I4_0);
-
- context.EmitStflg((int)PState.NBit);
- context.EmitStflg((int)PState.ZBit);
- context.EmitStflg((int)PState.CBit);
- context.EmitStflg((int)PState.VBit);
-
- context.MarkLabel(lblEnd);
- }
- }
- else
- {
- EmitVectorExtractF(context, op.Rn, 0, op.Size);
-
- if (cmpWithZero)
- {
- if (op.Size == 0)
- {
- context.EmitLdc_R4(0f);
- }
- else /* if (op.Size == 1) */
- {
- context.EmitLdc_R8(0d);
- }
- }
- else
- {
- EmitVectorExtractF(context, op.Rm, 0, op.Size);
- }
-
- context.EmitLdc_I4(!signalNaNs ? 0 : 1);
-
- EmitSoftFloatCall(context, nameof(SoftFloat32.FPCompare));
-
- EmitSetNzcv(context);
- }
- }
-
- private static void EmitCmpOp(ILEmitterCtx context, OpCode ilOp, bool scalar)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = !scalar ? bytes >> op.Size : 1;
-
- ulong szMask = ulong.MaxValue >> (64 - (8 << op.Size));
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractSx(context, op.Rn, index, op.Size);
-
- if (op is OpCodeSimdReg64 binOp)
- {
- EmitVectorExtractSx(context, binOp.Rm, index, op.Size);
- }
- else
- {
- context.EmitLdc_I8(0L);
- }
-
- ILLabel lblTrue = new ILLabel();
- ILLabel lblEnd = new ILLabel();
-
- context.Emit(ilOp, lblTrue);
-
- EmitVectorInsert(context, op.Rd, index, op.Size, 0);
-
- context.Emit(OpCodes.Br_S, lblEnd);
-
- context.MarkLabel(lblTrue);
-
- EmitVectorInsert(context, op.Rd, index, op.Size, (long)szMask);
-
- context.MarkLabel(lblEnd);
- }
-
- if ((op.RegisterSize == RegisterSize.Simd64) || scalar)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- private static void EmitCmtstOp(ILEmitterCtx context, bool scalar)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = !scalar ? bytes >> op.Size : 1;
-
- ulong szMask = ulong.MaxValue >> (64 - (8 << op.Size));
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractZx(context, op.Rn, index, op.Size);
- EmitVectorExtractZx(context, op.Rm, index, op.Size);
-
- ILLabel lblTrue = new ILLabel();
- ILLabel lblEnd = new ILLabel();
-
- context.Emit(OpCodes.And);
-
- context.EmitLdc_I8(0L);
-
- context.Emit(OpCodes.Bne_Un_S, lblTrue);
-
- EmitVectorInsert(context, op.Rd, index, op.Size, 0);
-
- context.Emit(OpCodes.Br_S, lblEnd);
-
- context.MarkLabel(lblTrue);
-
- EmitVectorInsert(context, op.Rd, index, op.Size, (long)szMask);
-
- context.MarkLabel(lblEnd);
- }
-
- if ((op.RegisterSize == RegisterSize.Simd64) || scalar)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- private static void EmitCmpOpF(ILEmitterCtx context, string name, bool scalar)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = !scalar ? bytes >> sizeF + 2 : 1;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractF(context, op.Rn, index, sizeF);
-
- if (op is OpCodeSimdReg64 binOp)
- {
- EmitVectorExtractF(context, binOp.Rm, index, sizeF);
- }
- else
- {
- if (sizeF == 0)
- {
- context.EmitLdc_R4(0f);
- }
- else /* if (sizeF == 1) */
- {
- context.EmitLdc_R8(0d);
- }
- }
-
- EmitSoftFloatCall(context, name);
-
- EmitVectorInsertF(context, op.Rd, index, sizeF);
- }
-
- if (!scalar)
- {
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- if (sizeF == 0)
- {
- EmitVectorZero32_128(context, op.Rd);
- }
- else /* if (sizeF == 1) */
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- }
-
- private static void EmitCmpSseOrSse2OpF(ILEmitterCtx context, string name, bool scalar, bool isLeOrLt = false)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (sizeF == 0)
- {
- Type[] types = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- if (!isLeOrLt)
- {
- context.EmitLdvec(op.Rn);
- }
-
- if (op is OpCodeSimdReg64 binOp)
- {
- context.EmitLdvec(binOp.Rm);
- }
- else
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
- }
-
- if (isLeOrLt)
- {
- context.EmitLdvec(op.Rn);
- }
-
- context.EmitCall(typeof(Sse).GetMethod(name, types));
-
- context.EmitStvec(op.Rd);
-
- if (scalar)
- {
- EmitVectorZero32_128(context, op.Rd);
- }
- else if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else /* if (sizeF == 1) */
- {
- Type[] types = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- if (!isLeOrLt)
- {
- context.EmitLdvec(op.Rn);
- }
-
- if (op is OpCodeSimdReg64 binOp)
- {
- context.EmitLdvec(binOp.Rm);
- }
- else
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
- }
-
- if (isLeOrLt)
- {
- context.EmitLdvec(op.Rn);
- }
-
- context.EmitCall(typeof(Sse2).GetMethod(name, types));
-
- context.EmitStvec(op.Rd);
-
- if (scalar)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- }
- }
-}
diff --git a/ChocolArm64/Instructions/InstEmitSimdCrypto.cs b/ChocolArm64/Instructions/InstEmitSimdCrypto.cs
deleted file mode 100644
index 33c81aab0a..0000000000
--- a/ChocolArm64/Instructions/InstEmitSimdCrypto.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.Translation;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
- public static void Aesd_V(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.Decrypt));
-
- context.EmitStvec(op.Rd);
- }
-
- public static void Aese_V(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.Encrypt));
-
- context.EmitStvec(op.Rd);
- }
-
- public static void Aesimc_V(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- context.EmitLdvec(op.Rn);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.InverseMixColumns));
-
- context.EmitStvec(op.Rd);
- }
-
- public static void Aesmc_V(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- context.EmitLdvec(op.Rn);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.MixColumns));
-
- context.EmitStvec(op.Rd);
- }
- }
-}
diff --git a/ChocolArm64/Instructions/InstEmitSimdCvt.cs b/ChocolArm64/Instructions/InstEmitSimdCvt.cs
deleted file mode 100644
index 2b3deb98e0..0000000000
--- a/ChocolArm64/Instructions/InstEmitSimdCvt.cs
+++ /dev/null
@@ -1,1382 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System;
-using System.Reflection.Emit;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-using static ChocolArm64.Instructions.InstEmitSimdHelper;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
- public static void Fcvt_S(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- if (op.Size == 0 && op.Opc == 1) // Single -> Double.
- {
- if (Optimizations.UseSse2)
- {
- Type[] typesCvt = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertScalarToVector128Double), typesCvt));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitVectorExtractF(context, op.Rn, 0, 0);
-
- EmitFloatCast(context, 1);
-
- EmitScalarSetF(context, op.Rd, 1);
- }
- }
- else if (op.Size == 1 && op.Opc == 0) // Double -> Single.
- {
- if (Optimizations.UseSse2)
- {
- Type[] typesCvt = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertScalarToVector128Single), typesCvt));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitVectorExtractF(context, op.Rn, 0, 1);
-
- EmitFloatCast(context, 0);
-
- EmitScalarSetF(context, op.Rd, 0);
- }
- }
- else if (op.Size == 0 && op.Opc == 3) // Single -> Half.
- {
- EmitVectorExtractF(context, op.Rn, 0, 0);
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- context.EmitCall(typeof(SoftFloat32_16), nameof(SoftFloat32_16.FPConvert));
-
- context.Emit(OpCodes.Conv_U8);
- EmitScalarSet(context, op.Rd, 1);
- }
- else if (op.Size == 3 && op.Opc == 0) // Half -> Single.
- {
- EmitVectorExtractZx(context, op.Rn, 0, 1);
- context.Emit(OpCodes.Conv_U2);
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- context.EmitCall(typeof(SoftFloat16_32), nameof(SoftFloat16_32.FPConvert));
-
- EmitScalarSetF(context, op.Rd, 0);
- }
- else if (op.Size == 1 && op.Opc == 3) // Double -> Half.
- {
- throw new NotImplementedException("Double-precision to half-precision.");
- }
- else if (op.Size == 3 && op.Opc == 1) // Double -> Half.
- {
- throw new NotImplementedException("Half-precision to double-precision.");
- }
- else // Invalid encoding.
- {
- throw new InvalidOperationException($"type == {op.Size} && opc == {op.Opc}");
- }
- }
-
- public static void Fcvtas_Gp(ILEmitterCtx context)
- {
- EmitFcvt_s_Gp(context, () => EmitRoundMathCall(context, MidpointRounding.AwayFromZero));
- }
-
- public static void Fcvtau_Gp(ILEmitterCtx context)
- {
- EmitFcvt_u_Gp(context, () => EmitRoundMathCall(context, MidpointRounding.AwayFromZero));
- }
-
- public static void Fcvtl_V(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (Optimizations.UseSse2 && sizeF == 1)
- {
- Type[] typesCvt = new Type[] { typeof(Vector128) };
-
- context.EmitLdvec(op.Rn);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveHighToLow)));
- }
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToVector128Double), typesCvt));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- int elems = 4 >> sizeF;
-
- int part = op.RegisterSize == RegisterSize.Simd128 ? elems : 0;
-
- for (int index = 0; index < elems; index++)
- {
- if (sizeF == 0)
- {
- EmitVectorExtractZx(context, op.Rn, part + index, 1);
- context.Emit(OpCodes.Conv_U2);
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- context.EmitCall(typeof(SoftFloat16_32), nameof(SoftFloat16_32.FPConvert));
- }
- else /* if (sizeF == 1) */
- {
- EmitVectorExtractF(context, op.Rn, part + index, 0);
-
- context.Emit(OpCodes.Conv_R8);
- }
-
- EmitVectorInsertTmpF(context, index, sizeF);
- }
-
- context.EmitLdvectmp();
- context.EmitStvec(op.Rd);
- }
- }
-
- public static void Fcvtms_Gp(ILEmitterCtx context)
- {
- EmitFcvt_s_Gp(context, () => EmitUnaryMathCall(context, nameof(Math.Floor)));
- }
-
- public static void Fcvtmu_Gp(ILEmitterCtx context)
- {
- EmitFcvt_u_Gp(context, () => EmitUnaryMathCall(context, nameof(Math.Floor)));
- }
-
- public static void Fcvtn_V(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (Optimizations.UseSse2 && sizeF == 1)
- {
- Type[] typesCvt = new Type[] { typeof(Vector128) };
-
- string nameMov = op.RegisterSize == RegisterSize.Simd128
- ? nameof(Sse.MoveLowToHigh)
- : nameof(Sse.MoveHighToLow);
-
- context.EmitLdvec(op.Rd);
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveLowToHigh)));
-
- context.EmitLdvec(op.Rn);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToVector128Single), typesCvt));
- context.Emit(OpCodes.Dup);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveLowToHigh)));
-
- context.EmitCall(typeof(Sse).GetMethod(nameMov));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- int elems = 4 >> sizeF;
-
- int part = op.RegisterSize == RegisterSize.Simd128 ? elems : 0;
-
- if (part != 0)
- {
- context.EmitLdvec(op.Rd);
- context.EmitStvectmp();
- }
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractF(context, op.Rn, index, sizeF);
-
- if (sizeF == 0)
- {
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- context.EmitCall(typeof(SoftFloat32_16), nameof(SoftFloat32_16.FPConvert));
-
- context.Emit(OpCodes.Conv_U8);
- EmitVectorInsertTmp(context, part + index, 1);
- }
- else /* if (sizeF == 1) */
- {
- context.Emit(OpCodes.Conv_R4);
-
- EmitVectorInsertTmpF(context, part + index, 0);
- }
- }
-
- context.EmitLdvectmp();
- context.EmitStvec(op.Rd);
-
- if (part == 0)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- }
-
- public static void Fcvtns_S(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- EmitSse41Fcvt_Signed(context, RoundMode.ToNearest, scalar: true);
- }
- else
- {
- EmitFcvtn(context, signed: true, scalar: true);
- }
- }
-
- public static void Fcvtns_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- EmitSse41Fcvt_Signed(context, RoundMode.ToNearest, scalar: false);
- }
- else
- {
- EmitFcvtn(context, signed: true, scalar: false);
- }
- }
-
- public static void Fcvtnu_S(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- EmitSse41Fcvt_Unsigned(context, RoundMode.ToNearest, scalar: true);
- }
- else
- {
- EmitFcvtn(context, signed: false, scalar: true);
- }
- }
-
- public static void Fcvtnu_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- EmitSse41Fcvt_Unsigned(context, RoundMode.ToNearest, scalar: false);
- }
- else
- {
- EmitFcvtn(context, signed: false, scalar: false);
- }
- }
-
- public static void Fcvtps_Gp(ILEmitterCtx context)
- {
- EmitFcvt_s_Gp(context, () => EmitUnaryMathCall(context, nameof(Math.Ceiling)));
- }
-
- public static void Fcvtpu_Gp(ILEmitterCtx context)
- {
- EmitFcvt_u_Gp(context, () => EmitUnaryMathCall(context, nameof(Math.Ceiling)));
- }
-
- public static void Fcvtzs_Gp(ILEmitterCtx context)
- {
- EmitFcvt_s_Gp(context, () => { });
- }
-
- public static void Fcvtzs_Gp_Fixed(ILEmitterCtx context)
- {
- EmitFcvtzs_Gp_Fixed(context);
- }
-
- public static void Fcvtzs_S(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- EmitSse41Fcvt_Signed(context, RoundMode.TowardsZero, scalar: true);
- }
- else
- {
- EmitFcvtz(context, signed: true, scalar: true);
- }
- }
-
- public static void Fcvtzs_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- EmitSse41Fcvt_Signed(context, RoundMode.TowardsZero, scalar: false);
- }
- else
- {
- EmitFcvtz(context, signed: true, scalar: false);
- }
- }
-
- public static void Fcvtzs_V_Fixed(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- EmitSse41Fcvt_Signed(context, RoundMode.TowardsZero, scalar: false);
- }
- else
- {
- EmitFcvtz(context, signed: true, scalar: false);
- }
- }
-
- public static void Fcvtzu_Gp(ILEmitterCtx context)
- {
- EmitFcvt_u_Gp(context, () => { });
- }
-
- public static void Fcvtzu_Gp_Fixed(ILEmitterCtx context)
- {
- EmitFcvtzu_Gp_Fixed(context);
- }
-
- public static void Fcvtzu_S(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- EmitSse41Fcvt_Unsigned(context, RoundMode.TowardsZero, scalar: true);
- }
- else
- {
- EmitFcvtz(context, signed: false, scalar: true);
- }
- }
-
- public static void Fcvtzu_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- EmitSse41Fcvt_Unsigned(context, RoundMode.TowardsZero, scalar: false);
- }
- else
- {
- EmitFcvtz(context, signed: false, scalar: false);
- }
- }
-
- public static void Fcvtzu_V_Fixed(ILEmitterCtx context)
- {
- if (Optimizations.UseSse41)
- {
- EmitSse41Fcvt_Unsigned(context, RoundMode.TowardsZero, scalar: false);
- }
- else
- {
- EmitFcvtz(context, signed: false, scalar: false);
- }
- }
-
- public static void Scvtf_Gp(ILEmitterCtx context)
- {
- OpCodeSimdCvt64 op = (OpCodeSimdCvt64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
-
- if (context.CurrOp.RegisterSize == RegisterSize.Int32)
- {
- context.Emit(OpCodes.Conv_I4);
- }
-
- EmitFloatCast(context, op.Size);
-
- EmitScalarSetF(context, op.Rd, op.Size);
- }
-
- public static void Scvtf_Gp_Fixed(ILEmitterCtx context)
- {
- OpCodeSimdCvt64 op = (OpCodeSimdCvt64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
-
- if (context.CurrOp.RegisterSize == RegisterSize.Int32)
- {
- context.Emit(OpCodes.Conv_I4);
- }
-
- EmitFloatCast(context, op.Size);
-
- EmitI2fFBitsMul(context, op.Size, op.FBits);
-
- EmitScalarSetF(context, op.Rd, op.Size);
- }
-
- public static void Scvtf_S(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (Optimizations.UseSse2 && sizeF == 0)
- {
- EmitSse2cvtF_Signed(context, scalar: true);
- }
- else
- {
- EmitVectorExtractSx(context, op.Rn, 0, sizeF + 2);
-
- EmitFloatCast(context, sizeF);
-
- EmitScalarSetF(context, op.Rd, sizeF);
- }
- }
-
- public static void Scvtf_V(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (Optimizations.UseSse2 && sizeF == 0)
- {
- EmitSse2cvtF_Signed(context, scalar: false);
- }
- else
- {
- EmitVectorCvtf(context, signed: true);
- }
- }
-
- public static void Scvtf_V_Fixed(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- // sizeF == ((OpCodeSimdShImm64)op).Size - 2
- int sizeF = op.Size & 1;
-
- if (Optimizations.UseSse2 && sizeF == 0)
- {
- EmitSse2cvtF_Signed(context, scalar: false);
- }
- else
- {
- EmitVectorCvtf(context, signed: true);
- }
- }
-
- public static void Ucvtf_Gp(ILEmitterCtx context)
- {
- OpCodeSimdCvt64 op = (OpCodeSimdCvt64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
-
- if (context.CurrOp.RegisterSize == RegisterSize.Int32)
- {
- context.Emit(OpCodes.Conv_U4);
- }
-
- context.Emit(OpCodes.Conv_R_Un);
-
- EmitFloatCast(context, op.Size);
-
- EmitScalarSetF(context, op.Rd, op.Size);
- }
-
- public static void Ucvtf_Gp_Fixed(ILEmitterCtx context)
- {
- OpCodeSimdCvt64 op = (OpCodeSimdCvt64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
-
- if (context.CurrOp.RegisterSize == RegisterSize.Int32)
- {
- context.Emit(OpCodes.Conv_U4);
- }
-
- context.Emit(OpCodes.Conv_R_Un);
-
- EmitFloatCast(context, op.Size);
-
- EmitI2fFBitsMul(context, op.Size, op.FBits);
-
- EmitScalarSetF(context, op.Rd, op.Size);
- }
-
- public static void Ucvtf_S(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (Optimizations.UseSse2 && sizeF == 0)
- {
- EmitSse2cvtF_Unsigned(context, scalar: true);
- }
- else
- {
- EmitVectorExtractZx(context, op.Rn, 0, sizeF + 2);
-
- context.Emit(OpCodes.Conv_R_Un);
-
- EmitFloatCast(context, sizeF);
-
- EmitScalarSetF(context, op.Rd, sizeF);
- }
- }
-
- public static void Ucvtf_V(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (Optimizations.UseSse2 && sizeF == 0)
- {
- EmitSse2cvtF_Unsigned(context, scalar: false);
- }
- else
- {
- EmitVectorCvtf(context, signed: false);
- }
- }
-
- public static void Ucvtf_V_Fixed(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- // sizeF == ((OpCodeSimdShImm64)op).Size - 2
- int sizeF = op.Size & 1;
-
- if (Optimizations.UseSse2 && sizeF == 0)
- {
- EmitSse2cvtF_Unsigned(context, scalar: false);
- }
- else
- {
- EmitVectorCvtf(context, signed: false);
- }
- }
-
- private static void EmitFcvtn(ILEmitterCtx context, bool signed, bool scalar)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
- int sizeI = sizeF + 2;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = !scalar ? bytes >> sizeI : 1;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractF(context, op.Rn, index, sizeF);
-
- EmitRoundMathCall(context, MidpointRounding.ToEven);
-
- if (sizeF == 0)
- {
- VectorHelper.EmitCall(context, signed
- ? nameof(VectorHelper.SatF32ToS32)
- : nameof(VectorHelper.SatF32ToU32));
-
- context.Emit(OpCodes.Conv_U8);
- }
- else /* if (sizeF == 1) */
- {
- VectorHelper.EmitCall(context, signed
- ? nameof(VectorHelper.SatF64ToS64)
- : nameof(VectorHelper.SatF64ToU64));
- }
-
- if (scalar)
- {
- EmitVectorZeroAll(context, op.Rd);
- }
-
- EmitVectorInsert(context, op.Rd, index, sizeI);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- private static void EmitFcvtz(ILEmitterCtx context, bool signed, bool scalar)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
- int sizeI = sizeF + 2;
-
- int fBits = GetFBits(context);
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = !scalar ? bytes >> sizeI : 1;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractF(context, op.Rn, index, sizeF);
-
- EmitF2iFBitsMul(context, sizeF, fBits);
-
- if (sizeF == 0)
- {
- VectorHelper.EmitCall(context, signed
- ? nameof(VectorHelper.SatF32ToS32)
- : nameof(VectorHelper.SatF32ToU32));
-
- context.Emit(OpCodes.Conv_U8);
- }
- else /* if (sizeF == 1) */
- {
- VectorHelper.EmitCall(context, signed
- ? nameof(VectorHelper.SatF64ToS64)
- : nameof(VectorHelper.SatF64ToU64));
- }
-
- if (scalar)
- {
- EmitVectorZeroAll(context, op.Rd);
- }
-
- EmitVectorInsert(context, op.Rd, index, sizeI);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- private static void EmitFcvt_s_Gp(ILEmitterCtx context, Action emit)
- {
- EmitFcvt___Gp(context, emit, true);
- }
-
- private static void EmitFcvt_u_Gp(ILEmitterCtx context, Action emit)
- {
- EmitFcvt___Gp(context, emit, false);
- }
-
- private static void EmitFcvt___Gp(ILEmitterCtx context, Action emit, bool signed)
- {
- OpCodeSimdCvt64 op = (OpCodeSimdCvt64)context.CurrOp;
-
- EmitVectorExtractF(context, op.Rn, 0, op.Size);
-
- emit();
-
- if (signed)
- {
- EmitScalarFcvts(context, op.Size, 0);
- }
- else
- {
- EmitScalarFcvtu(context, op.Size, 0);
- }
-
- if (context.CurrOp.RegisterSize == RegisterSize.Int32)
- {
- context.Emit(OpCodes.Conv_U8);
- }
-
- context.EmitStintzr(op.Rd);
- }
-
- private static void EmitFcvtzs_Gp_Fixed(ILEmitterCtx context)
- {
- EmitFcvtz__Gp_Fixed(context, true);
- }
-
- private static void EmitFcvtzu_Gp_Fixed(ILEmitterCtx context)
- {
- EmitFcvtz__Gp_Fixed(context, false);
- }
-
- private static void EmitFcvtz__Gp_Fixed(ILEmitterCtx context, bool signed)
- {
- OpCodeSimdCvt64 op = (OpCodeSimdCvt64)context.CurrOp;
-
- EmitVectorExtractF(context, op.Rn, 0, op.Size);
-
- if (signed)
- {
- EmitScalarFcvts(context, op.Size, op.FBits);
- }
- else
- {
- EmitScalarFcvtu(context, op.Size, op.FBits);
- }
-
- if (context.CurrOp.RegisterSize == RegisterSize.Int32)
- {
- context.Emit(OpCodes.Conv_U8);
- }
-
- context.EmitStintzr(op.Rd);
- }
-
- private static void EmitVectorCvtf(ILEmitterCtx context, bool signed)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
- int sizeI = sizeF + 2;
-
- int fBits = GetFBits(context);
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> sizeI;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtract(context, op.Rn, index, sizeI, signed);
-
- if (!signed)
- {
- context.Emit(OpCodes.Conv_R_Un);
- }
-
- EmitFloatCast(context, sizeF);
-
- EmitI2fFBitsMul(context, sizeF, fBits);
-
- EmitVectorInsertF(context, op.Rd, index, sizeF);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- private static int GetFBits(ILEmitterCtx context)
- {
- if (context.CurrOp is OpCodeSimdShImm64 op)
- {
- return GetImmShr(op);
- }
-
- return 0;
- }
-
- private static void EmitFloatCast(ILEmitterCtx context, int size)
- {
- if (size == 0)
- {
- context.Emit(OpCodes.Conv_R4);
- }
- else if (size == 1)
- {
- context.Emit(OpCodes.Conv_R8);
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(size));
- }
- }
-
- private static void EmitScalarFcvts(ILEmitterCtx context, int size, int fBits)
- {
- if (size < 0 || size > 1)
- {
- throw new ArgumentOutOfRangeException(nameof(size));
- }
-
- EmitF2iFBitsMul(context, size, fBits);
-
- if (context.CurrOp.RegisterSize == RegisterSize.Int32)
- {
- if (size == 0)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.SatF32ToS32));
- }
- else /* if (size == 1) */
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.SatF64ToS32));
- }
- }
- else
- {
- if (size == 0)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.SatF32ToS64));
- }
- else /* if (size == 1) */
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.SatF64ToS64));
- }
- }
- }
-
- private static void EmitScalarFcvtu(ILEmitterCtx context, int size, int fBits)
- {
- if (size < 0 || size > 1)
- {
- throw new ArgumentOutOfRangeException(nameof(size));
- }
-
- EmitF2iFBitsMul(context, size, fBits);
-
- if (context.CurrOp.RegisterSize == RegisterSize.Int32)
- {
- if (size == 0)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.SatF32ToU32));
- }
- else /* if (size == 1) */
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.SatF64ToU32));
- }
- }
- else
- {
- if (size == 0)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.SatF32ToU64));
- }
- else /* if (size == 1) */
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.SatF64ToU64));
- }
- }
- }
-
- private static void EmitF2iFBitsMul(ILEmitterCtx context, int size, int fBits)
- {
- if (fBits != 0)
- {
- if (size == 0)
- {
- context.EmitLdc_R4(MathF.Pow(2f, fBits));
- }
- else if (size == 1)
- {
- context.EmitLdc_R8(Math.Pow(2d, fBits));
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(size));
- }
-
- context.Emit(OpCodes.Mul);
- }
- }
-
- private static void EmitI2fFBitsMul(ILEmitterCtx context, int size, int fBits)
- {
- if (fBits != 0)
- {
- if (size == 0)
- {
- context.EmitLdc_R4(1f / MathF.Pow(2f, fBits));
- }
- else if (size == 1)
- {
- context.EmitLdc_R8(1d / Math.Pow(2d, fBits));
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(size));
- }
-
- context.Emit(OpCodes.Mul);
- }
- }
-
- private static void EmitSse41Fcvt_Signed(ILEmitterCtx context, RoundMode roundMode, bool scalar)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- // sizeF == ((OpCodeSimdShImm64)op).Size - 2
- int sizeF = op.Size & 1;
-
- if (sizeF == 0)
- {
- Type[] types = new Type[] { typeof(Vector128), typeof(Vector128) };
- Type[] typesRndCvt = new Type[] { typeof(Vector128) };
- Type[] typesSav = new Type[] { typeof(int) };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.CompareOrdered), types));
-
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.And), types));
-
- if (op is OpCodeSimdShImm64 fixedOp)
- {
- int fBits = GetImmShr(fixedOp);
-
- // BitConverter.Int32BitsToSingle(fpScaled) == MathF.Pow(2f, fBits)
- int fpScaled = 0x3F800000 + fBits * 0x800000;
-
- context.EmitLdc_I4(fpScaled);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), types));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(GetVectorSse41NameRnd(roundMode), typesRndCvt));
-
- context.EmitStvectmp();
- context.EmitLdvectmp();
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToVector128Int32), typesRndCvt));
-
- context.EmitLdvectmp();
-
- context.EmitLdc_I4(0x4F000000); // 2.14748365E9f (2147483648)
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.CompareGreaterThanOrEqual), types));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Xor), types));
-
- context.EmitStvec(op.Rd);
-
- if (scalar)
- {
- EmitVectorZero32_128(context, op.Rd);
- }
- else if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else /* if (sizeF == 1) */
- {
- Type[] types = new Type[] { typeof(Vector128), typeof(Vector128) };
- Type[] typesRndCvt = new Type[] { typeof(Vector128) };
- Type[] typesSv = new Type[] { typeof(long), typeof(long) };
- Type[] typesSav = new Type[] { typeof(long) };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareOrdered), types));
-
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.And), types));
-
- if (op is OpCodeSimdShImm64 fixedOp)
- {
- int fBits = GetImmShr(fixedOp);
-
- // BitConverter.Int64BitsToDouble(fpScaled) == Math.Pow(2d, fBits)
- long fpScaled = 0x3FF0000000000000L + fBits * 0x10000000000000L;
-
- context.EmitLdc_I8(fpScaled);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), types));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(GetVectorSse41NameRnd(roundMode), typesRndCvt));
-
- context.EmitStvectmp();
-
- if (!scalar)
- {
- context.EmitLdvectmp();
- context.EmitLdvectmp();
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), types));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToInt64), typesRndCvt));
- }
- else
- {
- context.EmitLdc_I8(0L);
- }
-
- context.EmitLdvectmp();
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToInt64), typesRndCvt));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetVector128), typesSv));
-
- context.EmitLdvectmp();
-
- context.EmitLdc_I8(0x43E0000000000000L); // 9.2233720368547760E18d (9223372036854775808)
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanOrEqual), types));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), types));
-
- context.EmitStvec(op.Rd);
-
- if (scalar)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- }
-
- private static void EmitSse41Fcvt_Unsigned(ILEmitterCtx context, RoundMode roundMode, bool scalar)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- // sizeF == ((OpCodeSimdShImm64)op).Size - 2
- int sizeF = op.Size & 1;
-
- if (sizeF == 0)
- {
- Type[] types = new Type[] { typeof(Vector128), typeof(Vector128) };
- Type[] typesAdd = new Type[] { typeof(Vector128), typeof(Vector128) };
- Type[] typesRndCvt = new Type[] { typeof(Vector128) };
- Type[] typesSav = new Type[] { typeof(int) };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.CompareOrdered), types));
-
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.And), types));
-
- if (op is OpCodeSimdShImm64 fixedOp)
- {
- int fBits = GetImmShr(fixedOp);
-
- // BitConverter.Int32BitsToSingle(fpScaled) == MathF.Pow(2f, fBits)
- int fpScaled = 0x3F800000 + fBits * 0x800000;
-
- context.EmitLdc_I4(fpScaled);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), types));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(GetVectorSse41NameRnd(roundMode), typesRndCvt));
-
- context.Emit(OpCodes.Dup);
-
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.CompareGreaterThan), types));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.And), types));
-
- context.EmitStvectmp();
- context.EmitLdvectmp();
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToVector128Int32), typesRndCvt));
-
- context.EmitLdvectmp();
-
- context.EmitLdc_I4(0x4F000000); // 2.14748365E9f (2147483648)
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitStvectmp2();
- context.EmitLdvectmp2();
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Subtract), types));
-
- context.Emit(OpCodes.Dup);
-
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.CompareGreaterThan), types));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.And), types));
-
- context.EmitStvectmp();
- context.EmitLdvectmp();
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToVector128Int32), typesRndCvt));
-
- context.EmitLdvectmp();
- context.EmitLdvectmp2();
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.CompareGreaterThanOrEqual), types));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Xor), types));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
-
- context.EmitStvec(op.Rd);
-
- if (scalar)
- {
- EmitVectorZero32_128(context, op.Rd);
- }
- else if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else /* if (sizeF == 1) */
- {
- Type[] types = new Type[] { typeof(Vector128), typeof(Vector128) };
- Type[] typesAdd = new Type[] { typeof(Vector128), typeof(Vector128) };
- Type[] typesRndCvt = new Type[] { typeof(Vector128) };
- Type[] typesSv = new Type[] { typeof(long), typeof(long) };
- Type[] typesSav = new Type[] { typeof(long) };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareOrdered), types));
-
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.And), types));
-
- if (op is OpCodeSimdShImm64 fixedOp)
- {
- int fBits = GetImmShr(fixedOp);
-
- // BitConverter.Int64BitsToDouble(fpScaled) == Math.Pow(2d, fBits)
- long fpScaled = 0x3FF0000000000000L + fBits * 0x10000000000000L;
-
- context.EmitLdc_I8(fpScaled);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), types));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(GetVectorSse41NameRnd(roundMode), typesRndCvt));
-
- context.Emit(OpCodes.Dup);
-
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThan), types));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.And), types));
-
- context.EmitStvectmp();
-
- if (!scalar)
- {
- context.EmitLdvectmp();
- context.EmitLdvectmp();
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), types));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToInt64), typesRndCvt));
- }
- else
- {
- context.EmitLdc_I8(0L);
- }
-
- context.EmitLdvectmp();
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToInt64), typesRndCvt));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetVector128), typesSv));
-
- context.EmitLdvectmp();
-
- context.EmitLdc_I8(0x43E0000000000000L); // 9.2233720368547760E18d (9223372036854775808)
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitStvectmp2();
- context.EmitLdvectmp2();
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), types));
-
- context.Emit(OpCodes.Dup);
-
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThan), types));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.And), types));
-
- context.EmitStvectmp();
-
- if (!scalar)
- {
- context.EmitLdvectmp();
- context.EmitLdvectmp();
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), types));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToInt64), typesRndCvt));
- }
- else
- {
- context.EmitLdc_I8(0L);
- }
-
- context.EmitLdvectmp();
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToInt64), typesRndCvt));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetVector128), typesSv));
-
- context.EmitLdvectmp();
- context.EmitLdvectmp2();
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanOrEqual), types));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), types));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
-
- context.EmitStvec(op.Rd);
-
- if (scalar)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- }
-
- private static void EmitSse2cvtF_Signed(ILEmitterCtx context, bool scalar)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- Type[] typesMul = new Type[] { typeof(Vector128), typeof(Vector128) };
- Type[] typesCvt = new Type[] { typeof(Vector128) };
- Type[] typesSav = new Type[] { typeof(int) };
-
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToVector128Single), typesCvt));
-
- if (op is OpCodeSimdShImm64 fixedOp)
- {
- int fBits = GetImmShr(fixedOp);
-
- // BitConverter.Int32BitsToSingle(fpScaled) == 1f / MathF.Pow(2f, fBits)
- int fpScaled = 0x3F800000 - fBits * 0x800000;
-
- context.EmitLdc_I4(fpScaled);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesMul));
- }
-
- context.EmitStvec(op.Rd);
-
- if (scalar)
- {
- EmitVectorZero32_128(context, op.Rd);
- }
- else if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- private static void EmitSse2cvtF_Unsigned(ILEmitterCtx context, bool scalar)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- Type[] typesMulAdd = new Type[] { typeof(Vector128), typeof(Vector128) };
- Type[] typesSrlSll = new Type[] { typeof(Vector128), typeof(byte) };
- Type[] typesCvt = new Type[] { typeof(Vector128) };
- Type[] typesSav = new Type[] { typeof(int) };
-
- context.EmitLdvec(op.Rn);
-
- context.EmitLdc_I4(16);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), typesSrlSll));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToVector128Single), typesCvt));
-
- context.EmitLdc_I4(0x47800000); // 65536.0f (1 << 16)
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesMulAdd));
-
- context.EmitLdvec(op.Rn);
-
- context.EmitLdc_I4(16);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), typesSrlSll));
-
- context.EmitLdc_I4(16);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), typesSrlSll));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToVector128Single), typesCvt));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Add), typesMulAdd));
-
- if (op is OpCodeSimdShImm64 fixedOp)
- {
- int fBits = GetImmShr(fixedOp);
-
- // BitConverter.Int32BitsToSingle(fpScaled) == 1f / MathF.Pow(2f, fBits)
- int fpScaled = 0x3F800000 - fBits * 0x800000;
-
- context.EmitLdc_I4(fpScaled);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesMulAdd));
- }
-
- context.EmitStvec(op.Rd);
-
- if (scalar)
- {
- EmitVectorZero32_128(context, op.Rd);
- }
- else if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- private static string GetScalarSse41NameRnd(RoundMode roundMode)
- {
- switch (roundMode)
- {
- case RoundMode.ToNearest:
- return nameof(Sse41.RoundToNearestIntegerScalar); // even
-
- case RoundMode.TowardsPlusInfinity:
- return nameof(Sse41.RoundToPositiveInfinityScalar);
-
- case RoundMode.TowardsMinusInfinity:
- return nameof(Sse41.RoundToNegativeInfinityScalar);
-
- default: /* case RoundMode.TowardsZero: */
- return nameof(Sse41.RoundToZeroScalar);
- }
- }
-
- private static string GetVectorSse41NameRnd(RoundMode roundMode)
- {
- switch (roundMode)
- {
- case RoundMode.ToNearest:
- return nameof(Sse41.RoundToNearestInteger); // even
-
- case RoundMode.TowardsPlusInfinity:
- return nameof(Sse41.RoundToPositiveInfinity);
-
- case RoundMode.TowardsMinusInfinity:
- return nameof(Sse41.RoundToNegativeInfinity);
-
- default: /* case RoundMode.TowardsZero: */
- return nameof(Sse41.RoundToZero);
- }
- }
- }
-}
diff --git a/ChocolArm64/Instructions/InstEmitSimdHash.cs b/ChocolArm64/Instructions/InstEmitSimdHash.cs
deleted file mode 100644
index bb767fec07..0000000000
--- a/ChocolArm64/Instructions/InstEmitSimdHash.cs
+++ /dev/null
@@ -1,140 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.Translation;
-
-using static ChocolArm64.Instructions.InstEmitSimdHelper;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
-#region "Sha1"
- public static void Sha1c_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- context.EmitLdvec(op.Rd);
- EmitVectorExtractZx(context, op.Rn, 0, 2);
- context.EmitLdvec(op.Rm);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.HashChoose));
-
- context.EmitStvec(op.Rd);
- }
-
- public static void Sha1h_V(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- EmitVectorExtractZx(context, op.Rn, 0, 2);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.FixedRotate));
-
- EmitScalarSet(context, op.Rd, 2);
- }
-
- public static void Sha1m_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- context.EmitLdvec(op.Rd);
- EmitVectorExtractZx(context, op.Rn, 0, 2);
- context.EmitLdvec(op.Rm);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.HashMajority));
-
- context.EmitStvec(op.Rd);
- }
-
- public static void Sha1p_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- context.EmitLdvec(op.Rd);
- EmitVectorExtractZx(context, op.Rn, 0, 2);
- context.EmitLdvec(op.Rm);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.HashParity));
-
- context.EmitStvec(op.Rd);
- }
-
- public static void Sha1su0_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.Sha1SchedulePart1));
-
- context.EmitStvec(op.Rd);
- }
-
- public static void Sha1su1_V(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.Sha1SchedulePart2));
-
- context.EmitStvec(op.Rd);
- }
-#endregion
-
-#region "Sha256"
- public static void Sha256h_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.HashLower));
-
- context.EmitStvec(op.Rd);
- }
-
- public static void Sha256h2_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.HashUpper));
-
- context.EmitStvec(op.Rd);
- }
-
- public static void Sha256su0_V(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.Sha256SchedulePart1));
-
- context.EmitStvec(op.Rd);
- }
-
- public static void Sha256su1_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.Sha256SchedulePart2));
-
- context.EmitStvec(op.Rd);
- }
-#endregion
- }
-}
diff --git a/ChocolArm64/Instructions/InstEmitSimdHelper.cs b/ChocolArm64/Instructions/InstEmitSimdHelper.cs
deleted file mode 100644
index c8c8df743a..0000000000
--- a/ChocolArm64/Instructions/InstEmitSimdHelper.cs
+++ /dev/null
@@ -1,1580 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System;
-using System.Reflection;
-using System.Reflection.Emit;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace ChocolArm64.Instructions
-{
- static class InstEmitSimdHelper
- {
- public static readonly Type[] IntTypesPerSizeLog2 = new Type[]
- {
- typeof(sbyte),
- typeof(short),
- typeof(int),
- typeof(long)
- };
-
- public static readonly Type[] UIntTypesPerSizeLog2 = new Type[]
- {
- typeof(byte),
- typeof(ushort),
- typeof(uint),
- typeof(ulong)
- };
-
- public static readonly Type[] VectorIntTypesPerSizeLog2 = new Type[]
- {
- typeof(Vector128),
- typeof(Vector128),
- typeof(Vector128),
- typeof(Vector128)
- };
-
- public static readonly Type[] VectorUIntTypesPerSizeLog2 = new Type[]
- {
- typeof(Vector128),
- typeof(Vector128),
- typeof(Vector128),
- typeof(Vector128)
- };
-
- [Flags]
- public enum OperFlags
- {
- Rd = 1 << 0,
- Rn = 1 << 1,
- Rm = 1 << 2,
- Ra = 1 << 3,
-
- RnRm = Rn | Rm,
- RdRn = Rd | Rn,
- RaRnRm = Ra | Rn | Rm,
- RdRnRm = Rd | Rn | Rm
- }
-
- public static int GetImmShl(OpCodeSimdShImm64 op)
- {
- return op.Imm - (8 << op.Size);
- }
-
- public static int GetImmShr(OpCodeSimdShImm64 op)
- {
- return (8 << (op.Size + 1)) - op.Imm;
- }
-
- public static void EmitSse2Op(ILEmitterCtx context, string name)
- {
- EmitSseOp(context, name, typeof(Sse2));
- }
-
- public static void EmitSse41Op(ILEmitterCtx context, string name)
- {
- EmitSseOp(context, name, typeof(Sse41));
- }
-
- public static void EmitSse42Op(ILEmitterCtx context, string name)
- {
- EmitSseOp(context, name, typeof(Sse42));
- }
-
- private static void EmitSseOp(ILEmitterCtx context, string name, Type type)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- context.EmitLdvec(op.Rn);
-
- Type baseType = VectorIntTypesPerSizeLog2[op.Size];
-
- if (op is OpCodeSimdReg64 binOp)
- {
- context.EmitLdvec(binOp.Rm);
-
- context.EmitCall(type.GetMethod(name, new Type[] { baseType, baseType }));
- }
- else
- {
- context.EmitCall(type.GetMethod(name, new Type[] { baseType }));
- }
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void EmitScalarSseOrSse2OpF(ILEmitterCtx context, string name)
- {
- EmitSseOrSse2OpF(context, name, true);
- }
-
- public static void EmitVectorSseOrSse2OpF(ILEmitterCtx context, string name)
- {
- EmitSseOrSse2OpF(context, name, false);
- }
-
- public static void EmitSseOrSse2OpF(ILEmitterCtx context, string name, bool scalar)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- context.EmitLdvec(op.Rn);
-
- Type type;
- Type baseType;
-
- if (sizeF == 0)
- {
- type = typeof(Sse);
- baseType = typeof(Vector128);
- }
- else /* if (sizeF == 1) */
- {
- type = typeof(Sse2);
- baseType = typeof(Vector128);
- }
-
- if (op is OpCodeSimdReg64 binOp)
- {
- context.EmitLdvec(binOp.Rm);
-
- context.EmitCall(type.GetMethod(name, new Type[] { baseType, baseType }));
- }
- else
- {
- context.EmitCall(type.GetMethod(name, new Type[] { baseType }));
- }
-
- context.EmitStvec(op.Rd);
-
- if (scalar)
- {
- if (sizeF == 0)
- {
- EmitVectorZero32_128(context, op.Rd);
- }
- else /* if (sizeF == 1) */
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void EmitUnaryMathCall(ILEmitterCtx context, string name)
- {
- IOpCodeSimd64 op = (IOpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- MethodInfo mthdInfo;
-
- if (sizeF == 0)
- {
- mthdInfo = typeof(MathF).GetMethod(name, new Type[] { typeof(float) });
- }
- else /* if (sizeF == 1) */
- {
- mthdInfo = typeof(Math).GetMethod(name, new Type[] { typeof(double) });
- }
-
- context.EmitCall(mthdInfo);
- }
-
- public static void EmitBinaryMathCall(ILEmitterCtx context, string name)
- {
- IOpCodeSimd64 op = (IOpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- MethodInfo mthdInfo;
-
- if (sizeF == 0)
- {
- mthdInfo = typeof(MathF).GetMethod(name, new Type[] { typeof(float), typeof(float) });
- }
- else /* if (sizeF == 1) */
- {
- mthdInfo = typeof(Math).GetMethod(name, new Type[] { typeof(double), typeof(double) });
- }
-
- context.EmitCall(mthdInfo);
- }
-
- public static void EmitRoundMathCall(ILEmitterCtx context, MidpointRounding roundMode)
- {
- IOpCodeSimd64 op = (IOpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- MethodInfo mthdInfo;
-
- if (sizeF == 0)
- {
- mthdInfo = typeof(MathF).GetMethod(nameof(MathF.Round), new Type[] { typeof(float), typeof(MidpointRounding) });
- }
- else /* if (sizeF == 1) */
- {
- mthdInfo = typeof(Math).GetMethod(nameof(Math.Round), new Type[] { typeof(double), typeof(MidpointRounding) });
- }
-
- context.EmitLdc_I4((int)roundMode);
-
- context.EmitCall(mthdInfo);
- }
-
- public static void EmitSoftFloatCall(ILEmitterCtx context, string name)
- {
- IOpCodeSimd64 op = (IOpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- Type type = sizeF == 0
- ? typeof(SoftFloat32)
- : typeof(SoftFloat64);
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- context.EmitCall(type, name);
- }
-
- public static void EmitScalarBinaryOpByElemF(ILEmitterCtx context, Action emit)
- {
- OpCodeSimdRegElemF64 op = (OpCodeSimdRegElemF64)context.CurrOp;
-
- EmitScalarOpByElemF(context, emit, op.Index, ternary: false);
- }
-
- public static void EmitScalarTernaryOpByElemF(ILEmitterCtx context, Action emit)
- {
- OpCodeSimdRegElemF64 op = (OpCodeSimdRegElemF64)context.CurrOp;
-
- EmitScalarOpByElemF(context, emit, op.Index, ternary: true);
- }
-
- public static void EmitScalarOpByElemF(ILEmitterCtx context, Action emit, int elem, bool ternary)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (ternary)
- {
- EmitVectorExtractF(context, op.Rd, 0, sizeF);
- }
-
- EmitVectorExtractF(context, op.Rn, 0, sizeF);
- EmitVectorExtractF(context, op.Rm, elem, sizeF);
-
- emit();
-
- EmitScalarSetF(context, op.Rd, sizeF);
- }
-
- public static void EmitScalarUnaryOpSx(ILEmitterCtx context, Action emit)
- {
- EmitScalarOp(context, emit, OperFlags.Rn, true);
- }
-
- public static void EmitScalarBinaryOpSx(ILEmitterCtx context, Action emit)
- {
- EmitScalarOp(context, emit, OperFlags.RnRm, true);
- }
-
- public static void EmitScalarUnaryOpZx(ILEmitterCtx context, Action emit)
- {
- EmitScalarOp(context, emit, OperFlags.Rn, false);
- }
-
- public static void EmitScalarBinaryOpZx(ILEmitterCtx context, Action emit)
- {
- EmitScalarOp(context, emit, OperFlags.RnRm, false);
- }
-
- public static void EmitScalarTernaryOpZx(ILEmitterCtx context, Action emit)
- {
- EmitScalarOp(context, emit, OperFlags.RdRnRm, false);
- }
-
- public static void EmitScalarOp(ILEmitterCtx context, Action emit, OperFlags opers, bool signed)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- bool rd = (opers & OperFlags.Rd) != 0;
- bool rn = (opers & OperFlags.Rn) != 0;
- bool rm = (opers & OperFlags.Rm) != 0;
-
- if (rd)
- {
- EmitVectorExtract(context, op.Rd, 0, op.Size, signed);
- }
-
- if (rn)
- {
- EmitVectorExtract(context, op.Rn, 0, op.Size, signed);
- }
-
- if (rm)
- {
- EmitVectorExtract(context, ((OpCodeSimdReg64)op).Rm, 0, op.Size, signed);
- }
-
- emit();
-
- EmitScalarSet(context, op.Rd, op.Size);
- }
-
- public static void EmitScalarUnaryOpF(ILEmitterCtx context, Action emit)
- {
- EmitScalarOpF(context, emit, OperFlags.Rn);
- }
-
- public static void EmitScalarBinaryOpF(ILEmitterCtx context, Action emit)
- {
- EmitScalarOpF(context, emit, OperFlags.RnRm);
- }
-
- public static void EmitScalarTernaryRaOpF(ILEmitterCtx context, Action emit)
- {
- EmitScalarOpF(context, emit, OperFlags.RaRnRm);
- }
-
- public static void EmitScalarOpF(ILEmitterCtx context, Action emit, OperFlags opers)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- bool ra = (opers & OperFlags.Ra) != 0;
- bool rn = (opers & OperFlags.Rn) != 0;
- bool rm = (opers & OperFlags.Rm) != 0;
-
- if (ra)
- {
- EmitVectorExtractF(context, ((OpCodeSimdReg64)op).Ra, 0, sizeF);
- }
-
- if (rn)
- {
- EmitVectorExtractF(context, op.Rn, 0, sizeF);
- }
-
- if (rm)
- {
- EmitVectorExtractF(context, ((OpCodeSimdReg64)op).Rm, 0, sizeF);
- }
-
- emit();
-
- EmitScalarSetF(context, op.Rd, sizeF);
- }
-
- public static void EmitVectorUnaryOpF(ILEmitterCtx context, Action emit)
- {
- EmitVectorOpF(context, emit, OperFlags.Rn);
- }
-
- public static void EmitVectorBinaryOpF(ILEmitterCtx context, Action emit)
- {
- EmitVectorOpF(context, emit, OperFlags.RnRm);
- }
-
- public static void EmitVectorTernaryOpF(ILEmitterCtx context, Action emit)
- {
- EmitVectorOpF(context, emit, OperFlags.RdRnRm);
- }
-
- public static void EmitVectorOpF(ILEmitterCtx context, Action emit, OperFlags opers)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> sizeF + 2;
-
- bool rd = (opers & OperFlags.Rd) != 0;
- bool rn = (opers & OperFlags.Rn) != 0;
- bool rm = (opers & OperFlags.Rm) != 0;
-
- for (int index = 0; index < elems; index++)
- {
- if (rd)
- {
- EmitVectorExtractF(context, op.Rd, index, sizeF);
- }
-
- if (rn)
- {
- EmitVectorExtractF(context, op.Rn, index, sizeF);
- }
-
- if (rm)
- {
- EmitVectorExtractF(context, ((OpCodeSimdReg64)op).Rm, index, sizeF);
- }
-
- emit();
-
- EmitVectorInsertF(context, op.Rd, index, sizeF);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void EmitVectorBinaryOpByElemF(ILEmitterCtx context, Action emit)
- {
- OpCodeSimdRegElemF64 op = (OpCodeSimdRegElemF64)context.CurrOp;
-
- EmitVectorOpByElemF(context, emit, op.Index, ternary: false);
- }
-
- public static void EmitVectorTernaryOpByElemF(ILEmitterCtx context, Action emit)
- {
- OpCodeSimdRegElemF64 op = (OpCodeSimdRegElemF64)context.CurrOp;
-
- EmitVectorOpByElemF(context, emit, op.Index, ternary: true);
- }
-
- public static void EmitVectorOpByElemF(ILEmitterCtx context, Action emit, int elem, bool ternary)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> sizeF + 2;
-
- for (int index = 0; index < elems; index++)
- {
- if (ternary)
- {
- EmitVectorExtractF(context, op.Rd, index, sizeF);
- }
-
- EmitVectorExtractF(context, op.Rn, index, sizeF);
- EmitVectorExtractF(context, op.Rm, elem, sizeF);
-
- emit();
-
- EmitVectorInsertTmpF(context, index, sizeF);
- }
-
- context.EmitLdvectmp();
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void EmitVectorUnaryOpSx(ILEmitterCtx context, Action emit)
- {
- EmitVectorOp(context, emit, OperFlags.Rn, true);
- }
-
- public static void EmitVectorBinaryOpSx(ILEmitterCtx context, Action emit)
- {
- EmitVectorOp(context, emit, OperFlags.RnRm, true);
- }
-
- public static void EmitVectorTernaryOpSx(ILEmitterCtx context, Action emit)
- {
- EmitVectorOp(context, emit, OperFlags.RdRnRm, true);
- }
-
- public static void EmitVectorUnaryOpZx(ILEmitterCtx context, Action emit)
- {
- EmitVectorOp(context, emit, OperFlags.Rn, false);
- }
-
- public static void EmitVectorBinaryOpZx(ILEmitterCtx context, Action emit)
- {
- EmitVectorOp(context, emit, OperFlags.RnRm, false);
- }
-
- public static void EmitVectorTernaryOpZx(ILEmitterCtx context, Action emit)
- {
- EmitVectorOp(context, emit, OperFlags.RdRnRm, false);
- }
-
- public static void EmitVectorOp(ILEmitterCtx context, Action emit, OperFlags opers, bool signed)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> op.Size;
-
- bool rd = (opers & OperFlags.Rd) != 0;
- bool rn = (opers & OperFlags.Rn) != 0;
- bool rm = (opers & OperFlags.Rm) != 0;
-
- for (int index = 0; index < elems; index++)
- {
- if (rd)
- {
- EmitVectorExtract(context, op.Rd, index, op.Size, signed);
- }
-
- if (rn)
- {
- EmitVectorExtract(context, op.Rn, index, op.Size, signed);
- }
-
- if (rm)
- {
- EmitVectorExtract(context, ((OpCodeSimdReg64)op).Rm, index, op.Size, signed);
- }
-
- emit();
-
- EmitVectorInsert(context, op.Rd, index, op.Size);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void EmitVectorBinaryOpByElemSx(ILEmitterCtx context, Action emit)
- {
- OpCodeSimdRegElem64 op = (OpCodeSimdRegElem64)context.CurrOp;
-
- EmitVectorOpByElem(context, emit, op.Index, ternary: false, signed: true);
- }
-
- public static void EmitVectorBinaryOpByElemZx(ILEmitterCtx context, Action emit)
- {
- OpCodeSimdRegElem64 op = (OpCodeSimdRegElem64)context.CurrOp;
-
- EmitVectorOpByElem(context, emit, op.Index, ternary: false, signed: false);
- }
-
- public static void EmitVectorTernaryOpByElemZx(ILEmitterCtx context, Action emit)
- {
- OpCodeSimdRegElem64 op = (OpCodeSimdRegElem64)context.CurrOp;
-
- EmitVectorOpByElem(context, emit, op.Index, ternary: true, signed: false);
- }
-
- public static void EmitVectorOpByElem(ILEmitterCtx context, Action emit, int elem, bool ternary, bool signed)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> op.Size;
-
- EmitVectorExtract(context, op.Rm, elem, op.Size, signed);
- context.EmitSttmp();
-
- for (int index = 0; index < elems; index++)
- {
- if (ternary)
- {
- EmitVectorExtract(context, op.Rd, index, op.Size, signed);
- }
-
- EmitVectorExtract(context, op.Rn, index, op.Size, signed);
- context.EmitLdtmp();
-
- emit();
-
- EmitVectorInsert(context, op.Rd, index, op.Size);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void EmitVectorImmUnaryOp(ILEmitterCtx context, Action emit)
- {
- EmitVectorImmOp(context, emit, false);
- }
-
- public static void EmitVectorImmBinaryOp(ILEmitterCtx context, Action emit)
- {
- EmitVectorImmOp(context, emit, true);
- }
-
- public static void EmitVectorImmOp(ILEmitterCtx context, Action emit, bool binary)
- {
- OpCodeSimdImm64 op = (OpCodeSimdImm64)context.CurrOp;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> op.Size;
-
- for (int index = 0; index < elems; index++)
- {
- if (binary)
- {
- EmitVectorExtractZx(context, op.Rd, index, op.Size);
- }
-
- context.EmitLdc_I8(op.Imm);
-
- emit();
-
- EmitVectorInsert(context, op.Rd, index, op.Size);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void EmitVectorWidenRmBinaryOpSx(ILEmitterCtx context, Action emit)
- {
- EmitVectorWidenRmBinaryOp(context, emit, true);
- }
-
- public static void EmitVectorWidenRmBinaryOpZx(ILEmitterCtx context, Action emit)
- {
- EmitVectorWidenRmBinaryOp(context, emit, false);
- }
-
- public static void EmitVectorWidenRmBinaryOp(ILEmitterCtx context, Action emit, bool signed)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int elems = 8 >> op.Size;
-
- int part = op.RegisterSize == RegisterSize.Simd128 ? elems : 0;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtract(context, op.Rn, index, op.Size + 1, signed);
- EmitVectorExtract(context, op.Rm, part + index, op.Size, signed);
-
- emit();
-
- EmitVectorInsertTmp(context, index, op.Size + 1);
- }
-
- context.EmitLdvectmp();
- context.EmitStvec(op.Rd);
- }
-
- public static void EmitVectorWidenRnRmBinaryOpSx(ILEmitterCtx context, Action emit)
- {
- EmitVectorWidenRnRmOp(context, emit, false, true);
- }
-
- public static void EmitVectorWidenRnRmBinaryOpZx(ILEmitterCtx context, Action emit)
- {
- EmitVectorWidenRnRmOp(context, emit, false, false);
- }
-
- public static void EmitVectorWidenRnRmTernaryOpSx(ILEmitterCtx context, Action emit)
- {
- EmitVectorWidenRnRmOp(context, emit, true, true);
- }
-
- public static void EmitVectorWidenRnRmTernaryOpZx(ILEmitterCtx context, Action emit)
- {
- EmitVectorWidenRnRmOp(context, emit, true, false);
- }
-
- public static void EmitVectorWidenRnRmOp(ILEmitterCtx context, Action emit, bool ternary, bool signed)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int elems = 8 >> op.Size;
-
- int part = op.RegisterSize == RegisterSize.Simd128 ? elems : 0;
-
- for (int index = 0; index < elems; index++)
- {
- if (ternary)
- {
- EmitVectorExtract(context, op.Rd, index, op.Size + 1, signed);
- }
-
- EmitVectorExtract(context, op.Rn, part + index, op.Size, signed);
- EmitVectorExtract(context, op.Rm, part + index, op.Size, signed);
-
- emit();
-
- EmitVectorInsertTmp(context, index, op.Size + 1);
- }
-
- context.EmitLdvectmp();
- context.EmitStvec(op.Rd);
- }
-
- public static void EmitVectorWidenBinaryOpByElemSx(ILEmitterCtx context, Action emit)
- {
- OpCodeSimdRegElem64 op = (OpCodeSimdRegElem64)context.CurrOp;
-
- EmitVectorWidenOpByElem(context, emit, op.Index, ternary: false, signed: true);
- }
-
- public static void EmitVectorWidenBinaryOpByElemZx(ILEmitterCtx context, Action emit)
- {
- OpCodeSimdRegElem64 op = (OpCodeSimdRegElem64)context.CurrOp;
-
- EmitVectorWidenOpByElem(context, emit, op.Index, ternary: false, signed: false);
- }
-
- public static void EmitVectorWidenTernaryOpByElemSx(ILEmitterCtx context, Action emit)
- {
- OpCodeSimdRegElem64 op = (OpCodeSimdRegElem64)context.CurrOp;
-
- EmitVectorWidenOpByElem(context, emit, op.Index, ternary: true, signed: true);
- }
-
- public static void EmitVectorWidenTernaryOpByElemZx(ILEmitterCtx context, Action emit)
- {
- OpCodeSimdRegElem64 op = (OpCodeSimdRegElem64)context.CurrOp;
-
- EmitVectorWidenOpByElem(context, emit, op.Index, ternary: true, signed: false);
- }
-
- public static void EmitVectorWidenOpByElem(ILEmitterCtx context, Action emit, int elem, bool ternary, bool signed)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int elems = 8 >> op.Size;
-
- int part = op.RegisterSize == RegisterSize.Simd128 ? elems : 0;
-
- EmitVectorExtract(context, op.Rm, elem, op.Size, signed);
- context.EmitSttmp();
-
- for (int index = 0; index < elems; index++)
- {
- if (ternary)
- {
- EmitVectorExtract(context, op.Rd, index, op.Size + 1, signed);
- }
-
- EmitVectorExtract(context, op.Rn, part + index, op.Size, signed);
- context.EmitLdtmp();
-
- emit();
-
- EmitVectorInsertTmp(context, index, op.Size + 1);
- }
-
- context.EmitLdvectmp();
- context.EmitStvec(op.Rd);
- }
-
- public static void EmitVectorPairwiseOpSx(ILEmitterCtx context, Action emit)
- {
- EmitVectorPairwiseOp(context, emit, true);
- }
-
- public static void EmitVectorPairwiseOpZx(ILEmitterCtx context, Action emit)
- {
- EmitVectorPairwiseOp(context, emit, false);
- }
-
- public static void EmitVectorPairwiseOp(ILEmitterCtx context, Action emit, bool signed)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int words = op.GetBitsCount() >> 4;
- int pairs = words >> op.Size;
-
- for (int index = 0; index < pairs; index++)
- {
- int idx = index << 1;
-
- EmitVectorExtract(context, op.Rn, idx, op.Size, signed);
- EmitVectorExtract(context, op.Rn, idx + 1, op.Size, signed);
-
- emit();
-
- EmitVectorExtract(context, op.Rm, idx, op.Size, signed);
- EmitVectorExtract(context, op.Rm, idx + 1, op.Size, signed);
-
- emit();
-
- EmitVectorInsertTmp(context, pairs + index, op.Size);
- EmitVectorInsertTmp(context, index, op.Size);
- }
-
- context.EmitLdvectmp();
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void EmitVectorAcrossVectorOpSx(ILEmitterCtx context, Action emit)
- {
- EmitVectorAcrossVectorOp(context, emit, signed: true, isLong: false);
- }
-
- public static void EmitVectorAcrossVectorOpZx(ILEmitterCtx context, Action emit)
- {
- EmitVectorAcrossVectorOp(context, emit, signed: false, isLong: false);
- }
-
- public static void EmitVectorLongAcrossVectorOpSx(ILEmitterCtx context, Action emit)
- {
- EmitVectorAcrossVectorOp(context, emit, signed: true, isLong: true);
- }
-
- public static void EmitVectorLongAcrossVectorOpZx(ILEmitterCtx context, Action emit)
- {
- EmitVectorAcrossVectorOp(context, emit, signed: false, isLong: true);
- }
-
- public static void EmitVectorAcrossVectorOp(
- ILEmitterCtx context,
- Action emit,
- bool signed,
- bool isLong)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> op.Size;
-
- EmitVectorExtract(context, op.Rn, 0, op.Size, signed);
-
- for (int index = 1; index < elems; index++)
- {
- EmitVectorExtract(context, op.Rn, index, op.Size, signed);
-
- emit();
- }
-
- EmitScalarSet(context, op.Rd, isLong ? op.Size + 1 : op.Size);
- }
-
- public static void EmitVectorPairwiseOpF(ILEmitterCtx context, Action emit)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- int words = op.GetBitsCount() >> 4;
- int pairs = words >> sizeF + 2;
-
- for (int index = 0; index < pairs; index++)
- {
- int idx = index << 1;
-
- EmitVectorExtractF(context, op.Rn, idx, sizeF);
- EmitVectorExtractF(context, op.Rn, idx + 1, sizeF);
-
- emit();
-
- EmitVectorExtractF(context, op.Rm, idx, sizeF);
- EmitVectorExtractF(context, op.Rm, idx + 1, sizeF);
-
- emit();
-
- EmitVectorInsertTmpF(context, pairs + index, sizeF);
- EmitVectorInsertTmpF(context, index, sizeF);
- }
-
- context.EmitLdvectmp();
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void EmitVectorPairwiseSseOrSse2OpF(ILEmitterCtx context, string name)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int sizeF = op.Size & 1;
-
- if (sizeF == 0)
- {
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- Type[] types = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.UnpackLow), types));
-
- context.EmitStvectmp();
- context.EmitLdvectmp();
-
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveLowToHigh), types));
-
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
-
- context.EmitLdvectmp();
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveHighToLow), types));
-
- context.EmitCall(typeof(Sse).GetMethod(name, types));
-
- context.EmitStvec(op.Rd);
- }
- else /* if (op.RegisterSize == RegisterSize.Simd128) */
- {
- Type[] typesSfl = new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) };
- Type[] types = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitLdc_I4(2 << 6 | 0 << 4 | 2 << 2 | 0 << 0);
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Shuffle), typesSfl));
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitLdc_I4(3 << 6 | 1 << 4 | 3 << 2 | 1 << 0);
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Shuffle), typesSfl));
-
- context.EmitCall(typeof(Sse).GetMethod(name, types));
-
- context.EmitStvec(op.Rd);
- }
- }
- else /* if (sizeF == 1) */
- {
- Type[] types = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), types));
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), types));
-
- context.EmitCall(typeof(Sse2).GetMethod(name, types));
-
- context.EmitStvec(op.Rd);
- }
- }
-
- [Flags]
- public enum SaturatingFlags
- {
- Scalar = 1 << 0,
- Signed = 1 << 1,
-
- Add = 1 << 2,
- Sub = 1 << 3,
-
- Accumulate = 1 << 4,
-
- ScalarSx = Scalar | Signed,
- ScalarZx = Scalar,
-
- VectorSx = Signed,
- VectorZx = 0
- }
-
- public static void EmitScalarSaturatingUnaryOpSx(ILEmitterCtx context, Action emit)
- {
- EmitSaturatingUnaryOpSx(context, emit, SaturatingFlags.ScalarSx);
- }
-
- public static void EmitVectorSaturatingUnaryOpSx(ILEmitterCtx context, Action emit)
- {
- EmitSaturatingUnaryOpSx(context, emit, SaturatingFlags.VectorSx);
- }
-
- public static void EmitSaturatingUnaryOpSx(ILEmitterCtx context, Action emit, SaturatingFlags flags)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- bool scalar = (flags & SaturatingFlags.Scalar) != 0;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = !scalar ? bytes >> op.Size : 1;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractSx(context, op.Rn, index, op.Size);
-
- emit();
-
- if (op.Size <= 2)
- {
- EmitSatQ(context, op.Size, true, true);
- }
- else /* if (op.Size == 3) */
- {
- EmitUnarySignedSatQAbsOrNeg(context);
- }
-
- if (scalar)
- {
- EmitVectorZeroAll(context, op.Rd);
- }
-
- EmitVectorInsert(context, op.Rd, index, op.Size);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void EmitScalarSaturatingBinaryOpSx(ILEmitterCtx context, SaturatingFlags flags)
- {
- EmitSaturatingBinaryOp(context, () => { }, SaturatingFlags.ScalarSx | flags);
- }
-
- public static void EmitScalarSaturatingBinaryOpZx(ILEmitterCtx context, SaturatingFlags flags)
- {
- EmitSaturatingBinaryOp(context, () => { }, SaturatingFlags.ScalarZx | flags);
- }
-
- public static void EmitVectorSaturatingBinaryOpSx(ILEmitterCtx context, SaturatingFlags flags)
- {
- EmitSaturatingBinaryOp(context, () => { }, SaturatingFlags.VectorSx | flags);
- }
-
- public static void EmitVectorSaturatingBinaryOpZx(ILEmitterCtx context, SaturatingFlags flags)
- {
- EmitSaturatingBinaryOp(context, () => { }, SaturatingFlags.VectorZx | flags);
- }
-
- public static void EmitSaturatingBinaryOp(ILEmitterCtx context, Action emit, SaturatingFlags flags)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- bool scalar = (flags & SaturatingFlags.Scalar) != 0;
- bool signed = (flags & SaturatingFlags.Signed) != 0;
-
- bool add = (flags & SaturatingFlags.Add) != 0;
- bool sub = (flags & SaturatingFlags.Sub) != 0;
-
- bool accumulate = (flags & SaturatingFlags.Accumulate) != 0;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = !scalar ? bytes >> op.Size : 1;
-
- if (add || sub)
- {
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtract(context, op.Rn, index, op.Size, signed);
- EmitVectorExtract(context, ((OpCodeSimdReg64)op).Rm, index, op.Size, signed);
-
- if (op.Size <= 2)
- {
- context.Emit(add ? OpCodes.Add : OpCodes.Sub);
-
- EmitSatQ(context, op.Size, true, signed);
- }
- else /* if (op.Size == 3) */
- {
- if (add)
- {
- EmitBinarySatQAdd(context, signed);
- }
- else /* if (sub) */
- {
- EmitBinarySatQSub(context, signed);
- }
- }
-
- if (scalar)
- {
- EmitVectorZeroAll(context, op.Rd);
- }
-
- EmitVectorInsert(context, op.Rd, index, op.Size);
- }
- }
- else if (accumulate)
- {
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtract(context, op.Rn, index, op.Size, !signed);
- EmitVectorExtract(context, op.Rd, index, op.Size, signed);
-
- if (op.Size <= 2)
- {
- context.Emit(OpCodes.Add);
-
- EmitSatQ(context, op.Size, true, signed);
- }
- else /* if (op.Size == 3) */
- {
- EmitBinarySatQAccumulate(context, signed);
- }
-
- if (scalar)
- {
- EmitVectorZeroAll(context, op.Rd);
- }
-
- EmitVectorInsert(context, op.Rd, index, op.Size);
- }
- }
- else
- {
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtract(context, op.Rn, index, op.Size, signed);
- EmitVectorExtract(context, ((OpCodeSimdReg64)op).Rm, index, op.Size, signed);
-
- emit();
-
- EmitSatQ(context, op.Size, true, signed);
-
- if (scalar)
- {
- EmitVectorZeroAll(context, op.Rd);
- }
-
- EmitVectorInsert(context, op.Rd, index, op.Size);
- }
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- [Flags]
- public enum SaturatingNarrowFlags
- {
- Scalar = 1 << 0,
- SignedSrc = 1 << 1,
- SignedDst = 1 << 2,
-
- ScalarSxSx = Scalar | SignedSrc | SignedDst,
- ScalarSxZx = Scalar | SignedSrc,
- ScalarZxZx = Scalar,
-
- VectorSxSx = SignedSrc | SignedDst,
- VectorSxZx = SignedSrc,
- VectorZxZx = 0
- }
-
- public static void EmitSaturatingNarrowOp(ILEmitterCtx context, SaturatingNarrowFlags flags)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- bool scalar = (flags & SaturatingNarrowFlags.Scalar) != 0;
- bool signedSrc = (flags & SaturatingNarrowFlags.SignedSrc) != 0;
- bool signedDst = (flags & SaturatingNarrowFlags.SignedDst) != 0;
-
- int elems = !scalar ? 8 >> op.Size : 1;
-
- int part = !scalar && (op.RegisterSize == RegisterSize.Simd128) ? elems : 0;
-
- if (scalar)
- {
- EmitVectorZeroLowerTmp(context);
- }
-
- if (part != 0)
- {
- context.EmitLdvec(op.Rd);
- context.EmitStvectmp();
- }
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtract(context, op.Rn, index, op.Size + 1, signedSrc);
-
- EmitSatQ(context, op.Size, signedSrc, signedDst);
-
- EmitVectorInsertTmp(context, part + index, op.Size);
- }
-
- context.EmitLdvectmp();
- context.EmitStvec(op.Rd);
-
- if (part == 0)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- // TSrc (16bit, 32bit, 64bit; signed, unsigned) > TDst (8bit, 16bit, 32bit; signed, unsigned).
- public static void EmitSatQ(ILEmitterCtx context, int sizeDst, bool signedSrc, bool signedDst)
- {
- if ((uint)sizeDst > 2u)
- {
- throw new ArgumentOutOfRangeException(nameof(sizeDst));
- }
-
- context.EmitLdc_I4(sizeDst);
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- if (signedSrc)
- {
- SoftFallback.EmitCall(context, signedDst
- ? nameof(SoftFallback.SignedSrcSignedDstSatQ)
- : nameof(SoftFallback.SignedSrcUnsignedDstSatQ));
- }
- else
- {
- SoftFallback.EmitCall(context, signedDst
- ? nameof(SoftFallback.UnsignedSrcSignedDstSatQ)
- : nameof(SoftFallback.UnsignedSrcUnsignedDstSatQ));
- }
- }
-
- // TSrc (64bit) == TDst (64bit); signed.
- public static void EmitUnarySignedSatQAbsOrNeg(ILEmitterCtx context)
- {
- if (((OpCodeSimd64)context.CurrOp).Size < 3)
- {
- throw new InvalidOperationException();
- }
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.UnarySignedSatQAbsOrNeg));
- }
-
- // TSrcs (64bit) == TDst (64bit); signed, unsigned.
- public static void EmitBinarySatQAdd(ILEmitterCtx context, bool signed)
- {
- if (((OpCodeSimdReg64)context.CurrOp).Size < 3)
- {
- throw new InvalidOperationException();
- }
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- SoftFallback.EmitCall(context, signed
- ? nameof(SoftFallback.BinarySignedSatQAdd)
- : nameof(SoftFallback.BinaryUnsignedSatQAdd));
- }
-
- // TSrcs (64bit) == TDst (64bit); signed, unsigned.
- public static void EmitBinarySatQSub(ILEmitterCtx context, bool signed)
- {
- if (((OpCodeSimdReg64)context.CurrOp).Size < 3)
- {
- throw new InvalidOperationException();
- }
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- SoftFallback.EmitCall(context, signed
- ? nameof(SoftFallback.BinarySignedSatQSub)
- : nameof(SoftFallback.BinaryUnsignedSatQSub));
- }
-
- // TSrcs (64bit) == TDst (64bit); signed, unsigned.
- public static void EmitBinarySatQAccumulate(ILEmitterCtx context, bool signed)
- {
- if (((OpCodeSimd64)context.CurrOp).Size < 3)
- {
- throw new InvalidOperationException();
- }
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- SoftFallback.EmitCall(context, signed
- ? nameof(SoftFallback.BinarySignedSatQAcc)
- : nameof(SoftFallback.BinaryUnsignedSatQAcc));
- }
-
- public static void EmitScalarSet(ILEmitterCtx context, int reg, int size)
- {
- EmitVectorZeroAll(context, reg);
- EmitVectorInsert(context, reg, 0, size);
- }
-
- public static void EmitScalarSetF(ILEmitterCtx context, int reg, int size)
- {
- if (Optimizations.UseSse41 && size == 0)
- {
- // If the type is float, we can perform insertion and
- // zero the upper bits with a single instruction (INSERTPS);
- context.EmitLdvec(reg);
-
- VectorHelper.EmitCall(context, nameof(VectorHelper.Sse41VectorInsertScalarSingle));
-
- context.EmitStvec(reg);
- }
- else
- {
- EmitVectorZeroAll(context, reg);
- EmitVectorInsertF(context, reg, 0, size);
- }
- }
-
- public static void EmitVectorExtractSx(ILEmitterCtx context, int reg, int index, int size)
- {
- EmitVectorExtract(context, reg, index, size, true);
- }
-
- public static void EmitVectorExtractZx(ILEmitterCtx context, int reg, int index, int size)
- {
- EmitVectorExtract(context, reg, index, size, false);
- }
-
- public static void EmitVectorExtract(ILEmitterCtx context, int reg, int index, int size, bool signed)
- {
- ThrowIfInvalid(index, size);
-
- context.EmitLdvec(reg);
- context.EmitLdc_I4(index);
- context.EmitLdc_I4(size);
-
- VectorHelper.EmitCall(context, signed
- ? nameof(VectorHelper.VectorExtractIntSx)
- : nameof(VectorHelper.VectorExtractIntZx));
- }
-
- public static void EmitVectorExtractF(ILEmitterCtx context, int reg, int index, int size)
- {
- ThrowIfInvalidF(index, size);
-
- context.EmitLdvec(reg);
- context.EmitLdc_I4(index);
-
- if (size == 0)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorExtractSingle));
- }
- else if (size == 1)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorExtractDouble));
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(size));
- }
- }
-
- public static void EmitVectorZeroAll(ILEmitterCtx context, int reg)
- {
- if (Optimizations.UseSse)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
-
- context.EmitStvec(reg);
- }
- else
- {
- EmitVectorZeroLower(context, reg);
- EmitVectorZeroUpper(context, reg);
- }
- }
-
- public static void EmitVectorZeroLower(ILEmitterCtx context, int reg)
- {
- EmitVectorInsert(context, reg, 0, 3, 0);
- }
-
- public static void EmitVectorZeroLowerTmp(ILEmitterCtx context)
- {
- if (Optimizations.UseSse)
- {
- context.EmitLdvectmp();
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveHighToLow)));
-
- context.EmitStvectmp();
- }
- else
- {
- EmitVectorInsertTmp(context, 0, 3, 0);
- }
- }
-
- public static void EmitVectorZeroUpper(ILEmitterCtx context, int reg)
- {
- if (Optimizations.UseSse)
- {
- // TODO: Use Sse2.MoveScalar once it is fixed (in .NET Core 3.0),
- // as of the time of writing it just crashes the JIT.
-
- /*Type[] typesMov = new Type[] { typeof(Vector128) };
-
- context.EmitLdvec(reg);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.MoveScalar), typesMov));
-
- context.EmitStvec(reg);*/
-
- context.EmitLdvec(reg);
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveLowToHigh)));
-
- context.EmitStvec(reg);
- }
- else
- {
- EmitVectorInsert(context, reg, 1, 3, 0);
- }
- }
-
- public static void EmitVectorZero32_128(ILEmitterCtx context, int reg)
- {
- if (!Sse.IsSupported)
- {
- throw new PlatformNotSupportedException();
- }
-
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
- context.EmitLdvec(reg);
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveScalar)));
-
- context.EmitStvec(reg);
- }
-
- public static void EmitVectorInsert(ILEmitterCtx context, int reg, int index, int size)
- {
- ThrowIfInvalid(index, size);
-
- context.EmitLdvec(reg);
- context.EmitLdc_I4(index);
- context.EmitLdc_I4(size);
-
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorInsertInt));
-
- context.EmitStvec(reg);
- }
-
- public static void EmitVectorInsertTmp(ILEmitterCtx context, int index, int size)
- {
- ThrowIfInvalid(index, size);
-
- context.EmitLdvectmp();
- context.EmitLdc_I4(index);
- context.EmitLdc_I4(size);
-
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorInsertInt));
-
- context.EmitStvectmp();
- }
-
- public static void EmitVectorInsert(ILEmitterCtx context, int reg, int index, int size, long value)
- {
- ThrowIfInvalid(index, size);
-
- context.EmitLdc_I8(value);
- context.EmitLdvec(reg);
- context.EmitLdc_I4(index);
- context.EmitLdc_I4(size);
-
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorInsertInt));
-
- context.EmitStvec(reg);
- }
-
- public static void EmitVectorInsertTmp(ILEmitterCtx context, int index, int size, long value)
- {
- ThrowIfInvalid(index, size);
-
- context.EmitLdc_I8(value);
- context.EmitLdvectmp();
- context.EmitLdc_I4(index);
- context.EmitLdc_I4(size);
-
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorInsertInt));
-
- context.EmitStvectmp();
- }
-
- public static void EmitVectorInsertF(ILEmitterCtx context, int reg, int index, int size)
- {
- ThrowIfInvalidF(index, size);
-
- context.EmitLdvec(reg);
- context.EmitLdc_I4(index);
-
- if (size == 0)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorInsertSingle));
- }
- else if (size == 1)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorInsertDouble));
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(size));
- }
-
- context.EmitStvec(reg);
- }
-
- public static void EmitVectorInsertTmpF(ILEmitterCtx context, int index, int size)
- {
- ThrowIfInvalidF(index, size);
-
- context.EmitLdvectmp();
- context.EmitLdc_I4(index);
-
- if (size == 0)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorInsertSingle));
- }
- else if (size == 1)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorInsertDouble));
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(size));
- }
-
- context.EmitStvectmp();
- }
-
- private static void ThrowIfInvalid(int index, int size)
- {
- if ((uint)size > 3u)
- {
- throw new ArgumentOutOfRangeException(nameof(size));
- }
-
- if ((uint)index >= 16u >> size)
- {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- }
-
- private static void ThrowIfInvalidF(int index, int size)
- {
- if ((uint)size > 1u)
- {
- throw new ArgumentOutOfRangeException(nameof(size));
- }
-
- if ((uint)index >= 4u >> size)
- {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- }
- }
-}
diff --git a/ChocolArm64/Instructions/InstEmitSimdLogical.cs b/ChocolArm64/Instructions/InstEmitSimdLogical.cs
deleted file mode 100644
index a5a9227410..0000000000
--- a/ChocolArm64/Instructions/InstEmitSimdLogical.cs
+++ /dev/null
@@ -1,437 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System;
-using System.Reflection.Emit;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-using static ChocolArm64.Instructions.InstEmitSimdHelper;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
- public static void And_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse2)
- {
- EmitSse2Op(context, nameof(Sse2.And));
- }
- else
- {
- EmitVectorBinaryOpZx(context, () => context.Emit(OpCodes.And));
- }
- }
-
- public static void Bic_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse2)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- Type[] typesAnt = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rm);
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAnt));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorBinaryOpZx(context, () =>
- {
- context.Emit(OpCodes.Not);
- context.Emit(OpCodes.And);
- });
- }
- }
-
- public static void Bic_Vi(ILEmitterCtx context)
- {
- EmitVectorImmBinaryOp(context, () =>
- {
- context.Emit(OpCodes.Not);
- context.Emit(OpCodes.And);
- });
- }
-
- public static void Bif_V(ILEmitterCtx context)
- {
- EmitBifBit(context, notRm: true);
- }
-
- public static void Bit_V(ILEmitterCtx context)
- {
- EmitBifBit(context, notRm: false);
- }
-
- private static void EmitBifBit(ILEmitterCtx context, bool notRm)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- if (Optimizations.UseSse2)
- {
- Type[] typesXorAnd = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- string nameAnd = notRm ? nameof(Sse2.AndNot) : nameof(Sse2.And);
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rm);
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rd);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), typesXorAnd));
- context.EmitCall(typeof(Sse2).GetMethod(nameAnd, typesXorAnd));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), typesXorAnd));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- int elems = op.RegisterSize == RegisterSize.Simd128 ? 2 : 1;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractZx(context, op.Rd, index, 3);
- context.Emit(OpCodes.Dup);
-
- EmitVectorExtractZx(context, op.Rn, index, 3);
-
- context.Emit(OpCodes.Xor);
-
- EmitVectorExtractZx(context, op.Rm, index, 3);
-
- if (notRm)
- {
- context.Emit(OpCodes.Not);
- }
-
- context.Emit(OpCodes.And);
- context.Emit(OpCodes.Xor);
-
- EmitVectorInsert(context, op.Rd, index, 3);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- }
-
- public static void Bsl_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse2)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- Type[] typesXorAnd = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rm);
- context.EmitLdvec(op.Rm);
- context.EmitLdvec(op.Rn);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), typesXorAnd));
-
- context.EmitLdvec(op.Rd);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.And), typesXorAnd));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), typesXorAnd));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorTernaryOpZx(context, () =>
- {
- context.EmitSttmp();
- context.EmitLdtmp();
-
- context.Emit(OpCodes.Xor);
- context.Emit(OpCodes.And);
-
- context.EmitLdtmp();
-
- context.Emit(OpCodes.Xor);
- });
- }
- }
-
- public static void Eor_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse2)
- {
- EmitSse2Op(context, nameof(Sse2.Xor));
- }
- else
- {
- EmitVectorBinaryOpZx(context, () => context.Emit(OpCodes.Xor));
- }
- }
-
- public static void Not_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse2)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- Type[] typesSav = new Type[] { typeof(long) };
- Type[] typesAnt = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rn);
-
- context.EmitLdc_I8(-1L);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAnt));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorUnaryOpZx(context, () => context.Emit(OpCodes.Not));
- }
- }
-
- public static void Orn_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse2)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- Type[] typesSav = new Type[] { typeof(long) };
- Type[] typesAntOr = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitLdc_I8(-1L);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAntOr));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Or), typesAntOr));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorBinaryOpZx(context, () =>
- {
- context.Emit(OpCodes.Not);
- context.Emit(OpCodes.Or);
- });
- }
- }
-
- public static void Orr_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse2)
- {
- EmitSse2Op(context, nameof(Sse2.Or));
- }
- else
- {
- EmitVectorBinaryOpZx(context, () => context.Emit(OpCodes.Or));
- }
- }
-
- public static void Orr_Vi(ILEmitterCtx context)
- {
- EmitVectorImmBinaryOp(context, () => context.Emit(OpCodes.Or));
- }
-
- public static void Rbit_V(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int elems = op.RegisterSize == RegisterSize.Simd128 ? 16 : 8;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractZx(context, op.Rn, index, 0);
-
- context.Emit(OpCodes.Conv_U4);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.ReverseBits8));
-
- context.Emit(OpCodes.Conv_U8);
-
- EmitVectorInsert(context, op.Rd, index, 0);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void Rev16_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSsse3)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- Type[] typesSve = new Type[] { typeof(long), typeof(long) };
- Type[] typesSfl = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rn); // value
-
- context.EmitLdc_I8(14L << 56 | 15L << 48 | 12L << 40 | 13L << 32 | 10L << 24 | 11L << 16 | 08L << 8 | 09L << 0); // maskE1
- context.EmitLdc_I8(06L << 56 | 07L << 48 | 04L << 40 | 05L << 32 | 02L << 24 | 03L << 16 | 00L << 8 | 01L << 0); // maskE0
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetVector128), typesSve));
-
- context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), typesSfl));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitRev_V(context, containerSize: 1);
- }
- }
-
- public static void Rev32_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSsse3)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- Type[] typesSve = new Type[] { typeof(long), typeof(long) };
- Type[] typesSfl = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rn); // value
-
- if (op.Size == 0)
- {
- context.EmitLdc_I8(12L << 56 | 13L << 48 | 14L << 40 | 15L << 32 | 08L << 24 | 09L << 16 | 10L << 8 | 11L << 0); // maskE1
- context.EmitLdc_I8(04L << 56 | 05L << 48 | 06L << 40 | 07L << 32 | 00L << 24 | 01L << 16 | 02L << 8 | 03L << 0); // maskE0
- }
- else /* if (op.Size == 1) */
- {
- context.EmitLdc_I8(13L << 56 | 12L << 48 | 15L << 40 | 14L << 32 | 09L << 24 | 08L << 16 | 11L << 8 | 10L << 0); // maskE1
- context.EmitLdc_I8(05L << 56 | 04L << 48 | 07L << 40 | 06L << 32 | 01L << 24 | 00L << 16 | 03L << 8 | 02L << 0); // maskE0
- }
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetVector128), typesSve));
-
- context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), typesSfl));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitRev_V(context, containerSize: 2);
- }
- }
-
- public static void Rev64_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSsse3)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- Type[] typesSve = new Type[] { typeof(long), typeof(long) };
- Type[] typesSfl = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rn); // value
-
- if (op.Size == 0)
- {
- context.EmitLdc_I8(08L << 56 | 09L << 48 | 10L << 40 | 11L << 32 | 12L << 24 | 13L << 16 | 14L << 8 | 15L << 0); // maskE1
- context.EmitLdc_I8(00L << 56 | 01L << 48 | 02L << 40 | 03L << 32 | 04L << 24 | 05L << 16 | 06L << 8 | 07L << 0); // maskE0
- }
- else if (op.Size == 1)
- {
- context.EmitLdc_I8(09L << 56 | 08L << 48 | 11L << 40 | 10L << 32 | 13L << 24 | 12L << 16 | 15L << 8 | 14L << 0); // maskE1
- context.EmitLdc_I8(01L << 56 | 00L << 48 | 03L << 40 | 02L << 32 | 05L << 24 | 04L << 16 | 07L << 8 | 06L << 0); // maskE0
- }
- else /* if (op.Size == 2) */
- {
- context.EmitLdc_I8(11L << 56 | 10L << 48 | 09L << 40 | 08L << 32 | 15L << 24 | 14L << 16 | 13L << 8 | 12L << 0); // maskE1
- context.EmitLdc_I8(03L << 56 | 02L << 48 | 01L << 40 | 00L << 32 | 07L << 24 | 06L << 16 | 05L << 8 | 04L << 0); // maskE0
- }
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetVector128), typesSve));
-
- context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), typesSfl));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitRev_V(context, containerSize: 3);
- }
- }
-
- private static void EmitRev_V(ILEmitterCtx context, int containerSize)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> op.Size;
-
- int containerMask = (1 << (containerSize - op.Size)) - 1;
-
- for (int index = 0; index < elems; index++)
- {
- int revIndex = index ^ containerMask;
-
- EmitVectorExtractZx(context, op.Rn, revIndex, op.Size);
-
- EmitVectorInsertTmp(context, index, op.Size);
- }
-
- context.EmitLdvectmp();
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- }
-}
diff --git a/ChocolArm64/Instructions/InstEmitSimdMemory.cs b/ChocolArm64/Instructions/InstEmitSimdMemory.cs
deleted file mode 100644
index 073b0f0a59..0000000000
--- a/ChocolArm64/Instructions/InstEmitSimdMemory.cs
+++ /dev/null
@@ -1,182 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System;
-using System.Reflection.Emit;
-
-using static ChocolArm64.Instructions.InstEmitMemoryHelper;
-using static ChocolArm64.Instructions.InstEmitSimdHelper;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
- public static void Ld__Vms(ILEmitterCtx context)
- {
- EmitSimdMemMs(context, isLoad: true);
- }
-
- public static void Ld__Vss(ILEmitterCtx context)
- {
- EmitSimdMemSs(context, isLoad: true);
- }
-
- public static void St__Vms(ILEmitterCtx context)
- {
- EmitSimdMemMs(context, isLoad: false);
- }
-
- public static void St__Vss(ILEmitterCtx context)
- {
- EmitSimdMemSs(context, isLoad: false);
- }
-
- private static void EmitSimdMemMs(ILEmitterCtx context, bool isLoad)
- {
- OpCodeSimdMemMs64 op = (OpCodeSimdMemMs64)context.CurrOp;
-
- int offset = 0;
-
- for (int rep = 0; rep < op.Reps; rep++)
- for (int elem = 0; elem < op.Elems; elem++)
- for (int sElem = 0; sElem < op.SElems; sElem++)
- {
- int rtt = (op.Rt + rep + sElem) & 0x1f;
-
- if (isLoad)
- {
- context.EmitLdint(op.Rn);
- context.EmitLdc_I8(offset);
-
- context.Emit(OpCodes.Add);
-
- EmitReadZxCall(context, op.Size);
-
- EmitVectorInsert(context, rtt, elem, op.Size);
-
- if (op.RegisterSize == RegisterSize.Simd64 && elem == op.Elems - 1)
- {
- EmitVectorZeroUpper(context, rtt);
- }
- }
- else
- {
- context.EmitLdint(op.Rn);
- context.EmitLdc_I8(offset);
-
- context.Emit(OpCodes.Add);
-
- EmitVectorExtractZx(context, rtt, elem, op.Size);
-
- EmitWriteCall(context, op.Size);
- }
-
- offset += 1 << op.Size;
- }
-
- if (op.WBack)
- {
- EmitSimdMemWBack(context, offset);
- }
- }
-
- private static void EmitSimdMemSs(ILEmitterCtx context, bool isLoad)
- {
- OpCodeSimdMemSs64 op = (OpCodeSimdMemSs64)context.CurrOp;
-
- int offset = 0;
-
- void EmitMemAddress()
- {
- context.EmitLdint(op.Rn);
- context.EmitLdc_I8(offset);
-
- context.Emit(OpCodes.Add);
- }
-
- if (op.Replicate)
- {
- // Only loads uses the replicate mode.
- if (!isLoad)
- {
- throw new InvalidOperationException();
- }
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> op.Size;
-
- for (int sElem = 0; sElem < op.SElems; sElem++)
- {
- int rt = (op.Rt + sElem) & 0x1f;
-
- for (int index = 0; index < elems; index++)
- {
- EmitMemAddress();
-
- EmitReadZxCall(context, op.Size);
-
- EmitVectorInsert(context, rt, index, op.Size);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, rt);
- }
-
- offset += 1 << op.Size;
- }
- }
- else
- {
- for (int sElem = 0; sElem < op.SElems; sElem++)
- {
- int rt = (op.Rt + sElem) & 0x1f;
-
- if (isLoad)
- {
- EmitMemAddress();
-
- EmitReadZxCall(context, op.Size);
-
- EmitVectorInsert(context, rt, op.Index, op.Size);
- }
- else
- {
- EmitMemAddress();
-
- EmitVectorExtractZx(context, rt, op.Index, op.Size);
-
- EmitWriteCall(context, op.Size);
- }
-
- offset += 1 << op.Size;
- }
- }
-
- if (op.WBack)
- {
- EmitSimdMemWBack(context, offset);
- }
- }
-
- private static void EmitSimdMemWBack(ILEmitterCtx context, int offset)
- {
- OpCodeMemReg64 op = (OpCodeMemReg64)context.CurrOp;
-
- context.EmitLdint(op.Rn);
-
- if (op.Rm != RegisterAlias.Zr)
- {
- context.EmitLdint(op.Rm);
- }
- else
- {
- context.EmitLdc_I8(offset);
- }
-
- context.Emit(OpCodes.Add);
-
- context.EmitStint(op.Rn);
- }
- }
-}
\ No newline at end of file
diff --git a/ChocolArm64/Instructions/InstEmitSimdMove.cs b/ChocolArm64/Instructions/InstEmitSimdMove.cs
deleted file mode 100644
index 647a2238a6..0000000000
--- a/ChocolArm64/Instructions/InstEmitSimdMove.cs
+++ /dev/null
@@ -1,793 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.IntermediateRepresentation;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System;
-using System.Reflection.Emit;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-using static ChocolArm64.Instructions.InstEmitSimdHelper;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
-#region "Masks"
- private static readonly long[] _masksE0_TrnUzpXtn = new long[]
- {
- 14L << 56 | 12L << 48 | 10L << 40 | 08L << 32 | 06L << 24 | 04L << 16 | 02L << 8 | 00L << 0,
- 13L << 56 | 12L << 48 | 09L << 40 | 08L << 32 | 05L << 24 | 04L << 16 | 01L << 8 | 00L << 0,
- 11L << 56 | 10L << 48 | 09L << 40 | 08L << 32 | 03L << 24 | 02L << 16 | 01L << 8 | 00L << 0
- };
-
- private static readonly long[] _masksE1_TrnUzp = new long[]
- {
- 15L << 56 | 13L << 48 | 11L << 40 | 09L << 32 | 07L << 24 | 05L << 16 | 03L << 8 | 01L << 0,
- 15L << 56 | 14L << 48 | 11L << 40 | 10L << 32 | 07L << 24 | 06L << 16 | 03L << 8 | 02L << 0,
- 15L << 56 | 14L << 48 | 13L << 40 | 12L << 32 | 07L << 24 | 06L << 16 | 05L << 8 | 04L << 0
- };
-
- private static readonly long[] _masksE0_Uzp = new long[]
- {
- 13L << 56 | 09L << 48 | 05L << 40 | 01L << 32 | 12L << 24 | 08L << 16 | 04L << 8 | 00L << 0,
- 11L << 56 | 10L << 48 | 03L << 40 | 02L << 32 | 09L << 24 | 08L << 16 | 01L << 8 | 00L << 0
- };
-
- private static readonly long[] _masksE1_Uzp = new long[]
- {
- 15L << 56 | 11L << 48 | 07L << 40 | 03L << 32 | 14L << 24 | 10L << 16 | 06L << 8 | 02L << 0,
- 15L << 56 | 14L << 48 | 07L << 40 | 06L << 32 | 13L << 24 | 12L << 16 | 05L << 8 | 04L << 0
- };
-#endregion
-
- public static void Dup_Gp(ILEmitterCtx context)
- {
- OpCodeSimdIns64 op = (OpCodeSimdIns64)context.CurrOp;
-
- if (Optimizations.UseSse2)
- {
- Type[] typesSav = new Type[] { UIntTypesPerSizeLog2[op.Size] };
-
- context.EmitLdintzr(op.Rn);
-
- switch (op.Size)
- {
- case 0: context.Emit(OpCodes.Conv_U1); break;
- case 1: context.Emit(OpCodes.Conv_U2); break;
- case 2: context.Emit(OpCodes.Conv_U4); break;
- }
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> op.Size;
-
- for (int index = 0; index < elems; index++)
- {
- context.EmitLdintzr(op.Rn);
-
- EmitVectorInsert(context, op.Rd, index, op.Size);
- }
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void Dup_S(ILEmitterCtx context)
- {
- OpCodeSimdIns64 op = (OpCodeSimdIns64)context.CurrOp;
-
- EmitVectorExtractZx(context, op.Rn, op.DstIndex, op.Size);
-
- EmitScalarSet(context, op.Rd, op.Size);
- }
-
- public static void Dup_V(ILEmitterCtx context)
- {
- OpCodeSimdIns64 op = (OpCodeSimdIns64)context.CurrOp;
-
- if (Optimizations.UseSse2)
- {
- Type[] typesSav = new Type[] { UIntTypesPerSizeLog2[op.Size] };
-
- EmitVectorExtractZx(context, op.Rn, op.DstIndex, op.Size);
-
- switch (op.Size)
- {
- case 0: context.Emit(OpCodes.Conv_U1); break;
- case 1: context.Emit(OpCodes.Conv_U2); break;
- case 2: context.Emit(OpCodes.Conv_U4); break;
- }
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> op.Size;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractZx(context, op.Rn, op.DstIndex, op.Size);
-
- EmitVectorInsert(context, op.Rd, index, op.Size);
- }
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void Ext_V(ILEmitterCtx context)
- {
- OpCodeSimdExt64 op = (OpCodeSimdExt64)context.CurrOp;
-
- if (Optimizations.UseSse2)
- {
- Type[] typesShs = new Type[] { typeof(Vector128), typeof(byte) };
- Type[] typesOr = new Type[] { typeof(Vector128), typeof(Vector128) };
-
- context.EmitLdvec(op.Rn);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveLowToHigh)));
- }
-
- context.EmitLdc_I4(op.Imm4);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesShs));
-
- context.EmitLdvec(op.Rm);
-
- context.EmitLdc_I4((op.RegisterSize == RegisterSize.Simd64 ? 8 : 16) - op.Imm4);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), typesShs));
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveLowToHigh)));
- }
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Or), typesOr));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- int bytes = op.GetBitsCount() >> 3;
-
- int position = op.Imm4;
-
- for (int index = 0; index < bytes; index++)
- {
- int reg = op.Imm4 + index < bytes ? op.Rn : op.Rm;
-
- if (position == bytes)
- {
- position = 0;
- }
-
- EmitVectorExtractZx(context, reg, position++, 0);
- EmitVectorInsertTmp(context, index, 0);
- }
-
- context.EmitLdvectmp();
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- }
-
- public static void Fcsel_S(ILEmitterCtx context)
- {
- OpCodeSimdFcond64 op = (OpCodeSimdFcond64)context.CurrOp;
-
- ILLabel lblTrue = new ILLabel();
- ILLabel lblEnd = new ILLabel();
-
- context.EmitCondBranch(lblTrue, op.Cond);
-
- EmitVectorExtractF(context, op.Rm, 0, op.Size);
-
- context.Emit(OpCodes.Br_S, lblEnd);
-
- context.MarkLabel(lblTrue);
-
- EmitVectorExtractF(context, op.Rn, 0, op.Size);
-
- context.MarkLabel(lblEnd);
-
- EmitScalarSetF(context, op.Rd, op.Size);
- }
-
- public static void Fmov_Ftoi(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- EmitVectorExtractZx(context, op.Rn, 0, op.Size + 2);
-
- context.EmitStintzr(op.Rd);
- }
-
- public static void Fmov_Ftoi1(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- EmitVectorExtractZx(context, op.Rn, 1, 3);
-
- context.EmitStintzr(op.Rd);
- }
-
- public static void Fmov_Itof(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
-
- EmitScalarSet(context, op.Rd, op.Size + 2);
- }
-
- public static void Fmov_Itof1(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
-
- EmitVectorInsert(context, op.Rd, 1, 3);
- }
-
- public static void Fmov_S(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- EmitVectorExtractF(context, op.Rn, 0, op.Size);
-
- EmitScalarSetF(context, op.Rd, op.Size);
- }
-
- public static void Fmov_Si(ILEmitterCtx context)
- {
- OpCodeSimdFmov64 op = (OpCodeSimdFmov64)context.CurrOp;
-
- context.EmitLdc_I8(op.Imm);
-
- EmitScalarSet(context, op.Rd, op.Size + 2);
- }
-
- public static void Fmov_Vi(ILEmitterCtx context)
- {
- OpCodeSimdImm64 op = (OpCodeSimdImm64)context.CurrOp;
-
- int elems = op.RegisterSize == RegisterSize.Simd128 ? 4 : 2;
-
- for (int index = 0; index < (elems >> op.Size); index++)
- {
- context.EmitLdc_I8(op.Imm);
-
- EmitVectorInsert(context, op.Rd, index, op.Size + 2);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void Ins_Gp(ILEmitterCtx context)
- {
- OpCodeSimdIns64 op = (OpCodeSimdIns64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
-
- EmitVectorInsert(context, op.Rd, op.DstIndex, op.Size);
- }
-
- public static void Ins_V(ILEmitterCtx context)
- {
- OpCodeSimdIns64 op = (OpCodeSimdIns64)context.CurrOp;
-
- EmitVectorExtractZx(context, op.Rn, op.SrcIndex, op.Size);
-
- EmitVectorInsert(context, op.Rd, op.DstIndex, op.Size);
- }
-
- public static void Movi_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse2)
- {
- EmitMoviMvni(context, not: false);
- }
- else
- {
- EmitVectorImmUnaryOp(context, () => { });
- }
- }
-
- public static void Mvni_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSse2)
- {
- EmitMoviMvni(context, not: true);
- }
- else
- {
- EmitVectorImmUnaryOp(context, () => context.Emit(OpCodes.Not));
- }
- }
-
- public static void Smov_S(ILEmitterCtx context)
- {
- OpCodeSimdIns64 op = (OpCodeSimdIns64)context.CurrOp;
-
- EmitVectorExtractSx(context, op.Rn, op.DstIndex, op.Size);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- context.Emit(OpCodes.Conv_U4);
- context.Emit(OpCodes.Conv_U8);
- }
-
- context.EmitStintzr(op.Rd);
- }
-
- public static void Tbl_V(ILEmitterCtx context)
- {
- OpCodeSimdTbl64 op = (OpCodeSimdTbl64)context.CurrOp;
-
- if (Optimizations.UseSsse3)
- {
- Type[] typesCmpSflSub = new Type[] { typeof(Vector128), typeof(Vector128) };
- Type[] typesOr = new Type[] { typeof(Vector128), typeof(Vector128) };
- Type[] typesSav = new Type[] { typeof(long) };
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitLdc_I8(0x0F0F0F0F0F0F0F0FL);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitStvectmp2();
- context.EmitLdvectmp2();
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThan), typesCmpSflSub));
-
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Or), typesOr));
-
- context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), typesCmpSflSub));
-
- for (int index = 1; index < op.Size; index++)
- {
- context.EmitLdvec((op.Rn + index) & 0x1F);
- context.EmitLdvec(op.Rm);
-
- context.EmitLdc_I8(0x1010101010101010L * index);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesCmpSflSub));
-
- context.EmitStvectmp();
- context.EmitLdvectmp();
-
- context.EmitLdvectmp2();
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThan), typesCmpSflSub));
-
- context.EmitLdvectmp();
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Or), typesOr));
-
- context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), typesCmpSflSub));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Or), typesOr));
- }
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- context.EmitLdvec(op.Rm);
-
- for (int index = 0; index < op.Size; index++)
- {
- context.EmitLdvec((op.Rn + index) & 0x1F);
- }
-
- switch (op.Size)
- {
- case 1: VectorHelper.EmitCall(context,
- nameof(VectorHelper.Tbl1_V64),
- nameof(VectorHelper.Tbl1_V128)); break;
-
- case 2: VectorHelper.EmitCall(context,
- nameof(VectorHelper.Tbl2_V64),
- nameof(VectorHelper.Tbl2_V128)); break;
-
- case 3: VectorHelper.EmitCall(context,
- nameof(VectorHelper.Tbl3_V64),
- nameof(VectorHelper.Tbl3_V128)); break;
-
- case 4: VectorHelper.EmitCall(context,
- nameof(VectorHelper.Tbl4_V64),
- nameof(VectorHelper.Tbl4_V128)); break;
-
- default: throw new InvalidOperationException();
- }
-
- context.EmitStvec(op.Rd);
- }
- }
-
- public static void Trn1_V(ILEmitterCtx context)
- {
- EmitVectorTranspose(context, part: 0);
- }
-
- public static void Trn2_V(ILEmitterCtx context)
- {
- EmitVectorTranspose(context, part: 1);
- }
-
- public static void Umov_S(ILEmitterCtx context)
- {
- OpCodeSimdIns64 op = (OpCodeSimdIns64)context.CurrOp;
-
- EmitVectorExtractZx(context, op.Rn, op.DstIndex, op.Size);
-
- context.EmitStintzr(op.Rd);
- }
-
- public static void Uzp1_V(ILEmitterCtx context)
- {
- EmitVectorUnzip(context, part: 0);
- }
-
- public static void Uzp2_V(ILEmitterCtx context)
- {
- EmitVectorUnzip(context, part: 1);
- }
-
- public static void Xtn_V(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- if (Optimizations.UseSsse3)
- {
- Type[] typesSve = new Type[] { typeof(long), typeof(long) };
-
- string nameMov = op.RegisterSize == RegisterSize.Simd128
- ? nameof(Sse.MoveLowToHigh)
- : nameof(Sse.MoveHighToLow);
-
- context.EmitLdvec(op.Rd);
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveLowToHigh)));
-
- context.EmitLdvec(op.Rn); // value
-
- context.EmitLdc_I8(_masksE0_TrnUzpXtn[op.Size]); // mask
- context.Emit(OpCodes.Dup); // mask
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetVector128), typesSve));
-
- context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), GetTypesSflUpk(0)));
-
- context.EmitCall(typeof(Sse).GetMethod(nameMov));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- int elems = 8 >> op.Size;
-
- int part = op.RegisterSize == RegisterSize.Simd128 ? elems : 0;
-
- if (part != 0)
- {
- context.EmitLdvec(op.Rd);
- context.EmitStvectmp();
- }
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractZx(context, op.Rn, index, op.Size + 1);
-
- EmitVectorInsertTmp(context, part + index, op.Size);
- }
-
- context.EmitLdvectmp();
- context.EmitStvec(op.Rd);
-
- if (part == 0)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- }
-
- public static void Zip1_V(ILEmitterCtx context)
- {
- EmitVectorZip(context, part: 0);
- }
-
- public static void Zip2_V(ILEmitterCtx context)
- {
- EmitVectorZip(context, part: 1);
- }
-
- private static void EmitMoviMvni(ILEmitterCtx context, bool not)
- {
- OpCodeSimdImm64 op = (OpCodeSimdImm64)context.CurrOp;
-
- Type[] typesSav = new Type[] { UIntTypesPerSizeLog2[op.Size] };
-
- long imm = op.Imm;
-
- if (not)
- {
- imm = ~imm;
- }
-
- if (op.Size < 3)
- {
- context.EmitLdc_I4((int)imm);
- }
- else
- {
- context.EmitLdc_I8(imm);
- }
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- private static void EmitVectorTranspose(ILEmitterCtx context, int part)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- if (Optimizations.UseSsse3)
- {
- Type[] typesSve = new Type[] { typeof(long), typeof(long) };
-
- string nameUpk = part == 0
- ? nameof(Sse2.UnpackLow)
- : nameof(Sse2.UnpackHigh);
-
- context.EmitLdvec(op.Rn); // value
-
- if (op.Size < 3)
- {
- context.EmitLdc_I8(_masksE1_TrnUzp [op.Size]); // maskE1
- context.EmitLdc_I8(_masksE0_TrnUzpXtn[op.Size]); // maskE0
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetVector128), typesSve));
-
- context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), GetTypesSflUpk(0)));
- }
-
- context.EmitLdvec(op.Rm); // value
-
- if (op.Size < 3)
- {
- context.EmitLdc_I8(_masksE1_TrnUzp [op.Size]); // maskE1
- context.EmitLdc_I8(_masksE0_TrnUzpXtn[op.Size]); // maskE0
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetVector128), typesSve));
-
- context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), GetTypesSflUpk(0)));
- }
-
- context.EmitCall(typeof(Sse2).GetMethod(nameUpk, GetTypesSflUpk(op.Size)));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- int words = op.GetBitsCount() >> 4;
- int pairs = words >> op.Size;
-
- for (int index = 0; index < pairs; index++)
- {
- int idx = index << 1;
-
- EmitVectorExtractZx(context, op.Rn, idx + part, op.Size);
- EmitVectorExtractZx(context, op.Rm, idx + part, op.Size);
-
- EmitVectorInsertTmp(context, idx + 1, op.Size);
- EmitVectorInsertTmp(context, idx, op.Size);
- }
-
- context.EmitLdvectmp();
- context.EmitStvec(op.Rd);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- private static void EmitVectorUnzip(ILEmitterCtx context, int part)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- if (Optimizations.UseSsse3)
- {
- Type[] typesSve = new Type[] { typeof(long), typeof(long) };
-
- string nameUpk = part == 0
- ? nameof(Sse2.UnpackLow)
- : nameof(Sse2.UnpackHigh);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.EmitLdvec(op.Rn); // value
-
- if (op.Size < 3)
- {
- context.EmitLdc_I8(_masksE1_TrnUzp [op.Size]); // maskE1
- context.EmitLdc_I8(_masksE0_TrnUzpXtn[op.Size]); // maskE0
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetVector128), typesSve));
-
- context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), GetTypesSflUpk(0)));
- }
-
- context.EmitLdvec(op.Rm); // value
-
- if (op.Size < 3)
- {
- context.EmitLdc_I8(_masksE1_TrnUzp [op.Size]); // maskE1
- context.EmitLdc_I8(_masksE0_TrnUzpXtn[op.Size]); // maskE0
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetVector128), typesSve));
-
- context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), GetTypesSflUpk(0)));
- }
-
- context.EmitCall(typeof(Sse2).GetMethod(nameUpk, GetTypesSflUpk(3)));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), GetTypesSflUpk(op.Size))); // value
-
- if (op.Size < 2)
- {
- context.EmitLdc_I8(_masksE1_Uzp[op.Size]); // maskE1
- context.EmitLdc_I8(_masksE0_Uzp[op.Size]); // maskE0
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetVector128), typesSve));
-
- context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), GetTypesSflUpk(0)));
- }
-
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameUpk, GetTypesSflUpk(3)));
-
- context.EmitStvec(op.Rd);
- }
- }
- else
- {
- int words = op.GetBitsCount() >> 4;
- int pairs = words >> op.Size;
-
- for (int index = 0; index < pairs; index++)
- {
- int idx = index << 1;
-
- EmitVectorExtractZx(context, op.Rn, idx + part, op.Size);
- EmitVectorExtractZx(context, op.Rm, idx + part, op.Size);
-
- EmitVectorInsertTmp(context, pairs + index, op.Size);
- EmitVectorInsertTmp(context, index, op.Size);
- }
-
- context.EmitLdvectmp();
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- }
-
- private static void EmitVectorZip(ILEmitterCtx context, int part)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- if (Optimizations.UseSse2)
- {
- string nameUpk = part == 0
- ? nameof(Sse2.UnpackLow)
- : nameof(Sse2.UnpackHigh);
-
- context.EmitLdvec(op.Rn);
- context.EmitLdvec(op.Rm);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.EmitCall(typeof(Sse2).GetMethod(nameUpk, GetTypesSflUpk(op.Size)));
- }
- else
- {
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), GetTypesSflUpk(op.Size)));
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameUpk, GetTypesSflUpk(3)));
- }
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- int words = op.GetBitsCount() >> 4;
- int pairs = words >> op.Size;
-
- int Base = part != 0 ? pairs : 0;
-
- for (int index = 0; index < pairs; index++)
- {
- int idx = index << 1;
-
- EmitVectorExtractZx(context, op.Rn, Base + index, op.Size);
- EmitVectorExtractZx(context, op.Rm, Base + index, op.Size);
-
- EmitVectorInsertTmp(context, idx + 1, op.Size);
- EmitVectorInsertTmp(context, idx, op.Size);
- }
-
- context.EmitLdvectmp();
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- }
-
- private static Type[] GetTypesSflUpk(int size)
- {
- return new Type[] { VectorIntTypesPerSizeLog2[size], VectorIntTypesPerSizeLog2[size] };
- }
- }
-}
diff --git a/ChocolArm64/Instructions/InstEmitSimdShift.cs b/ChocolArm64/Instructions/InstEmitSimdShift.cs
deleted file mode 100644
index 6865948ae0..0000000000
--- a/ChocolArm64/Instructions/InstEmitSimdShift.cs
+++ /dev/null
@@ -1,1175 +0,0 @@
-// https://github.com/intel/ARM_NEON_2_x86_SSE/blob/master/NEON_2_SSE.h
-
-using ChocolArm64.Decoders;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System;
-using System.Reflection.Emit;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-using static ChocolArm64.Instructions.InstEmitSimdHelper;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
-#region "Masks"
- private static readonly long[] _masks_RshrnShrn = new long[]
- {
- 14L << 56 | 12L << 48 | 10L << 40 | 08L << 32 | 06L << 24 | 04L << 16 | 02L << 8 | 00L << 0,
- 13L << 56 | 12L << 48 | 09L << 40 | 08L << 32 | 05L << 24 | 04L << 16 | 01L << 8 | 00L << 0,
- 11L << 56 | 10L << 48 | 09L << 40 | 08L << 32 | 03L << 24 | 02L << 16 | 01L << 8 | 00L << 0
- };
-#endregion
-
- public static void Rshrn_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSsse3)
- {
- OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
-
- Type[] typesAdd = new Type[] { VectorUIntTypesPerSizeLog2[op.Size + 1], VectorUIntTypesPerSizeLog2[op.Size + 1] };
- Type[] typesSrl = new Type[] { VectorUIntTypesPerSizeLog2[op.Size + 1], typeof(byte) };
- Type[] typesSfl = new Type[] { typeof(Vector128), typeof(Vector128) };
- Type[] typesSav = new Type[] { UIntTypesPerSizeLog2[op.Size + 1] };
- Type[] typesSve = new Type[] { typeof(long), typeof(long) };
-
- string nameMov = op.RegisterSize == RegisterSize.Simd128
- ? nameof(Sse.MoveLowToHigh)
- : nameof(Sse.MoveHighToLow);
-
- int shift = GetImmShr(op);
-
- long roundConst = 1L << (shift - 1);
-
- context.EmitLdvec(op.Rd);
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveLowToHigh)));
-
- context.EmitLdvec(op.Rn);
-
- context.EmitLdc_I8(roundConst);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
-
- context.EmitLdc_I4(shift);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), typesSrl)); // value
-
- context.EmitLdc_I8(_masks_RshrnShrn[op.Size]); // mask
- context.Emit(OpCodes.Dup); // mask
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetVector128), typesSve));
-
- context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), typesSfl));
-
- context.EmitCall(typeof(Sse).GetMethod(nameMov));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitVectorShrImmNarrowOpZx(context, round: true);
- }
- }
-
- public static void Shl_S(ILEmitterCtx context)
- {
- OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
-
- int shift = GetImmShl(op);
-
- EmitScalarUnaryOpZx(context, () =>
- {
- context.EmitLdc_I4(shift);
-
- context.Emit(OpCodes.Shl);
- });
- }
-
- public static void Shl_V(ILEmitterCtx context)
- {
- OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
-
- int shift = GetImmShl(op);
-
- if (Optimizations.UseSse2 && op.Size > 0)
- {
- Type[] typesSll = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], typeof(byte) };
-
- context.EmitLdvec(op.Rn);
-
- context.EmitLdc_I4(shift);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), typesSll));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorUnaryOpZx(context, () =>
- {
- context.EmitLdc_I4(shift);
-
- context.Emit(OpCodes.Shl);
- });
- }
- }
-
- public static void Shll_V(ILEmitterCtx context)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int shift = 8 << op.Size;
-
- if (Optimizations.UseSse41)
- {
- Type[] typesSll = new Type[] { VectorUIntTypesPerSizeLog2[op.Size + 1], typeof(byte) };
- Type[] typesCvt = new Type[] { VectorUIntTypesPerSizeLog2[op.Size] };
-
- string[] namesCvt = new string[] { nameof(Sse41.ConvertToVector128Int16),
- nameof(Sse41.ConvertToVector128Int32),
- nameof(Sse41.ConvertToVector128Int64) };
-
- context.EmitLdvec(op.Rn);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSll));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt));
-
- context.EmitLdc_I4(shift);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), typesSll));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitVectorShImmWidenBinaryZx(context, () => context.Emit(OpCodes.Shl), shift);
- }
- }
-
- public static void Shrn_V(ILEmitterCtx context)
- {
- if (Optimizations.UseSsse3)
- {
- OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
-
- Type[] typesSrl = new Type[] { VectorUIntTypesPerSizeLog2[op.Size + 1], typeof(byte) };
- Type[] typesSfl = new Type[] { typeof(Vector128), typeof(Vector128) };
- Type[] typesSve = new Type[] { typeof(long), typeof(long) };
-
- string nameMov = op.RegisterSize == RegisterSize.Simd128
- ? nameof(Sse.MoveLowToHigh)
- : nameof(Sse.MoveHighToLow);
-
- int shift = GetImmShr(op);
-
- context.EmitLdvec(op.Rd);
- VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
-
- context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveLowToHigh)));
-
- context.EmitLdvec(op.Rn);
-
- context.EmitLdc_I4(shift);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), typesSrl)); // value
-
- context.EmitLdc_I8(_masks_RshrnShrn[op.Size]); // mask
- context.Emit(OpCodes.Dup); // mask
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetVector128), typesSve));
-
- context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), typesSfl));
-
- context.EmitCall(typeof(Sse).GetMethod(nameMov));
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitVectorShrImmNarrowOpZx(context, round: false);
- }
- }
-
- public static void Sli_V(ILEmitterCtx context)
- {
- OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> op.Size;
-
- int shift = GetImmShl(op);
-
- ulong mask = shift != 0 ? ulong.MaxValue >> (64 - shift) : 0;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractZx(context, op.Rn, index, op.Size);
-
- context.EmitLdc_I4(shift);
-
- context.Emit(OpCodes.Shl);
-
- EmitVectorExtractZx(context, op.Rd, index, op.Size);
-
- context.EmitLdc_I8((long)mask);
-
- context.Emit(OpCodes.And);
- context.Emit(OpCodes.Or);
-
- EmitVectorInsert(context, op.Rd, index, op.Size);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void Sqrshl_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> op.Size;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractSx(context, op.Rn, index, op.Size);
- EmitVectorExtractSx(context, op.Rm, index, op.Size);
-
- context.Emit(OpCodes.Ldc_I4_1);
- context.EmitLdc_I4(op.Size);
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.SignedShlRegSatQ));
-
- EmitVectorInsert(context, op.Rd, index, op.Size);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void Sqrshrn_S(ILEmitterCtx context)
- {
- EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarSxSx);
- }
-
- public static void Sqrshrn_V(ILEmitterCtx context)
- {
- EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorSxSx);
- }
-
- public static void Sqrshrun_S(ILEmitterCtx context)
- {
- EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarSxZx);
- }
-
- public static void Sqrshrun_V(ILEmitterCtx context)
- {
- EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorSxZx);
- }
-
- public static void Sqshl_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> op.Size;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractSx(context, op.Rn, index, op.Size);
- EmitVectorExtractSx(context, op.Rm, index, op.Size);
-
- context.Emit(OpCodes.Ldc_I4_0);
- context.EmitLdc_I4(op.Size);
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.SignedShlRegSatQ));
-
- EmitVectorInsert(context, op.Rd, index, op.Size);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void Sqshrn_S(ILEmitterCtx context)
- {
- EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarSxSx);
- }
-
- public static void Sqshrn_V(ILEmitterCtx context)
- {
- EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorSxSx);
- }
-
- public static void Sqshrun_S(ILEmitterCtx context)
- {
- EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarSxZx);
- }
-
- public static void Sqshrun_V(ILEmitterCtx context)
- {
- EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorSxZx);
- }
-
- public static void Srshl_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> op.Size;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractSx(context, op.Rn, index, op.Size);
- EmitVectorExtractSx(context, op.Rm, index, op.Size);
-
- context.Emit(OpCodes.Ldc_I4_1);
- context.EmitLdc_I4(op.Size);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.SignedShlReg));
-
- EmitVectorInsert(context, op.Rd, index, op.Size);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void Srshr_S(ILEmitterCtx context)
- {
- EmitScalarShrImmOpSx(context, ShrImmFlags.Round);
- }
-
- public static void Srshr_V(ILEmitterCtx context)
- {
- OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
-
- if (Optimizations.UseSse2 && op.Size > 0 && op.Size < 3)
- {
- Type[] typesShs = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesAdd = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
-
- int shift = GetImmShr(op);
- int eSize = 8 << op.Size;
-
- context.EmitLdvec(op.Rn);
-
- context.EmitLdc_I4(eSize - shift);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), typesShs));
-
- context.EmitLdc_I4(eSize - 1);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), typesShs));
-
- context.EmitLdvec(op.Rn);
-
- context.EmitLdc_I4(shift);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), typesShs));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorShrImmOpSx(context, ShrImmFlags.Round);
- }
- }
-
- public static void Srsra_S(ILEmitterCtx context)
- {
- EmitScalarShrImmOpSx(context, ShrImmFlags.Round | ShrImmFlags.Accumulate);
- }
-
- public static void Srsra_V(ILEmitterCtx context)
- {
- OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
-
- if (Optimizations.UseSse2 && op.Size > 0 && op.Size < 3)
- {
- Type[] typesShs = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesAdd = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
-
- int shift = GetImmShr(op);
- int eSize = 8 << op.Size;
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
-
- context.EmitLdc_I4(eSize - shift);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), typesShs));
-
- context.EmitLdc_I4(eSize - 1);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), typesShs));
-
- context.EmitLdvec(op.Rn);
-
- context.EmitLdc_I4(shift);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), typesShs));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorShrImmOpSx(context, ShrImmFlags.Round | ShrImmFlags.Accumulate);
- }
- }
-
- public static void Sshl_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> op.Size;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractSx(context, op.Rn, index, op.Size);
- EmitVectorExtractSx(context, op.Rm, index, op.Size);
-
- context.Emit(OpCodes.Ldc_I4_0);
- context.EmitLdc_I4(op.Size);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.SignedShlReg));
-
- EmitVectorInsert(context, op.Rd, index, op.Size);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void Sshll_V(ILEmitterCtx context)
- {
- OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
-
- int shift = GetImmShl(op);
-
- if (Optimizations.UseSse41)
- {
- Type[] typesSll = new Type[] { VectorIntTypesPerSizeLog2[op.Size + 1], typeof(byte) };
- Type[] typesCvt = new Type[] { VectorIntTypesPerSizeLog2[op.Size] };
-
- string[] namesCvt = new string[] { nameof(Sse41.ConvertToVector128Int16),
- nameof(Sse41.ConvertToVector128Int32),
- nameof(Sse41.ConvertToVector128Int64) };
-
- context.EmitLdvec(op.Rn);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSll));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt));
-
- if (shift != 0)
- {
- context.EmitLdc_I4(shift);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), typesSll));
- }
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitVectorShImmWidenBinarySx(context, () => context.Emit(OpCodes.Shl), shift);
- }
- }
-
- public static void Sshr_S(ILEmitterCtx context)
- {
- EmitShrImmOp(context, ShrImmFlags.ScalarSx);
- }
-
- public static void Sshr_V(ILEmitterCtx context)
- {
- OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
-
- if (Optimizations.UseSse2 && op.Size > 0 && op.Size < 3)
- {
- Type[] typesSra = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
-
- context.EmitLdvec(op.Rn);
-
- context.EmitLdc_I4(GetImmShr(op));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), typesSra));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitShrImmOp(context, ShrImmFlags.VectorSx);
- }
- }
-
- public static void Ssra_S(ILEmitterCtx context)
- {
- EmitScalarShrImmOpSx(context, ShrImmFlags.Accumulate);
- }
-
- public static void Ssra_V(ILEmitterCtx context)
- {
- OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
-
- if (Optimizations.UseSse2 && op.Size > 0 && op.Size < 3)
- {
- Type[] typesSra = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesAdd = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
-
- context.EmitLdc_I4(GetImmShr(op));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), typesSra));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorShrImmOpSx(context, ShrImmFlags.Accumulate);
- }
- }
-
- public static void Uqrshl_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> op.Size;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractZx(context, op.Rn, index, op.Size);
- EmitVectorExtractZx(context, op.Rm, index, op.Size);
-
- context.Emit(OpCodes.Ldc_I4_1);
- context.EmitLdc_I4(op.Size);
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.UnsignedShlRegSatQ));
-
- EmitVectorInsert(context, op.Rd, index, op.Size);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void Uqrshrn_S(ILEmitterCtx context)
- {
- EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarZxZx);
- }
-
- public static void Uqrshrn_V(ILEmitterCtx context)
- {
- EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorZxZx);
- }
-
- public static void Uqshl_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> op.Size;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractZx(context, op.Rn, index, op.Size);
- EmitVectorExtractZx(context, op.Rm, index, op.Size);
-
- context.Emit(OpCodes.Ldc_I4_0);
- context.EmitLdc_I4(op.Size);
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.UnsignedShlRegSatQ));
-
- EmitVectorInsert(context, op.Rd, index, op.Size);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void Uqshrn_S(ILEmitterCtx context)
- {
- EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarZxZx);
- }
-
- public static void Uqshrn_V(ILEmitterCtx context)
- {
- EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorZxZx);
- }
-
- public static void Urshl_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> op.Size;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractZx(context, op.Rn, index, op.Size);
- EmitVectorExtractZx(context, op.Rm, index, op.Size);
-
- context.Emit(OpCodes.Ldc_I4_1);
- context.EmitLdc_I4(op.Size);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.UnsignedShlReg));
-
- EmitVectorInsert(context, op.Rd, index, op.Size);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void Urshr_S(ILEmitterCtx context)
- {
- EmitScalarShrImmOpZx(context, ShrImmFlags.Round);
- }
-
- public static void Urshr_V(ILEmitterCtx context)
- {
- OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
-
- if (Optimizations.UseSse2 && op.Size > 0)
- {
- Type[] typesShs = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesAdd = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], VectorUIntTypesPerSizeLog2[op.Size] };
-
- int shift = GetImmShr(op);
- int eSize = 8 << op.Size;
-
- context.EmitLdvec(op.Rn);
-
- context.EmitLdc_I4(eSize - shift);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), typesShs));
-
- context.EmitLdc_I4(eSize - 1);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), typesShs));
-
- context.EmitLdvec(op.Rn);
-
- context.EmitLdc_I4(shift);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), typesShs));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorShrImmOpZx(context, ShrImmFlags.Round);
- }
- }
-
- public static void Ursra_S(ILEmitterCtx context)
- {
- EmitScalarShrImmOpZx(context, ShrImmFlags.Round | ShrImmFlags.Accumulate);
- }
-
- public static void Ursra_V(ILEmitterCtx context)
- {
- OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
-
- if (Optimizations.UseSse2 && op.Size > 0)
- {
- Type[] typesShs = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesAdd = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], VectorUIntTypesPerSizeLog2[op.Size] };
-
- int shift = GetImmShr(op);
- int eSize = 8 << op.Size;
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
-
- context.EmitLdc_I4(eSize - shift);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), typesShs));
-
- context.EmitLdc_I4(eSize - 1);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), typesShs));
-
- context.EmitLdvec(op.Rn);
-
- context.EmitLdc_I4(shift);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), typesShs));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorShrImmOpZx(context, ShrImmFlags.Round | ShrImmFlags.Accumulate);
- }
- }
-
- public static void Ushl_V(ILEmitterCtx context)
- {
- OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> op.Size;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractZx(context, op.Rn, index, op.Size);
- EmitVectorExtractZx(context, op.Rm, index, op.Size);
-
- context.Emit(OpCodes.Ldc_I4_0);
- context.EmitLdc_I4(op.Size);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.UnsignedShlReg));
-
- EmitVectorInsert(context, op.Rd, index, op.Size);
- }
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- public static void Ushll_V(ILEmitterCtx context)
- {
- OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
-
- int shift = GetImmShl(op);
-
- if (Optimizations.UseSse41)
- {
- Type[] typesSll = new Type[] { VectorUIntTypesPerSizeLog2[op.Size + 1], typeof(byte) };
- Type[] typesCvt = new Type[] { VectorUIntTypesPerSizeLog2[op.Size] };
-
- string[] namesCvt = new string[] { nameof(Sse41.ConvertToVector128Int16),
- nameof(Sse41.ConvertToVector128Int32),
- nameof(Sse41.ConvertToVector128Int64) };
-
- context.EmitLdvec(op.Rn);
-
- if (op.RegisterSize == RegisterSize.Simd128)
- {
- context.Emit(OpCodes.Ldc_I4_8);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSll));
- }
-
- context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt));
-
- if (shift != 0)
- {
- context.EmitLdc_I4(shift);
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), typesSll));
- }
-
- context.EmitStvec(op.Rd);
- }
- else
- {
- EmitVectorShImmWidenBinaryZx(context, () => context.Emit(OpCodes.Shl), shift);
- }
- }
-
- public static void Ushr_S(ILEmitterCtx context)
- {
- EmitShrImmOp(context, ShrImmFlags.ScalarZx);
- }
-
- public static void Ushr_V(ILEmitterCtx context)
- {
- OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
-
- if (Optimizations.UseSse2 && op.Size > 0)
- {
- Type[] typesSrl = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], typeof(byte) };
-
- context.EmitLdvec(op.Rn);
-
- context.EmitLdc_I4(GetImmShr(op));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), typesSrl));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitShrImmOp(context, ShrImmFlags.VectorZx);
- }
- }
-
- public static void Usra_S(ILEmitterCtx context)
- {
- EmitScalarShrImmOpZx(context, ShrImmFlags.Accumulate);
- }
-
- public static void Usra_V(ILEmitterCtx context)
- {
- OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
-
- if (Optimizations.UseSse2 && op.Size > 0)
- {
- Type[] typesSrl = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], typeof(byte) };
- Type[] typesAdd = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], VectorUIntTypesPerSizeLog2[op.Size] };
-
- context.EmitLdvec(op.Rd);
- context.EmitLdvec(op.Rn);
-
- context.EmitLdc_I4(GetImmShr(op));
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), typesSrl));
-
- context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
-
- context.EmitStvec(op.Rd);
-
- if (op.RegisterSize == RegisterSize.Simd64)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
- else
- {
- EmitVectorShrImmOpZx(context, ShrImmFlags.Accumulate);
- }
- }
-
- [Flags]
- private enum ShrImmFlags
- {
- Scalar = 1 << 0,
- Signed = 1 << 1,
-
- Round = 1 << 2,
- Accumulate = 1 << 3,
-
- ScalarSx = Scalar | Signed,
- ScalarZx = Scalar,
-
- VectorSx = Signed,
- VectorZx = 0
- }
-
- private static void EmitScalarShrImmOpSx(ILEmitterCtx context, ShrImmFlags flags)
- {
- EmitShrImmOp(context, ShrImmFlags.ScalarSx | flags);
- }
-
- private static void EmitScalarShrImmOpZx(ILEmitterCtx context, ShrImmFlags flags)
- {
- EmitShrImmOp(context, ShrImmFlags.ScalarZx | flags);
- }
-
- private static void EmitVectorShrImmOpSx(ILEmitterCtx context, ShrImmFlags flags)
- {
- EmitShrImmOp(context, ShrImmFlags.VectorSx | flags);
- }
-
- private static void EmitVectorShrImmOpZx(ILEmitterCtx context, ShrImmFlags flags)
- {
- EmitShrImmOp(context, ShrImmFlags.VectorZx | flags);
- }
-
- private static void EmitShrImmOp(ILEmitterCtx context, ShrImmFlags flags)
- {
- OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
-
- bool scalar = (flags & ShrImmFlags.Scalar) != 0;
- bool signed = (flags & ShrImmFlags.Signed) != 0;
- bool round = (flags & ShrImmFlags.Round) != 0;
- bool accumulate = (flags & ShrImmFlags.Accumulate) != 0;
-
- int shift = GetImmShr(op);
-
- long roundConst = 1L << (shift - 1);
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = !scalar ? bytes >> op.Size : 1;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtract(context, op.Rn, index, op.Size, signed);
-
- if (op.Size <= 2)
- {
- if (round)
- {
- context.EmitLdc_I8(roundConst);
-
- context.Emit(OpCodes.Add);
- }
-
- context.EmitLdc_I4(shift);
-
- context.Emit(signed ? OpCodes.Shr : OpCodes.Shr_Un);
- }
- else /* if (op.Size == 3) */
- {
- EmitShrImm64(context, signed, round ? roundConst : 0L, shift);
- }
-
- if (accumulate)
- {
- EmitVectorExtract(context, op.Rd, index, op.Size, signed);
-
- context.Emit(OpCodes.Add);
- }
-
- EmitVectorInsert(context, op.Rd, index, op.Size);
- }
-
- if ((op.RegisterSize == RegisterSize.Simd64) || scalar)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- private static void EmitVectorShrImmNarrowOpZx(ILEmitterCtx context, bool round)
- {
- OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
-
- int shift = GetImmShr(op);
-
- long roundConst = 1L << (shift - 1);
-
- int elems = 8 >> op.Size;
-
- int part = op.RegisterSize == RegisterSize.Simd128 ? elems : 0;
-
- if (part != 0)
- {
- context.EmitLdvec(op.Rd);
- context.EmitStvectmp();
- }
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtractZx(context, op.Rn, index, op.Size + 1);
-
- if (round)
- {
- context.EmitLdc_I8(roundConst);
-
- context.Emit(OpCodes.Add);
- }
-
- context.EmitLdc_I4(shift);
-
- context.Emit(OpCodes.Shr_Un);
-
- EmitVectorInsertTmp(context, part + index, op.Size);
- }
-
- context.EmitLdvectmp();
- context.EmitStvec(op.Rd);
-
- if (part == 0)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- [Flags]
- private enum ShrImmSaturatingNarrowFlags
- {
- Scalar = 1 << 0,
- SignedSrc = 1 << 1,
- SignedDst = 1 << 2,
-
- Round = 1 << 3,
-
- ScalarSxSx = Scalar | SignedSrc | SignedDst,
- ScalarSxZx = Scalar | SignedSrc,
- ScalarZxZx = Scalar,
-
- VectorSxSx = SignedSrc | SignedDst,
- VectorSxZx = SignedSrc,
- VectorZxZx = 0
- }
-
- private static void EmitRoundShrImmSaturatingNarrowOp(ILEmitterCtx context, ShrImmSaturatingNarrowFlags flags)
- {
- EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.Round | flags);
- }
-
- private static void EmitShrImmSaturatingNarrowOp(ILEmitterCtx context, ShrImmSaturatingNarrowFlags flags)
- {
- OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
-
- bool scalar = (flags & ShrImmSaturatingNarrowFlags.Scalar) != 0;
- bool signedSrc = (flags & ShrImmSaturatingNarrowFlags.SignedSrc) != 0;
- bool signedDst = (flags & ShrImmSaturatingNarrowFlags.SignedDst) != 0;
- bool round = (flags & ShrImmSaturatingNarrowFlags.Round) != 0;
-
- int shift = GetImmShr(op);
-
- long roundConst = 1L << (shift - 1);
-
- int elems = !scalar ? 8 >> op.Size : 1;
-
- int part = !scalar && (op.RegisterSize == RegisterSize.Simd128) ? elems : 0;
-
- if (scalar)
- {
- EmitVectorZeroLowerTmp(context);
- }
-
- if (part != 0)
- {
- context.EmitLdvec(op.Rd);
- context.EmitStvectmp();
- }
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtract(context, op.Rn, index, op.Size + 1, signedSrc);
-
- if (op.Size <= 1 || !round)
- {
- if (round)
- {
- context.EmitLdc_I8(roundConst);
-
- context.Emit(OpCodes.Add);
- }
-
- context.EmitLdc_I4(shift);
-
- context.Emit(signedSrc ? OpCodes.Shr : OpCodes.Shr_Un);
- }
- else /* if (op.Size == 2 && round) */
- {
- EmitShrImm64(context, signedSrc, roundConst, shift); // shift <= 32
- }
-
- EmitSatQ(context, op.Size, signedSrc, signedDst);
-
- EmitVectorInsertTmp(context, part + index, op.Size);
- }
-
- context.EmitLdvectmp();
- context.EmitStvec(op.Rd);
-
- if (part == 0)
- {
- EmitVectorZeroUpper(context, op.Rd);
- }
- }
-
- // dst64 = (Int(src64, signed) + roundConst) >> shift;
- private static void EmitShrImm64(ILEmitterCtx context, bool signed, long roundConst, int shift)
- {
- context.EmitLdc_I8(roundConst);
- context.EmitLdc_I4(shift);
-
- SoftFallback.EmitCall(context, signed
- ? nameof(SoftFallback.SignedShrImm64)
- : nameof(SoftFallback.UnsignedShrImm64));
- }
-
- private static void EmitVectorShImmWidenBinarySx(ILEmitterCtx context, Action emit, int imm)
- {
- EmitVectorShImmWidenBinaryOp(context, emit, imm, true);
- }
-
- private static void EmitVectorShImmWidenBinaryZx(ILEmitterCtx context, Action emit, int imm)
- {
- EmitVectorShImmWidenBinaryOp(context, emit, imm, false);
- }
-
- private static void EmitVectorShImmWidenBinaryOp(ILEmitterCtx context, Action emit, int imm, bool signed)
- {
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int elems = 8 >> op.Size;
-
- int part = op.RegisterSize == RegisterSize.Simd128 ? elems : 0;
-
- for (int index = 0; index < elems; index++)
- {
- EmitVectorExtract(context, op.Rn, part + index, op.Size, signed);
-
- context.EmitLdc_I4(imm);
-
- emit();
-
- EmitVectorInsertTmp(context, index, op.Size + 1);
- }
-
- context.EmitLdvectmp();
- context.EmitStvec(op.Rd);
- }
- }
-}
diff --git a/ChocolArm64/Instructions/InstEmitSystem.cs b/ChocolArm64/Instructions/InstEmitSystem.cs
deleted file mode 100644
index ac264de92e..0000000000
--- a/ChocolArm64/Instructions/InstEmitSystem.cs
+++ /dev/null
@@ -1,137 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System;
-using System.Reflection;
-using System.Reflection.Emit;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
- public static void Hint(ILEmitterCtx context)
- {
- // Execute as no-op.
- }
-
- public static void Isb(ILEmitterCtx context)
- {
- // Execute as no-op.
- }
-
- public static void Mrs(ILEmitterCtx context)
- {
- OpCodeSystem64 op = (OpCodeSystem64)context.CurrOp;
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
-
- string propName;
-
- switch (GetPackedId(op))
- {
- case 0b11_011_0000_0000_001: propName = nameof(CpuThreadState.CtrEl0); break;
- case 0b11_011_0000_0000_111: propName = nameof(CpuThreadState.DczidEl0); break;
- case 0b11_011_0100_0100_000: propName = nameof(CpuThreadState.CFpcr); break;
- case 0b11_011_0100_0100_001: propName = nameof(CpuThreadState.CFpsr); break;
- case 0b11_011_1101_0000_010: propName = nameof(CpuThreadState.TpidrEl0); break;
- case 0b11_011_1101_0000_011: propName = nameof(CpuThreadState.Tpidr); break;
- case 0b11_011_1110_0000_000: propName = nameof(CpuThreadState.CntfrqEl0); break;
- case 0b11_011_1110_0000_001: propName = nameof(CpuThreadState.CntpctEl0); break;
-
- default: throw new NotImplementedException($"Unknown MRS at {op.Position:x16}");
- }
-
- context.EmitCallPropGet(typeof(CpuThreadState), propName);
-
- PropertyInfo propInfo = typeof(CpuThreadState).GetProperty(propName);
-
- if (propInfo.PropertyType != typeof(long) &&
- propInfo.PropertyType != typeof(ulong))
- {
- context.Emit(OpCodes.Conv_U8);
- }
-
- context.EmitStintzr(op.Rt);
- }
-
- public static void Msr(ILEmitterCtx context)
- {
- OpCodeSystem64 op = (OpCodeSystem64)context.CurrOp;
-
- context.EmitLdarg(TranslatedSub.StateArgIdx);
- context.EmitLdintzr(op.Rt);
-
- string propName;
-
- switch (GetPackedId(op))
- {
- case 0b11_011_0100_0100_000: propName = nameof(CpuThreadState.CFpcr); break;
- case 0b11_011_0100_0100_001: propName = nameof(CpuThreadState.CFpsr); break;
- case 0b11_011_1101_0000_010: propName = nameof(CpuThreadState.TpidrEl0); break;
-
- default: throw new NotImplementedException($"Unknown MSR at {op.Position:x16}");
- }
-
- PropertyInfo propInfo = typeof(CpuThreadState).GetProperty(propName);
-
- if (propInfo.PropertyType != typeof(long) &&
- propInfo.PropertyType != typeof(ulong))
- {
- context.Emit(OpCodes.Conv_U4);
- }
-
- context.EmitCallPropSet(typeof(CpuThreadState), propName);
- }
-
- public static void Nop(ILEmitterCtx context)
- {
- // Do nothing.
- }
-
- public static void Sys(ILEmitterCtx context)
- {
- // This instruction is used to do some operations on the CPU like cache invalidation,
- // address translation and the like.
- // We treat it as no-op here since we don't have any cache being emulated anyway.
- OpCodeSystem64 op = (OpCodeSystem64)context.CurrOp;
-
- switch (GetPackedId(op))
- {
- case 0b11_011_0111_0100_001:
- {
- // DC ZVA
- for (int offs = 0; offs < (4 << CpuThreadState.DczSizeLog2); offs += 8)
- {
- context.EmitLdintzr(op.Rt);
- context.EmitLdc_I(offs);
-
- context.Emit(OpCodes.Add);
-
- context.EmitLdc_I8(0);
-
- InstEmitMemoryHelper.EmitWriteCall(context, 3);
- }
-
- break;
- }
-
- // No-op
- case 0b11_011_0111_1110_001: //DC CIVAC
- break;
- }
- }
-
- private static int GetPackedId(OpCodeSystem64 op)
- {
- int id;
-
- id = op.Op2 << 0;
- id |= op.CRm << 3;
- id |= op.CRn << 7;
- id |= op.Op1 << 11;
- id |= op.Op0 << 14;
-
- return id;
- }
- }
-}
diff --git a/ChocolArm64/Instructions/InstEmitter.cs b/ChocolArm64/Instructions/InstEmitter.cs
deleted file mode 100644
index db6e8604f8..0000000000
--- a/ChocolArm64/Instructions/InstEmitter.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-using ChocolArm64.Translation;
-
-namespace ChocolArm64.Instructions
-{
- delegate void InstEmitter(ILEmitterCtx context);
-}
\ No newline at end of file
diff --git a/ChocolArm64/Instructions/SoftFallback.cs b/ChocolArm64/Instructions/SoftFallback.cs
deleted file mode 100644
index 1663889457..0000000000
--- a/ChocolArm64/Instructions/SoftFallback.cs
+++ /dev/null
@@ -1,1194 +0,0 @@
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace ChocolArm64.Instructions
-{
- using static VectorHelper;
-
- static class SoftFallback
- {
- public static void EmitCall(ILEmitterCtx context, string mthdName)
- {
- context.EmitCall(typeof(SoftFallback), mthdName);
- }
-
-#region "ShlReg"
- public static long SignedShlReg(long value, long shift, bool round, int size)
- {
- int eSize = 8 << size;
-
- int shiftLsB = (sbyte)shift;
-
- if (shiftLsB < 0)
- {
- return SignedShrReg(value, -shiftLsB, round, eSize);
- }
- else if (shiftLsB > 0)
- {
- if (shiftLsB >= eSize)
- {
- return 0L;
- }
-
- return value << shiftLsB;
- }
- else /* if (shiftLsB == 0) */
- {
- return value;
- }
- }
-
- public static ulong UnsignedShlReg(ulong value, ulong shift, bool round, int size)
- {
- int eSize = 8 << size;
-
- int shiftLsB = (sbyte)shift;
-
- if (shiftLsB < 0)
- {
- return UnsignedShrReg(value, -shiftLsB, round, eSize);
- }
- else if (shiftLsB > 0)
- {
- if (shiftLsB >= eSize)
- {
- return 0UL;
- }
-
- return value << shiftLsB;
- }
- else /* if (shiftLsB == 0) */
- {
- return value;
- }
- }
-
- public static long SignedShlRegSatQ(long value, long shift, bool round, int size, CpuThreadState state)
- {
- int eSize = 8 << size;
-
- int shiftLsB = (sbyte)shift;
-
- if (shiftLsB < 0)
- {
- return SignedShrReg(value, -shiftLsB, round, eSize);
- }
- else if (shiftLsB > 0)
- {
- if (shiftLsB >= eSize)
- {
- return SignedSignSatQ(value, eSize, state);
- }
-
- if (eSize == 64)
- {
- long shl = value << shiftLsB;
- long shr = shl >> shiftLsB;
-
- if (shr != value)
- {
- return SignedSignSatQ(value, eSize, state);
- }
- else /* if (shr == value) */
- {
- return shl;
- }
- }
- else /* if (eSize != 64) */
- {
- return SignedSrcSignedDstSatQ(value << shiftLsB, size, state);
- }
- }
- else /* if (shiftLsB == 0) */
- {
- return value;
- }
- }
-
- public static ulong UnsignedShlRegSatQ(ulong value, ulong shift, bool round, int size, CpuThreadState state)
- {
- int eSize = 8 << size;
-
- int shiftLsB = (sbyte)shift;
-
- if (shiftLsB < 0)
- {
- return UnsignedShrReg(value, -shiftLsB, round, eSize);
- }
- else if (shiftLsB > 0)
- {
- if (shiftLsB >= eSize)
- {
- return UnsignedSignSatQ(value, eSize, state);
- }
-
- if (eSize == 64)
- {
- ulong shl = value << shiftLsB;
- ulong shr = shl >> shiftLsB;
-
- if (shr != value)
- {
- return UnsignedSignSatQ(value, eSize, state);
- }
- else /* if (shr == value) */
- {
- return shl;
- }
- }
- else /* if (eSize != 64) */
- {
- return UnsignedSrcUnsignedDstSatQ(value << shiftLsB, size, state);
- }
- }
- else /* if (shiftLsB == 0) */
- {
- return value;
- }
- }
-
- private static long SignedShrReg(long value, int shift, bool round, int eSize) // shift := [1, 128]; eSize := {8, 16, 32, 64}.
- {
- if (round)
- {
- if (shift >= eSize)
- {
- return 0L;
- }
-
- long roundConst = 1L << (shift - 1);
-
- long add = value + roundConst;
-
- if (eSize == 64)
- {
- if ((~value & (value ^ add)) < 0L)
- {
- return (long)((ulong)add >> shift);
- }
- else
- {
- return add >> shift;
- }
- }
- else /* if (eSize != 64) */
- {
- return add >> shift;
- }
- }
- else /* if (!round) */
- {
- if (shift >= eSize)
- {
- if (value < 0L)
- {
- return -1L;
- }
- else /* if (value >= 0L) */
- {
- return 0L;
- }
- }
-
- return value >> shift;
- }
- }
-
- private static ulong UnsignedShrReg(ulong value, int shift, bool round, int eSize) // shift := [1, 128]; eSize := {8, 16, 32, 64}.
- {
- if (round)
- {
- if (shift > 64)
- {
- return 0UL;
- }
-
- ulong roundConst = 1UL << (shift - 1);
-
- ulong add = value + roundConst;
-
- if (eSize == 64)
- {
- if ((add < value) && (add < roundConst))
- {
- if (shift == 64)
- {
- return 1UL;
- }
-
- return (add >> shift) | (0x8000000000000000UL >> (shift - 1));
- }
- else
- {
- if (shift == 64)
- {
- return 0UL;
- }
-
- return add >> shift;
- }
- }
- else /* if (eSize != 64) */
- {
- if (shift == 64)
- {
- return 0UL;
- }
-
- return add >> shift;
- }
- }
- else /* if (!round) */
- {
- if (shift >= eSize)
- {
- return 0UL;
- }
-
- return value >> shift;
- }
- }
-
- private static long SignedSignSatQ(long op, int eSize, CpuThreadState state) // eSize := {8, 16, 32, 64}.
- {
- long tMaxValue = (1L << (eSize - 1)) - 1L;
- long tMinValue = -(1L << (eSize - 1));
-
- if (op > 0L)
- {
- state.SetFpsrFlag(Fpsr.Qc);
-
- return tMaxValue;
- }
- else if (op < 0L)
- {
- state.SetFpsrFlag(Fpsr.Qc);
-
- return tMinValue;
- }
- else
- {
- return 0L;
- }
- }
-
- private static ulong UnsignedSignSatQ(ulong op, int eSize, CpuThreadState state) // eSize := {8, 16, 32, 64}.
- {
- ulong tMaxValue = ulong.MaxValue >> (64 - eSize);
-
- if (op > 0UL)
- {
- state.SetFpsrFlag(Fpsr.Qc);
-
- return tMaxValue;
- }
- else
- {
- return 0UL;
- }
- }
-#endregion
-
-#region "ShrImm64"
- public static long SignedShrImm64(long value, long roundConst, int shift)
- {
- if (roundConst == 0L)
- {
- if (shift <= 63)
- {
- return value >> shift;
- }
- else /* if (shift == 64) */
- {
- if (value < 0L)
- {
- return -1L;
- }
- else /* if (value >= 0L) */
- {
- return 0L;
- }
- }
- }
- else /* if (roundConst == 1L << (shift - 1)) */
- {
- if (shift <= 63)
- {
- long add = value + roundConst;
-
- if ((~value & (value ^ add)) < 0L)
- {
- return (long)((ulong)add >> shift);
- }
- else
- {
- return add >> shift;
- }
- }
- else /* if (shift == 64) */
- {
- return 0L;
- }
- }
- }
-
- public static ulong UnsignedShrImm64(ulong value, long roundConst, int shift)
- {
- if (roundConst == 0L)
- {
- if (shift <= 63)
- {
- return value >> shift;
- }
- else /* if (shift == 64) */
- {
- return 0UL;
- }
- }
- else /* if (roundConst == 1L << (shift - 1)) */
- {
- ulong add = value + (ulong)roundConst;
-
- if ((add < value) && (add < (ulong)roundConst))
- {
- if (shift <= 63)
- {
- return (add >> shift) | (0x8000000000000000UL >> (shift - 1));
- }
- else /* if (shift == 64) */
- {
- return 1UL;
- }
- }
- else
- {
- if (shift <= 63)
- {
- return add >> shift;
- }
- else /* if (shift == 64) */
- {
- return 0UL;
- }
- }
- }
- }
-#endregion
-
-#region "Saturating"
- public static long SignedSrcSignedDstSatQ(long op, int size, CpuThreadState state)
- {
- int eSize = 8 << size;
-
- long tMaxValue = (1L << (eSize - 1)) - 1L;
- long tMinValue = -(1L << (eSize - 1));
-
- if (op > tMaxValue)
- {
- state.SetFpsrFlag(Fpsr.Qc);
-
- return tMaxValue;
- }
- else if (op < tMinValue)
- {
- state.SetFpsrFlag(Fpsr.Qc);
-
- return tMinValue;
- }
- else
- {
- return op;
- }
- }
-
- public static ulong SignedSrcUnsignedDstSatQ(long op, int size, CpuThreadState state)
- {
- int eSize = 8 << size;
-
- ulong tMaxValue = (1UL << eSize) - 1UL;
- ulong tMinValue = 0UL;
-
- if (op > (long)tMaxValue)
- {
- state.SetFpsrFlag(Fpsr.Qc);
-
- return tMaxValue;
- }
- else if (op < (long)tMinValue)
- {
- state.SetFpsrFlag(Fpsr.Qc);
-
- return tMinValue;
- }
- else
- {
- return (ulong)op;
- }
- }
-
- public static long UnsignedSrcSignedDstSatQ(ulong op, int size, CpuThreadState state)
- {
- int eSize = 8 << size;
-
- long tMaxValue = (1L << (eSize - 1)) - 1L;
-
- if (op > (ulong)tMaxValue)
- {
- state.SetFpsrFlag(Fpsr.Qc);
-
- return tMaxValue;
- }
- else
- {
- return (long)op;
- }
- }
-
- public static ulong UnsignedSrcUnsignedDstSatQ(ulong op, int size, CpuThreadState state)
- {
- int eSize = 8 << size;
-
- ulong tMaxValue = (1UL << eSize) - 1UL;
-
- if (op > tMaxValue)
- {
- state.SetFpsrFlag(Fpsr.Qc);
-
- return tMaxValue;
- }
- else
- {
- return op;
- }
- }
-
- public static long UnarySignedSatQAbsOrNeg(long op, CpuThreadState state)
- {
- if (op == long.MinValue)
- {
- state.SetFpsrFlag(Fpsr.Qc);
-
- return long.MaxValue;
- }
- else
- {
- return op;
- }
- }
-
- public static long BinarySignedSatQAdd(long op1, long op2, CpuThreadState state)
- {
- long add = op1 + op2;
-
- if ((~(op1 ^ op2) & (op1 ^ add)) < 0L)
- {
- state.SetFpsrFlag(Fpsr.Qc);
-
- if (op1 < 0L)
- {
- return long.MinValue;
- }
- else
- {
- return long.MaxValue;
- }
- }
- else
- {
- return add;
- }
- }
-
- public static ulong BinaryUnsignedSatQAdd(ulong op1, ulong op2, CpuThreadState state)
- {
- ulong add = op1 + op2;
-
- if ((add < op1) && (add < op2))
- {
- state.SetFpsrFlag(Fpsr.Qc);
-
- return ulong.MaxValue;
- }
- else
- {
- return add;
- }
- }
-
- public static long BinarySignedSatQSub(long op1, long op2, CpuThreadState state)
- {
- long sub = op1 - op2;
-
- if (((op1 ^ op2) & (op1 ^ sub)) < 0L)
- {
- state.SetFpsrFlag(Fpsr.Qc);
-
- if (op1 < 0L)
- {
- return long.MinValue;
- }
- else
- {
- return long.MaxValue;
- }
- }
- else
- {
- return sub;
- }
- }
-
- public static ulong BinaryUnsignedSatQSub(ulong op1, ulong op2, CpuThreadState state)
- {
- ulong sub = op1 - op2;
-
- if (op1 < op2)
- {
- state.SetFpsrFlag(Fpsr.Qc);
-
- return ulong.MinValue;
- }
- else
- {
- return sub;
- }
- }
-
- public static long BinarySignedSatQAcc(ulong op1, long op2, CpuThreadState state)
- {
- if (op1 <= (ulong)long.MaxValue)
- {
- // op1 from ulong.MinValue to (ulong)long.MaxValue
- // op2 from long.MinValue to long.MaxValue
-
- long add = (long)op1 + op2;
-
- if ((~op2 & add) < 0L)
- {
- state.SetFpsrFlag(Fpsr.Qc);
-
- return long.MaxValue;
- }
- else
- {
- return add;
- }
- }
- else if (op2 >= 0L)
- {
- // op1 from (ulong)long.MaxValue + 1UL to ulong.MaxValue
- // op2 from (long)ulong.MinValue to long.MaxValue
-
- state.SetFpsrFlag(Fpsr.Qc);
-
- return long.MaxValue;
- }
- else
- {
- // op1 from (ulong)long.MaxValue + 1UL to ulong.MaxValue
- // op2 from long.MinValue to (long)ulong.MinValue - 1L
-
- ulong add = op1 + (ulong)op2;
-
- if (add > (ulong)long.MaxValue)
- {
- state.SetFpsrFlag(Fpsr.Qc);
-
- return long.MaxValue;
- }
- else
- {
- return (long)add;
- }
- }
- }
-
- public static ulong BinaryUnsignedSatQAcc(long op1, ulong op2, CpuThreadState state)
- {
- if (op1 >= 0L)
- {
- // op1 from (long)ulong.MinValue to long.MaxValue
- // op2 from ulong.MinValue to ulong.MaxValue
-
- ulong add = (ulong)op1 + op2;
-
- if ((add < (ulong)op1) && (add < op2))
- {
- state.SetFpsrFlag(Fpsr.Qc);
-
- return ulong.MaxValue;
- }
- else
- {
- return add;
- }
- }
- else if (op2 > (ulong)long.MaxValue)
- {
- // op1 from long.MinValue to (long)ulong.MinValue - 1L
- // op2 from (ulong)long.MaxValue + 1UL to ulong.MaxValue
-
- return (ulong)op1 + op2;
- }
- else
- {
- // op1 from long.MinValue to (long)ulong.MinValue - 1L
- // op2 from ulong.MinValue to (ulong)long.MaxValue
-
- long add = op1 + (long)op2;
-
- if (add < (long)ulong.MinValue)
- {
- state.SetFpsrFlag(Fpsr.Qc);
-
- return ulong.MinValue;
- }
- else
- {
- return (ulong)add;
- }
- }
- }
-#endregion
-
-#region "Count"
- public static ulong CountLeadingSigns(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
- {
- value ^= value >> 1;
-
- int highBit = size - 2;
-
- for (int bit = highBit; bit >= 0; bit--)
- {
- if (((int)(value >> bit) & 0b1) != 0)
- {
- return (ulong)(highBit - bit);
- }
- }
-
- return (ulong)(size - 1);
- }
-
- private static readonly byte[] ClzNibbleTbl = { 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
-
- public static ulong CountLeadingZeros(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
- {
- if (value == 0ul)
- {
- return (ulong)size;
- }
-
- int nibbleIdx = size;
- int preCount, count = 0;
-
- do
- {
- nibbleIdx -= 4;
- preCount = ClzNibbleTbl[(int)(value >> nibbleIdx) & 0b1111];
- count += preCount;
- }
- while (preCount == 4);
-
- return (ulong)count;
- }
-
- public static ulong CountSetBits8(ulong value) // "size" is 8 (SIMD&FP Inst.).
- {
- value = ((value >> 1) & 0x55ul) + (value & 0x55ul);
- value = ((value >> 2) & 0x33ul) + (value & 0x33ul);
-
- return (value >> 4) + (value & 0x0ful);
- }
-#endregion
-
-#region "Crc32"
- private const uint Crc32RevPoly = 0xedb88320;
- private const uint Crc32CRevPoly = 0x82f63b78;
-
- public static uint Crc32B(uint crc, byte val) => Crc32 (crc, Crc32RevPoly, val);
- public static uint Crc32H(uint crc, ushort val) => Crc32H(crc, Crc32RevPoly, val);
- public static uint Crc32W(uint crc, uint val) => Crc32W(crc, Crc32RevPoly, val);
- public static uint Crc32X(uint crc, ulong val) => Crc32X(crc, Crc32RevPoly, val);
-
- public static uint Crc32Cb(uint crc, byte val) => Crc32 (crc, Crc32CRevPoly, val);
- public static uint Crc32Ch(uint crc, ushort val) => Crc32H(crc, Crc32CRevPoly, val);
- public static uint Crc32Cw(uint crc, uint val) => Crc32W(crc, Crc32CRevPoly, val);
- public static uint Crc32Cx(uint crc, ulong val) => Crc32X(crc, Crc32CRevPoly, val);
-
- private static uint Crc32H(uint crc, uint poly, ushort val)
- {
- crc = Crc32(crc, poly, (byte)(val >> 0));
- crc = Crc32(crc, poly, (byte)(val >> 8));
-
- return crc;
- }
-
- private static uint Crc32W(uint crc, uint poly, uint val)
- {
- crc = Crc32(crc, poly, (byte)(val >> 0 ));
- crc = Crc32(crc, poly, (byte)(val >> 8 ));
- crc = Crc32(crc, poly, (byte)(val >> 16));
- crc = Crc32(crc, poly, (byte)(val >> 24));
-
- return crc;
- }
-
- private static uint Crc32X(uint crc, uint poly, ulong val)
- {
- crc = Crc32(crc, poly, (byte)(val >> 0 ));
- crc = Crc32(crc, poly, (byte)(val >> 8 ));
- crc = Crc32(crc, poly, (byte)(val >> 16));
- crc = Crc32(crc, poly, (byte)(val >> 24));
- crc = Crc32(crc, poly, (byte)(val >> 32));
- crc = Crc32(crc, poly, (byte)(val >> 40));
- crc = Crc32(crc, poly, (byte)(val >> 48));
- crc = Crc32(crc, poly, (byte)(val >> 56));
-
- return crc;
- }
-
- private static uint Crc32(uint crc, uint poly, byte val)
- {
- crc ^= val;
-
- for (int bit = 7; bit >= 0; bit--)
- {
- uint mask = (uint)(-(int)(crc & 1));
-
- crc = (crc >> 1) ^ (poly & mask);
- }
-
- return crc;
- }
-#endregion
-
-#region "Aes"
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector128 Decrypt(Vector128 value, Vector128 roundKey)
- {
- if (!Sse.IsSupported)
- {
- throw new PlatformNotSupportedException();
- }
-
- return CryptoHelper.AesInvSubBytes(CryptoHelper.AesInvShiftRows(Sse.Xor(value, roundKey)));
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector128 Encrypt(Vector128 value, Vector128 roundKey)
- {
- if (!Sse.IsSupported)
- {
- throw new PlatformNotSupportedException();
- }
-
- return CryptoHelper.AesSubBytes(CryptoHelper.AesShiftRows(Sse.Xor(value, roundKey)));
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector128 InverseMixColumns(Vector128 value)
- {
- return CryptoHelper.AesInvMixColumns(value);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector128 MixColumns(Vector128 value)
- {
- return CryptoHelper.AesMixColumns(value);
- }
-#endregion
-
-#region "Sha1"
- public static Vector128 HashChoose(Vector128 hash_abcd, uint hash_e, Vector128 wk)
- {
- for (int e = 0; e <= 3; e++)
- {
- uint t = ShaChoose((uint)VectorExtractIntZx(hash_abcd, (byte)1, 2),
- (uint)VectorExtractIntZx(hash_abcd, (byte)2, 2),
- (uint)VectorExtractIntZx(hash_abcd, (byte)3, 2));
-
- hash_e += Rol((uint)VectorExtractIntZx(hash_abcd, (byte)0, 2), 5) + t;
- hash_e += (uint)VectorExtractIntZx(wk, (byte)e, 2);
-
- t = Rol((uint)VectorExtractIntZx(hash_abcd, (byte)1, 2), 30);
- hash_abcd = VectorInsertInt((ulong)t, hash_abcd, (byte)1, 2);
-
- Rol32_160(ref hash_e, ref hash_abcd);
- }
-
- return hash_abcd;
- }
-
- public static uint FixedRotate(uint hash_e)
- {
- return hash_e.Rol(30);
- }
-
- public static Vector128 HashMajority(Vector128 hash_abcd, uint hash_e, Vector128 wk)
- {
- for (int e = 0; e <= 3; e++)
- {
- uint t = ShaMajority((uint)VectorExtractIntZx(hash_abcd, (byte)1, 2),
- (uint)VectorExtractIntZx(hash_abcd, (byte)2, 2),
- (uint)VectorExtractIntZx(hash_abcd, (byte)3, 2));
-
- hash_e += Rol((uint)VectorExtractIntZx(hash_abcd, (byte)0, 2), 5) + t;
- hash_e += (uint)VectorExtractIntZx(wk, (byte)e, 2);
-
- t = Rol((uint)VectorExtractIntZx(hash_abcd, (byte)1, 2), 30);
- hash_abcd = VectorInsertInt((ulong)t, hash_abcd, (byte)1, 2);
-
- Rol32_160(ref hash_e, ref hash_abcd);
- }
-
- return hash_abcd;
- }
-
- public static Vector128