aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64
diff options
context:
space:
mode:
authorLDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com>2019-10-31 19:09:03 +0100
committerAc_K <Acoustik666@gmail.com>2019-10-31 19:09:03 +0100
commiteee639d6ba544fa5dd9352426d55e91bc54e157d (patch)
tree1df440ca57d8c1725e84f403fbeecddb8e508a3a /ChocolArm64
parent35443bac5a16ced668d84e0a22c21ca9076b3924 (diff)
.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
Diffstat (limited to 'ChocolArm64')
-rw-r--r--ChocolArm64/ChocolArm64.csproj39
-rw-r--r--ChocolArm64/Decoders/BitUtils.cs59
-rw-r--r--ChocolArm64/Decoders/Block.cs99
-rw-r--r--ChocolArm64/Decoders/Condition.cs32
-rw-r--r--ChocolArm64/Decoders/DataOp.cs10
-rw-r--r--ChocolArm64/Decoders/Decoder.cs379
-rw-r--r--ChocolArm64/Decoders/DecoderHelper.cs112
-rw-r--r--ChocolArm64/Decoders/IOpCode32.cs9
-rw-r--r--ChocolArm64/Decoders/IOpCode32Alu.cs10
-rw-r--r--ChocolArm64/Decoders/IOpCode32BImm.cs4
-rw-r--r--ChocolArm64/Decoders/IOpCode32BReg.cs7
-rw-r--r--ChocolArm64/Decoders/IOpCode32Mem.cs12
-rw-r--r--ChocolArm64/Decoders/IOpCode32MemMult.cs13
-rw-r--r--ChocolArm64/Decoders/IOpCode64.cs13
-rw-r--r--ChocolArm64/Decoders/IOpCodeAlu64.cs10
-rw-r--r--ChocolArm64/Decoders/IOpCodeAluImm64.cs7
-rw-r--r--ChocolArm64/Decoders/IOpCodeAluRs64.cs10
-rw-r--r--ChocolArm64/Decoders/IOpCodeAluRx64.cs10
-rw-r--r--ChocolArm64/Decoders/IOpCodeBImm.cs7
-rw-r--r--ChocolArm64/Decoders/IOpCodeCond64.cs7
-rw-r--r--ChocolArm64/Decoders/IOpCodeLit64.cs11
-rw-r--r--ChocolArm64/Decoders/IOpCodeSimd64.cs7
-rw-r--r--ChocolArm64/Decoders/IntType.cs14
-rw-r--r--ChocolArm64/Decoders/OpCode32.cs24
-rw-r--r--ChocolArm64/Decoders/OpCode32Alu.cs20
-rw-r--r--ChocolArm64/Decoders/OpCode32AluImm.cs21
-rw-r--r--ChocolArm64/Decoders/OpCode32AluRsImm.cs20
-rw-r--r--ChocolArm64/Decoders/OpCode32BImm.cs29
-rw-r--r--ChocolArm64/Decoders/OpCode32BReg.cs14
-rw-r--r--ChocolArm64/Decoders/OpCode32Mem.cs37
-rw-r--r--ChocolArm64/Decoders/OpCode32MemImm.cs12
-rw-r--r--ChocolArm64/Decoders/OpCode32MemImm8.cs15
-rw-r--r--ChocolArm64/Decoders/OpCode32MemMult.cs57
-rw-r--r--ChocolArm64/Decoders/OpCode64.cs40
-rw-r--r--ChocolArm64/Decoders/OpCodeAdr64.cs18
-rw-r--r--ChocolArm64/Decoders/OpCodeAlu64.cs23
-rw-r--r--ChocolArm64/Decoders/OpCodeAluImm64.cs39
-rw-r--r--ChocolArm64/Decoders/OpCodeAluRs64.cs29
-rw-r--r--ChocolArm64/Decoders/OpCodeAluRx64.cs19
-rw-r--r--ChocolArm64/Decoders/OpCodeBImm64.cs11
-rw-r--r--ChocolArm64/Decoders/OpCodeBImmAl64.cs12
-rw-r--r--ChocolArm64/Decoders/OpCodeBImmCmp64.cs20
-rw-r--r--ChocolArm64/Decoders/OpCodeBImmCond64.cs25
-rw-r--r--ChocolArm64/Decoders/OpCodeBImmTest64.cs20
-rw-r--r--ChocolArm64/Decoders/OpCodeBReg64.cs24
-rw-r--r--ChocolArm64/Decoders/OpCodeBfm64.cs29
-rw-r--r--ChocolArm64/Decoders/OpCodeCcmp64.cs31
-rw-r--r--ChocolArm64/Decoders/OpCodeCcmpImm64.cs11
-rw-r--r--ChocolArm64/Decoders/OpCodeCcmpReg64.cs15
-rw-r--r--ChocolArm64/Decoders/OpCodeCsel64.cs17
-rw-r--r--ChocolArm64/Decoders/OpCodeException64.cs14
-rw-r--r--ChocolArm64/Decoders/OpCodeMem64.cs19
-rw-r--r--ChocolArm64/Decoders/OpCodeMemEx64.cs16
-rw-r--r--ChocolArm64/Decoders/OpCodeMemImm64.cs53
-rw-r--r--ChocolArm64/Decoders/OpCodeMemLit64.cs28
-rw-r--r--ChocolArm64/Decoders/OpCodeMemPair64.cs25
-rw-r--r--ChocolArm64/Decoders/OpCodeMemReg64.cs20
-rw-r--r--ChocolArm64/Decoders/OpCodeMov64.cs35
-rw-r--r--ChocolArm64/Decoders/OpCodeMul64.cs16
-rw-r--r--ChocolArm64/Decoders/OpCodeSimd64.cs25
-rw-r--r--ChocolArm64/Decoders/OpCodeSimdCvt64.cs21
-rw-r--r--ChocolArm64/Decoders/OpCodeSimdExt64.cs14
-rw-r--r--ChocolArm64/Decoders/OpCodeSimdFcond64.cs17
-rw-r--r--ChocolArm64/Decoders/OpCodeSimdFmov64.cs33
-rw-r--r--ChocolArm64/Decoders/OpCodeSimdImm64.cs100
-rw-r--r--ChocolArm64/Decoders/OpCodeSimdIns64.cs36
-rw-r--r--ChocolArm64/Decoders/OpCodeSimdMemImm64.cs19
-rw-r--r--ChocolArm64/Decoders/OpCodeSimdMemLit64.cs31
-rw-r--r--ChocolArm64/Decoders/OpCodeSimdMemMs64.cs48
-rw-r--r--ChocolArm64/Decoders/OpCodeSimdMemPair64.cs16
-rw-r--r--ChocolArm64/Decoders/OpCodeSimdMemReg64.cs14
-rw-r--r--ChocolArm64/Decoders/OpCodeSimdMemSs64.cs97
-rw-r--r--ChocolArm64/Decoders/OpCodeSimdReg64.cs18
-rw-r--r--ChocolArm64/Decoders/OpCodeSimdRegElem64.cs31
-rw-r--r--ChocolArm64/Decoders/OpCodeSimdRegElemF64.cs33
-rw-r--r--ChocolArm64/Decoders/OpCodeSimdShImm64.cs16
-rw-r--r--ChocolArm64/Decoders/OpCodeSimdTbl64.cs12
-rw-r--r--ChocolArm64/Decoders/OpCodeSystem64.cs24
-rw-r--r--ChocolArm64/Decoders/OpCodeT16.cs14
-rw-r--r--ChocolArm64/Decoders/OpCodeT16AluImm8.cs22
-rw-r--r--ChocolArm64/Decoders/OpCodeT16BReg.cs14
-rw-r--r--ChocolArm64/Decoders/ShiftType.cs10
-rw-r--r--ChocolArm64/Events/CpuTraceEventArgs.cs14
-rw-r--r--ChocolArm64/Events/InstExceptionEventArgs.cs16
-rw-r--r--ChocolArm64/Events/InstUndefinedEventArgs.cs16
-rw-r--r--ChocolArm64/Instructions/CryptoHelper.cs331
-rw-r--r--ChocolArm64/Instructions/Inst.cs18
-rw-r--r--ChocolArm64/Instructions/InstEmit32Helper.cs146
-rw-r--r--ChocolArm64/Instructions/InstEmitAlu.cs422
-rw-r--r--ChocolArm64/Instructions/InstEmitAlu32.cs142
-rw-r--r--ChocolArm64/Instructions/InstEmitAluHelper.cs462
-rw-r--r--ChocolArm64/Instructions/InstEmitBfm.cs243
-rw-r--r--ChocolArm64/Instructions/InstEmitCcmp.cs82
-rw-r--r--ChocolArm64/Instructions/InstEmitCsel.cs59
-rw-r--r--ChocolArm64/Instructions/InstEmitException.cs87
-rw-r--r--ChocolArm64/Instructions/InstEmitFlow.cs181
-rw-r--r--ChocolArm64/Instructions/InstEmitFlow32.cs81
-rw-r--r--ChocolArm64/Instructions/InstEmitFlowHelper.cs144
-rw-r--r--ChocolArm64/Instructions/InstEmitHash.cs115
-rw-r--r--ChocolArm64/Instructions/InstEmitMemory.cs241
-rw-r--r--ChocolArm64/Instructions/InstEmitMemory32.cs320
-rw-r--r--ChocolArm64/Instructions/InstEmitMemoryEx.cs350
-rw-r--r--ChocolArm64/Instructions/InstEmitMemoryHelper.cs475
-rw-r--r--ChocolArm64/Instructions/InstEmitMove.cs41
-rw-r--r--ChocolArm64/Instructions/InstEmitMul.cs80
-rw-r--r--ChocolArm64/Instructions/InstEmitSimdArithmetic.cs3797
-rw-r--r--ChocolArm64/Instructions/InstEmitSimdCmp.cs862
-rw-r--r--ChocolArm64/Instructions/InstEmitSimdCrypto.cs54
-rw-r--r--ChocolArm64/Instructions/InstEmitSimdCvt.cs1382
-rw-r--r--ChocolArm64/Instructions/InstEmitSimdHash.cs140
-rw-r--r--ChocolArm64/Instructions/InstEmitSimdHelper.cs1580
-rw-r--r--ChocolArm64/Instructions/InstEmitSimdLogical.cs437
-rw-r--r--ChocolArm64/Instructions/InstEmitSimdMemory.cs182
-rw-r--r--ChocolArm64/Instructions/InstEmitSimdMove.cs793
-rw-r--r--ChocolArm64/Instructions/InstEmitSimdShift.cs1175
-rw-r--r--ChocolArm64/Instructions/InstEmitSystem.cs137
-rw-r--r--ChocolArm64/Instructions/InstEmitter.cs6
-rw-r--r--ChocolArm64/Instructions/SoftFallback.cs1194
-rw-r--r--ChocolArm64/Instructions/SoftFloat.cs2790
-rw-r--r--ChocolArm64/Instructions/VectorHelper.cs646
-rw-r--r--ChocolArm64/IntermediateRepresentation/BasicBlock.cs122
-rw-r--r--ChocolArm64/IntermediateRepresentation/ILLabel.cs4
-rw-r--r--ChocolArm64/IntermediateRepresentation/Operation.cs112
-rw-r--r--ChocolArm64/IntermediateRepresentation/OperationType.cs18
-rw-r--r--ChocolArm64/IntermediateRepresentation/RegisterMask.cs56
-rw-r--r--ChocolArm64/Memory/CompareExchange128.cs151
-rw-r--r--ChocolArm64/Memory/IMemory.cs37
-rw-r--r--ChocolArm64/Memory/MemoryHelper.cs71
-rw-r--r--ChocolArm64/Memory/MemoryManagement.cs114
-rw-r--r--ChocolArm64/Memory/MemoryManagementUnix.cs70
-rw-r--r--ChocolArm64/Memory/MemoryManagementWindows.cs155
-rw-r--r--ChocolArm64/Memory/MemoryManager.cs1017
-rw-r--r--ChocolArm64/Memory/MemoryProtection.cs16
-rw-r--r--ChocolArm64/Memory/MemoryProtectionException.cs10
-rw-r--r--ChocolArm64/OpCodeTable.cs792
-rw-r--r--ChocolArm64/Optimizations.cs27
-rw-r--r--ChocolArm64/State/Aarch32Mode.cs15
-rw-r--r--ChocolArm64/State/CpuThreadState.cs354
-rw-r--r--ChocolArm64/State/ExecutionMode.cs9
-rw-r--r--ChocolArm64/State/FpExc.cs12
-rw-r--r--ChocolArm64/State/FpType.cs11
-rw-r--r--ChocolArm64/State/Fpcr.cs11
-rw-r--r--ChocolArm64/State/Fpsr.cs8
-rw-r--r--ChocolArm64/State/PState.cs24
-rw-r--r--ChocolArm64/State/Register.cs148
-rw-r--r--ChocolArm64/State/RegisterAlias.cs41
-rw-r--r--ChocolArm64/State/RegisterConsts.cs8
-rw-r--r--ChocolArm64/State/RegisterSize.cs10
-rw-r--r--ChocolArm64/State/RegisterType.cs9
-rw-r--r--ChocolArm64/State/RoundMode.cs10
-rw-r--r--ChocolArm64/Translation/CallType.cs9
-rw-r--r--ChocolArm64/Translation/ILEmitterCtx.cs709
-rw-r--r--ChocolArm64/Translation/ILGeneratorEx.cs121
-rw-r--r--ChocolArm64/Translation/RegisterUsage.cs176
-rw-r--r--ChocolArm64/Translation/TranslatedSub.cs93
-rw-r--r--ChocolArm64/Translation/TranslatedSubBuilder.cs274
-rw-r--r--ChocolArm64/Translation/TranslationTier.cs11
-rw-r--r--ChocolArm64/Translation/Translator.cs252
-rw-r--r--ChocolArm64/Translation/TranslatorCache.cs196
-rw-r--r--ChocolArm64/Translation/TranslatorQueue.cs77
-rw-r--r--ChocolArm64/Translation/TranslatorQueueItem.cs27
161 files changed, 0 insertions, 27032 deletions
diff --git a/ChocolArm64/ChocolArm64.csproj b/ChocolArm64/ChocolArm64.csproj
deleted file mode 100644
index cccdd94d..00000000
--- a/ChocolArm64/ChocolArm64.csproj
+++ /dev/null
@@ -1,39 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
- <PropertyGroup>
- <TargetFramework>netcoreapp2.1</TargetFramework>
- <RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
- <Configurations>Debug;Release;Profile Debug;Profile Release</Configurations>
- </PropertyGroup>
-
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
-
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile Debug|AnyCPU'">
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- <DefineConstants>TRACE;USE_PROFILING</DefineConstants>
- <Optimize>false</Optimize>
- </PropertyGroup>
-
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
-
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile Release|AnyCPU'">
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- <DefineConstants>TRACE;USE_PROFILING</DefineConstants>
- <Optimize>true</Optimize>
- </PropertyGroup>
-
- <ItemGroup>
- <PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
- <PackageReference Include="System.Runtime.Intrinsics.Experimental" Version="4.5.0-rc1" />
- </ItemGroup>
-
- <ItemGroup>
- <ProjectReference Include="..\Ryujinx.Profiler\Ryujinx.Profiler.csproj" />
- <ProjectReference Include="..\ARMeilleure\ARMeilleure.csproj" />
- </ItemGroup>
-
-</Project>
diff --git a/ChocolArm64/Decoders/BitUtils.cs b/ChocolArm64/Decoders/BitUtils.cs
deleted file mode 100644
index 8b9fb5e3..00000000
--- 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 fc87fd18..00000000
--- 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<OpCode64> OpCodes { get; private set; }
-
- public Block()
- {
- OpCodes = new List<OpCode64>();
- }
-
- 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<OpCode64> 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 ef4b2959..00000000
--- 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 b7768bb4..00000000
--- 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 a1eeee15..00000000
--- 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<Type, OpActivator> _opActivators;
-
- static Decoder()
- {
- _opActivators = new ConcurrentDictionary<Type, OpActivator>();
- }
-
- 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<Block> blocks = new List<Block>();
-
- Queue<Block> workQueue = new Queue<Block>();
-
- Dictionary<ulong, Block> visited = new Dictionary<ulong, Block>();
-
- 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<Block> 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 2209472b..00000000
--- 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 3353ffe8..00000000
--- 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 d6f6d82a..00000000
--- 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 b69c1e36..00000000
--- 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 a498b02d..00000000
--- 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 8ed25add..00000000
--- 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 d611c53b..00000000
--- 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 e9407123..00000000
--- 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 b9a5fe9e..00000000
--- 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 4b305e27..00000000
--- 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 df503ae9..00000000
--- 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 f41fc4d2..00000000
--- 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 f0c6a832..00000000
--- 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 2c465406..00000000
--- 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 c6dc2c7f..00000000
--- 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 fc8f54d6..00000000
--- 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 70f833ec..00000000
--- 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 1909757c..00000000
--- 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 0cf06696..00000000
--- 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 4302f117..00000000
--- 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 f23916be..00000000
--- 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 7f3c29a6..00000000
--- 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 4a0fa537..00000000
--- 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 ed648a5f..00000000
--- 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 ca46e08f..00000000
--- 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 02e446e8..00000000
--- 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 652da8a5..00000000
--- 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 1072228e..00000000
--- 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 98b2f07b..00000000
--- 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 b46fef4f..00000000
--- 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 64ac08a7..00000000
--- 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 bed840b8..00000000
--- 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 24cee056..00000000
--- 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 bb5326ce..00000000
--- 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 f419ffa0..00000000
--- 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 2e674a54..00000000
--- 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 ca7df554..00000000
--- 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 a2e8baea..00000000
--- 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 74dbff58..00000000
--- 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 6891a8f4..00000000
--- 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 d65a24a4..00000000
--- 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 78d5de55..00000000
--- 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 a0544d98..00000000
--- 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 108a2798..00000000
--- 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 2554124c..00000000
--- 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 36e67583..00000000
--- 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 39935eb3..00000000
--- 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 01a62ef5..00000000
--- 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 29bfeee3..00000000
--- 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 5b81c755..00000000
--- 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 2eb734aa..00000000
--- 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 7dbd9247..00000000
--- 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 176b7b93..00000000
--- 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 a705e489..00000000
--- 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 3181a85a..00000000
--- 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 1c57f19c..00000000
--- 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 47de231c..00000000
--- 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 6752e185..00000000
--- 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 27f586f1..00000000
--- 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 3b25faeb..00000000
--- 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 9fbab567..00000000
--- 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 c98ffd03..00000000
--- 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 83297c41..00000000
--- 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 1b796742..00000000
--- 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 4ccbbed2..00000000
--- 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 1b0ead33..00000000
--- 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 4bf462de..00000000
--- 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 04e95861..00000000
--- 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 b5db7345..00000000
--- 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 d4cd88d1..00000000
--- 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 13cc9090..00000000
--- 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 41c51565..00000000
--- 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 005c470d..00000000
--- 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 52c059f4..00000000
--- 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 29514700..00000000
--- 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 cad43103..00000000
--- 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 c12781ed..00000000
--- 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 e3cc0ba0..00000000
--- 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 3ad7ea8b..00000000
--- 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 e9b6ed5f..00000000
--- 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<float> AesInvMixColumns(Vector128<float> 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<float> AesInvShiftRows(Vector128<float> 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<float> AesInvSubBytes(Vector128<float> 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<float> AesMixColumns(Vector128<float> 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<float> AesShiftRows(Vector128<float> 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<float> AesSubBytes(Vector128<float> 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<float> op, byte[] state)
- {
- if (!Sse2.IsSupported)
- {
- throw new PlatformNotSupportedException();
- }
-
- fixed (byte* ptr = &state[0])
- {
- Sse2.Store(ptr, Sse.StaticCast<float, byte>(op));
- }
- }
-
- private unsafe static void FromByteArrayToVector(byte[] state, ref Vector128<float> op)
- {
- if (!Sse2.IsSupported)
- {
- throw new PlatformNotSupportedException();
- }
-
- fixed (byte* ptr = &state[0])
- {
- op = Sse.StaticCast<byte, float>(Sse2.LoadVector128(ptr));
- }
- }
- }
-}
diff --git a/ChocolArm64/Instructions/Inst.cs b/ChocolArm64/Instructions/Inst.cs
deleted file mode 100644
index de9ec18b..00000000
--- 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 c5d08b8a..00000000
--- 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 25bd8e64..00000000
--- 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 94a8c750..00000000
--- 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 64822088..00000000
--- 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 75e259c1..00000000
--- 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 e21dc696..00000000
--- 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 7008a8c7..00000000
--- 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 c835fb0d..00000000
--- 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 6355b8b4..00000000
--- 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 133e2784..00000000
--- 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 f36fe5a1..00000000
--- 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 7e21a886..00000000
--- 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 1328f393..00000000
--- 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 807a65fe..00000000
--- 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 5deb035d..00000000
--- 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 08c8265b..00000000
--- 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 be3e8e2d..00000000
--- 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 b7418e69..00000000
--- 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 fa9666eb..00000000
--- 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<float>), typeof(Vector128<float>) };
-
- 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<double>), typeof(Vector128<double>) };
-
- 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<float>), typeof(Vector128<float>) };
-
- 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<double>), typeof(Vector128<double>) };
-
- 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<float>), typeof(Vector128<float>) };
-
- 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<double>), typeof(Vector128<double>) };
-
- 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<float>), typeof(Vector128<float>) };
-
- 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<double>), typeof(Vector128<double>) };
-
- 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<float>), typeof(Vector128<float>) };
-
- 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<double>), typeof(Vector128<double>) };
-
- 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<float>), typeof(Vector128<float>) };
-
- 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<double>), typeof(Vector128<double>) };
-
- 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<float>), typeof(Vector128<float>) };
-
- 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<double>), typeof(Vector128<double>) };
-
- 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<float>), typeof(Vector128<float>), typeof(byte) };
- Type[] typesMulAdd = new Type[] { typeof(Vector128<float>), typeof(Vector128<float>) };
-
- 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<double>), typeof(Vector128<double>), typeof(byte) };
- Type[] typesMulAdd = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
-
- 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<float>), typeof(Vector128<float>) };
-
- 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<double>), typeof(Vector128<double>) };
-
- 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<float>), typeof(Vector128<float>), typeof(byte) };
- Type[] typesMulSub = new Type[] { typeof(Vector128<float>), typeof(Vector128<float>) };
-
- 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<double>), typeof(Vector128<double>), typeof(byte) };
- Type[] typesMulSub = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
-
- 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<float>), typeof(Vector128<float>) };
-
- 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<double>), typeof(Vector128<double>) };
-
- 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<float>), typeof(Vector128<float>), typeof(byte) };
- Type[] typesMul = new Type[] { typeof(Vector128<float>), typeof(Vector128<float>) };
-
- 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<double>), typeof(Vector128<double>), typeof(byte) };
- Type[] typesMul = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
-
- 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<float>), typeof(Vector128<float>) };
-
- 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<double>), typeof(Vector128<double>) };
-
- 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<float>), typeof(Vector128<float>) };
-
- 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<double>), typeof(Vector128<double>) };
-
- 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<float>), typeof(Vector128<float>) };
-
- 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<double>), typeof(Vector128<double>) };
-
- 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<float>), typeof(Vector128<float>) };
-
- 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<double>), typeof(Vector128<double>) };
-
- 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<float>), typeof(Vector128<float>) };
-
- 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<double>), typeof(Vector128<double>) };
-
- 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<float>), typeof(Vector128<float>) };
-
- 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<double>), typeof(Vector128<double>) };
-
- 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<long>), typeof(Vector128<long>) };
-
- 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<long>), typeof(Vector128<long>) };
- 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<long>), typeof(Vector128<long>) };
- 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<long>), typeof(Vector128<long>) };
- 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<float>), typeof(Vector128<float>) }
- : new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
-
- 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<float>) }
- : new Type[] { typeof(Vector128<double>) };
-
- 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<sbyte>), typeof(Vector128<sbyte>), typeof(Vector128<sbyte>) };
- Type[] typesMul = new Type[] { typeof(Vector128<short>), typeof(Vector128<short>) };
- Type[] typesShs = new Type[] { typeof(Vector128<short>), 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<short>), typeof(Vector128<short>) };
-
- 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<int>), typeof(Vector128<int>) };
-
- 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 b2925006..00000000
--- 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<long>), typeof(Vector128<long>) };
- 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<long>), typeof(Vector128<long>) };
- 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<long>), typeof(Vector128<long>) };
- 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<float>), typeof(Vector128<float>) };
-
- 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<double>), typeof(Vector128<double>) };
-
- 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<float>), typeof(Vector128<float>) };
-
- 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<double>), typeof(Vector128<double>) };
-
- 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 33c81aab..00000000
--- 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 2b3deb98..00000000
--- 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<double>), typeof(Vector128<float>) };
-
- 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<float>), typeof(Vector128<double>) };
-
- 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<float>) };
-
- 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<double>) };
-
- 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<float>), typeof(Vector128<float>) };
- Type[] typesRndCvt = new Type[] { typeof(Vector128<float>) };
- 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<double>), typeof(Vector128<double>) };
- Type[] typesRndCvt = new Type[] { typeof(Vector128<double>) };
- 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<float>), typeof(Vector128<float>) };
- Type[] typesAdd = new Type[] { typeof(Vector128<int>), typeof(Vector128<int>) };
- Type[] typesRndCvt = new Type[] { typeof(Vector128<float>) };
- 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<double>), typeof(Vector128<double>) };
- Type[] typesAdd = new Type[] { typeof(Vector128<long>), typeof(Vector128<long>) };
- Type[] typesRndCvt = new Type[] { typeof(Vector128<double>) };
- 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<float>), typeof(Vector128<float>) };
- Type[] typesCvt = new Type[] { typeof(Vector128<int>) };
- 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<float>), typeof(Vector128<float>) };
- Type[] typesSrlSll = new Type[] { typeof(Vector128<int>), typeof(byte) };
- Type[] typesCvt = new Type[] { typeof(Vector128<int>) };
- 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 bb767fec..00000000
--- 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 c8c8df74..00000000
--- 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<sbyte>),
- typeof(Vector128<short>),
- typeof(Vector128<int>),
- typeof(Vector128<long>)
- };
-
- public static readonly Type[] VectorUIntTypesPerSizeLog2 = new Type[]
- {
- typeof(Vector128<byte>),
- typeof(Vector128<ushort>),
- typeof(Vector128<uint>),
- typeof(Vector128<ulong>)
- };
-
- [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<float>);
- }
- else /* if (sizeF == 1) */
- {
- type = typeof(Sse2);
- baseType = typeof(Vector128<double>);
- }
-
- 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<float>), typeof(Vector128<float>) };
-
- 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<float>), typeof(Vector128<float>), typeof(byte) };
- Type[] types = new Type[] { typeof(Vector128<float>), typeof(Vector128<float>) };
-
- 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<double>), typeof(Vector128<double>) };
-
- 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<ulong>) };
-
- 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 a5a92274..00000000
--- 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<byte>), typeof(Vector128<byte>) };
-
- 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<byte>), typeof(Vector128<byte>) };
-
- 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<byte>), typeof(Vector128<byte>) };
-
- 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<long>), typeof(Vector128<long>) };
-
- 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<long>), typeof(Vector128<long>) };
-
- 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<sbyte>), typeof(Vector128<sbyte>) };
-
- 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<sbyte>), typeof(Vector128<sbyte>) };
-
- 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<sbyte>), typeof(Vector128<sbyte>) };
-
- 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 073b0f0a..00000000
--- 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 647a2238..00000000
--- 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<byte>), typeof(byte) };
- Type[] typesOr = new Type[] { typeof(Vector128<byte>), typeof(Vector128<byte>) };
-
- 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<sbyte>), typeof(Vector128<sbyte>) };
- Type[] typesOr = new Type[] { typeof(Vector128<long>), typeof(Vector128<long>) };
- 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 6865948a..00000000
--- 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<sbyte>), typeof(Vector128<sbyte>) };
- 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<sbyte>), typeof(Vector128<sbyte>) };
- 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 ac264de9..00000000
--- 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 db6e8604..00000000
--- 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 16638894..00000000
--- 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<float> Decrypt(Vector128<float> value, Vector128<float> roundKey)
- {
- if (!Sse.IsSupported)
- {
- throw new PlatformNotSupportedException();
- }
-
- return CryptoHelper.AesInvSubBytes(CryptoHelper.AesInvShiftRows(Sse.Xor(value, roundKey)));
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector128<float> Encrypt(Vector128<float> value, Vector128<float> roundKey)
- {
- if (!Sse.IsSupported)
- {
- throw new PlatformNotSupportedException();
- }
-
- return CryptoHelper.AesSubBytes(CryptoHelper.AesShiftRows(Sse.Xor(value, roundKey)));
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector128<float> InverseMixColumns(Vector128<float> value)
- {
- return CryptoHelper.AesInvMixColumns(value);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector128<float> MixColumns(Vector128<float> value)
- {
- return CryptoHelper.AesMixColumns(value);
- }
-#endregion
-
-#region "Sha1"
- public static Vector128<float> HashChoose(Vector128<float> hash_abcd, uint hash_e, Vector128<float> 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<float> HashMajority(Vector128<float> hash_abcd, uint hash_e, Vector128<float> 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<float> HashParity(Vector128<float> hash_abcd, uint hash_e, Vector128<float> wk)
- {
- for (int e = 0; e <= 3; e++)
- {
- uint t = ShaParity((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<float> Sha1SchedulePart1(Vector128<float> w0_3, Vector128<float> w4_7, Vector128<float> w8_11)
- {
- if (!Sse.IsSupported)
- {
- throw new PlatformNotSupportedException();
- }
-
- Vector128<float> result = new Vector128<float>();
-
- ulong t2 = VectorExtractIntZx(w4_7, (byte)0, 3);
- ulong t1 = VectorExtractIntZx(w0_3, (byte)1, 3);
-
- result = VectorInsertInt((ulong)t1, result, (byte)0, 3);
- result = VectorInsertInt((ulong)t2, result, (byte)1, 3);
-
- return Sse.Xor(result, Sse.Xor(w0_3, w8_11));
- }
-
- public static Vector128<float> Sha1SchedulePart2(Vector128<float> tw0_3, Vector128<float> w12_15)
- {
- if (!Sse2.IsSupported)
- {
- throw new PlatformNotSupportedException();
- }
-
- Vector128<float> result = new Vector128<float>();
-
- Vector128<float> t = Sse.Xor(tw0_3, Sse.StaticCast<uint, float>(
- Sse2.ShiftRightLogical128BitLane(Sse.StaticCast<float, uint>(w12_15), (byte)4)));
-
- uint tE0 = (uint)VectorExtractIntZx(t, (byte)0, 2);
- uint tE1 = (uint)VectorExtractIntZx(t, (byte)1, 2);
- uint tE2 = (uint)VectorExtractIntZx(t, (byte)2, 2);
- uint tE3 = (uint)VectorExtractIntZx(t, (byte)3, 2);
-
- result = VectorInsertInt((ulong)tE0.Rol(1), result, (byte)0, 2);
- result = VectorInsertInt((ulong)tE1.Rol(1), result, (byte)1, 2);
- result = VectorInsertInt((ulong)tE2.Rol(1), result, (byte)2, 2);
-
- return VectorInsertInt((ulong)(tE3.Rol(1) ^ tE0.Rol(2)), result, (byte)3, 2);
- }
-
- private static void Rol32_160(ref uint y, ref Vector128<float> x)
- {
- if (!Sse2.IsSupported)
- {
- throw new PlatformNotSupportedException();
- }
-
- uint xE3 = (uint)VectorExtractIntZx(x, (byte)3, 2);
-
- x = Sse.StaticCast<uint, float>(Sse2.ShiftLeftLogical128BitLane(Sse.StaticCast<float, uint>(x), (byte)4));
- x = VectorInsertInt((ulong)y, x, (byte)0, 2);
-
- y = xE3;
- }
-
- private static uint ShaChoose(uint x, uint y, uint z)
- {
- return ((y ^ z) & x) ^ z;
- }
-
- private static uint ShaMajority(uint x, uint y, uint z)
- {
- return (x & y) | ((x | y) & z);
- }
-
- private static uint ShaParity(uint x, uint y, uint z)
- {
- return x ^ y ^ z;
- }
-
- private static uint Rol(this uint value, int count)
- {
- return (value << count) | (value >> (32 - count));
- }
-#endregion
-
-#region "Sha256"
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector128<float> HashLower(Vector128<float> hash_abcd, Vector128<float> hash_efgh, Vector128<float> wk)
- {
- return Sha256Hash(hash_abcd, hash_efgh, wk, true);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector128<float> HashUpper(Vector128<float> hash_efgh, Vector128<float> hash_abcd, Vector128<float> wk)
- {
- return Sha256Hash(hash_abcd, hash_efgh, wk, false);
- }
-
- public static Vector128<float> Sha256SchedulePart1(Vector128<float> w0_3, Vector128<float> w4_7)
- {
- Vector128<float> result = new Vector128<float>();
-
- for (int e = 0; e <= 3; e++)
- {
- uint elt = (uint)VectorExtractIntZx(e <= 2 ? w0_3 : w4_7, (byte)(e <= 2 ? e + 1 : 0), 2);
-
- elt = elt.Ror(7) ^ elt.Ror(18) ^ elt.Lsr(3);
-
- elt += (uint)VectorExtractIntZx(w0_3, (byte)e, 2);
-
- result = VectorInsertInt((ulong)elt, result, (byte)e, 2);
- }
-
- return result;
- }
-
- public static Vector128<float> Sha256SchedulePart2(Vector128<float> w0_3, Vector128<float> w8_11, Vector128<float> w12_15)
- {
- Vector128<float> result = new Vector128<float>();
-
- ulong t1 = VectorExtractIntZx(w12_15, (byte)1, 3);
-
- for (int e = 0; e <= 1; e++)
- {
- uint elt = t1.ULongPart(e);
-
- elt = elt.Ror(17) ^ elt.Ror(19) ^ elt.Lsr(10);
-
- elt += (uint)VectorExtractIntZx(w0_3, (byte)e, 2);
- elt += (uint)VectorExtractIntZx(w8_11, (byte)(e + 1), 2);
-
- result = VectorInsertInt((ulong)elt, result, (byte)e, 2);
- }
-
- t1 = VectorExtractIntZx(result, (byte)0, 3);
-
- for (int e = 2; e <= 3; e++)
- {
- uint elt = t1.ULongPart(e - 2);
-
- elt = elt.Ror(17) ^ elt.Ror(19) ^ elt.Lsr(10);
-
- elt += (uint)VectorExtractIntZx(w0_3, (byte)e, 2);
- elt += (uint)VectorExtractIntZx(e == 2 ? w8_11 : w12_15, (byte)(e == 2 ? 3 : 0), 2);
-
- result = VectorInsertInt((ulong)elt, result, (byte)e, 2);
- }
-
- return result;
- }
-
- private static Vector128<float> Sha256Hash(Vector128<float> x, Vector128<float> y, Vector128<float> w, bool part1)
- {
- for (int e = 0; e <= 3; e++)
- {
- uint chs = ShaChoose((uint)VectorExtractIntZx(y, (byte)0, 2),
- (uint)VectorExtractIntZx(y, (byte)1, 2),
- (uint)VectorExtractIntZx(y, (byte)2, 2));
-
- uint maj = ShaMajority((uint)VectorExtractIntZx(x, (byte)0, 2),
- (uint)VectorExtractIntZx(x, (byte)1, 2),
- (uint)VectorExtractIntZx(x, (byte)2, 2));
-
- uint t1 = (uint)VectorExtractIntZx(y, (byte)3, 2);
- t1 += ShaHashSigma1((uint)VectorExtractIntZx(y, (byte)0, 2)) + chs;
- t1 += (uint)VectorExtractIntZx(w, (byte)e, 2);
-
- uint t2 = t1 + (uint)VectorExtractIntZx(x, (byte)3, 2);
- x = VectorInsertInt((ulong)t2, x, (byte)3, 2);
- t2 = t1 + ShaHashSigma0((uint)VectorExtractIntZx(x, (byte)0, 2)) + maj;
- y = VectorInsertInt((ulong)t2, y, (byte)3, 2);
-
- Rol32_256(ref y, ref x);
- }
-
- return part1 ? x : y;
- }
-
- private static void Rol32_256(ref Vector128<float> y, ref Vector128<float> x)
- {
- if (!Sse2.IsSupported)
- {
- throw new PlatformNotSupportedException();
- }
-
- uint yE3 = (uint)VectorExtractIntZx(y, (byte)3, 2);
- uint xE3 = (uint)VectorExtractIntZx(x, (byte)3, 2);
-
- y = Sse.StaticCast<uint, float>(Sse2.ShiftLeftLogical128BitLane(Sse.StaticCast<float, uint>(y), (byte)4));
- x = Sse.StaticCast<uint, float>(Sse2.ShiftLeftLogical128BitLane(Sse.StaticCast<float, uint>(x), (byte)4));
-
- y = VectorInsertInt((ulong)xE3, y, (byte)0, 2);
- x = VectorInsertInt((ulong)yE3, x, (byte)0, 2);
- }
-
- private static uint ShaHashSigma0(uint x)
- {
- return x.Ror(2) ^ x.Ror(13) ^ x.Ror(22);
- }
-
- private static uint ShaHashSigma1(uint x)
- {
- return x.Ror(6) ^ x.Ror(11) ^ x.Ror(25);
- }
-
- private static uint Ror(this uint value, int count)
- {
- return (value >> count) | (value << (32 - count));
- }
-
- private static uint Lsr(this uint value, int count)
- {
- return value >> count;
- }
-
- private static uint ULongPart(this ulong value, int part)
- {
- return part == 0
- ? (uint)(value & 0xFFFFFFFFUL)
- : (uint)(value >> 32);
- }
-#endregion
-
-#region "Reverse"
- public static uint ReverseBits8(uint value)
- {
- value = ((value & 0xaa) >> 1) | ((value & 0x55) << 1);
- value = ((value & 0xcc) >> 2) | ((value & 0x33) << 2);
-
- return (value >> 4) | ((value & 0x0f) << 4);
- }
-
- public static uint ReverseBits32(uint value)
- {
- value = ((value & 0xaaaaaaaa) >> 1) | ((value & 0x55555555) << 1);
- value = ((value & 0xcccccccc) >> 2) | ((value & 0x33333333) << 2);
- value = ((value & 0xf0f0f0f0) >> 4) | ((value & 0x0f0f0f0f) << 4);
- value = ((value & 0xff00ff00) >> 8) | ((value & 0x00ff00ff) << 8);
-
- return (value >> 16) | (value << 16);
- }
-
- public static ulong ReverseBits64(ulong value)
- {
- value = ((value & 0xaaaaaaaaaaaaaaaa) >> 1 ) | ((value & 0x5555555555555555) << 1 );
- value = ((value & 0xcccccccccccccccc) >> 2 ) | ((value & 0x3333333333333333) << 2 );
- value = ((value & 0xf0f0f0f0f0f0f0f0) >> 4 ) | ((value & 0x0f0f0f0f0f0f0f0f) << 4 );
- value = ((value & 0xff00ff00ff00ff00) >> 8 ) | ((value & 0x00ff00ff00ff00ff) << 8 );
- value = ((value & 0xffff0000ffff0000) >> 16) | ((value & 0x0000ffff0000ffff) << 16);
-
- return (value >> 32) | (value << 32);
- }
-
- public static uint ReverseBytes16_32(uint value) => (uint)ReverseBytes16_64(value);
- public static uint ReverseBytes32_32(uint value) => (uint)ReverseBytes32_64(value);
-
- public static ulong ReverseBytes16_64(ulong value) => ReverseBytes(value, RevSize.Rev16);
- public static ulong ReverseBytes32_64(ulong value) => ReverseBytes(value, RevSize.Rev32);
- public static ulong ReverseBytes64(ulong value) => ReverseBytes(value, RevSize.Rev64);
-
- private enum RevSize
- {
- Rev16,
- Rev32,
- Rev64
- }
-
- private static ulong ReverseBytes(ulong value, RevSize size)
- {
- value = ((value & 0xff00ff00ff00ff00) >> 8) | ((value & 0x00ff00ff00ff00ff) << 8);
-
- if (size == RevSize.Rev16)
- {
- return value;
- }
-
- value = ((value & 0xffff0000ffff0000) >> 16) | ((value & 0x0000ffff0000ffff) << 16);
-
- if (size == RevSize.Rev32)
- {
- return value;
- }
-
- value = ((value & 0xffffffff00000000) >> 32) | ((value & 0x00000000ffffffff) << 32);
-
- if (size == RevSize.Rev64)
- {
- return value;
- }
-
- throw new ArgumentException(nameof(size));
- }
-#endregion
-
-#region "MultiplyHigh"
- public static long SMulHi128(long left, long right)
- {
- long result = (long)UMulHi128((ulong)left, (ulong)right);
-
- if (left < 0)
- {
- result -= right;
- }
-
- if (right < 0)
- {
- result -= left;
- }
-
- return result;
- }
-
- public static ulong UMulHi128(ulong left, ulong right)
- {
- ulong lHigh = left >> 32;
- ulong lLow = left & 0xFFFFFFFF;
- ulong rHigh = right >> 32;
- ulong rLow = right & 0xFFFFFFFF;
-
- ulong z2 = lLow * rLow;
- ulong t = lHigh * rLow + (z2 >> 32);
- ulong z1 = t & 0xFFFFFFFF;
- ulong z0 = t >> 32;
-
- z1 += lLow * rHigh;
-
- return lHigh * rHigh + z0 + (z1 >> 32);
- }
-#endregion
- }
-}
diff --git a/ChocolArm64/Instructions/SoftFloat.cs b/ChocolArm64/Instructions/SoftFloat.cs
deleted file mode 100644
index e78932cc..00000000
--- a/ChocolArm64/Instructions/SoftFloat.cs
+++ /dev/null
@@ -1,2790 +0,0 @@
-using ChocolArm64.State;
-using System;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-
-namespace ChocolArm64.Instructions
-{
- static class SoftFloat
- {
- static SoftFloat()
- {
- RecipEstimateTable = BuildRecipEstimateTable();
- RecipSqrtEstimateTable = BuildRecipSqrtEstimateTable();
- }
-
- internal static readonly byte[] RecipEstimateTable;
- internal static readonly byte[] RecipSqrtEstimateTable;
-
- private static byte[] BuildRecipEstimateTable()
- {
- byte[] tbl = new byte[256];
-
- for (int idx = 0; idx < 256; idx++)
- {
- uint src = (uint)idx + 256u;
-
- Debug.Assert(256u <= src && src < 512u);
-
- src = (src << 1) + 1u;
-
- uint aux = (1u << 19) / src;
-
- uint dst = (aux + 1u) >> 1;
-
- Debug.Assert(256u <= dst && dst < 512u);
-
- tbl[idx] = (byte)(dst - 256u);
- }
-
- return tbl;
- }
-
- private static byte[] BuildRecipSqrtEstimateTable()
- {
- byte[] tbl = new byte[384];
-
- for (int idx = 0; idx < 384; idx++)
- {
- uint src = (uint)idx + 128u;
-
- Debug.Assert(128u <= src && src < 512u);
-
- if (src < 256u)
- {
- src = (src << 1) + 1u;
- }
- else
- {
- src = (src >> 1) << 1;
- src = (src + 1u) << 1;
- }
-
- uint aux = 512u;
-
- while (src * (aux + 1u) * (aux + 1u) < (1u << 28))
- {
- aux = aux + 1u;
- }
-
- uint dst = (aux + 1u) >> 1;
-
- Debug.Assert(256u <= dst && dst < 512u);
-
- tbl[idx] = (byte)(dst - 256u);
- }
-
- return tbl;
- }
- }
-
- static class SoftFloat16_32
- {
- public static float FPConvert(ushort valueBits, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat16_32.FPConvert: state.Fpcr = 0x{state.CFpcr:X8}");
-
- double real = valueBits.FPUnpackCv(out FpType type, out bool sign, state);
-
- float result;
-
- if (type == FpType.SNaN || type == FpType.QNaN)
- {
- if (state.GetFpcrFlag(Fpcr.Dn))
- {
- result = FPDefaultNaN();
- }
- else
- {
- result = FPConvertNaN(valueBits);
- }
-
- if (type == FpType.SNaN)
- {
- FPProcessException(FpExc.InvalidOp, state);
- }
- }
- else if (type == FpType.Infinity)
- {
- result = FPInfinity(sign);
- }
- else if (type == FpType.Zero)
- {
- result = FPZero(sign);
- }
- else
- {
- result = FPRoundCv(real, state);
- }
-
- return result;
- }
-
- private static float FPDefaultNaN()
- {
- return -float.NaN;
- }
-
- private static float FPInfinity(bool sign)
- {
- return sign ? float.NegativeInfinity : float.PositiveInfinity;
- }
-
- private static float FPZero(bool sign)
- {
- return sign ? -0f : +0f;
- }
-
- private static float FPMaxNormal(bool sign)
- {
- return sign ? float.MinValue : float.MaxValue;
- }
-
- private static double FPUnpackCv(
- this ushort valueBits,
- out FpType type,
- out bool sign,
- CpuThreadState state)
- {
- sign = (~(uint)valueBits & 0x8000u) == 0u;
-
- uint exp16 = ((uint)valueBits & 0x7C00u) >> 10;
- uint frac16 = (uint)valueBits & 0x03FFu;
-
- double real;
-
- if (exp16 == 0u)
- {
- if (frac16 == 0u)
- {
- type = FpType.Zero;
- real = 0d;
- }
- else
- {
- type = FpType.Nonzero; // Subnormal.
- real = Math.Pow(2d, -14) * ((double)frac16 * Math.Pow(2d, -10));
- }
- }
- else if (exp16 == 0x1Fu && !state.GetFpcrFlag(Fpcr.Ahp))
- {
- if (frac16 == 0u)
- {
- type = FpType.Infinity;
- real = Math.Pow(2d, 1000);
- }
- else
- {
- type = (~frac16 & 0x0200u) == 0u ? FpType.QNaN : FpType.SNaN;
- real = 0d;
- }
- }
- else
- {
- type = FpType.Nonzero; // Normal.
- real = Math.Pow(2d, (int)exp16 - 15) * (1d + (double)frac16 * Math.Pow(2d, -10));
- }
-
- return sign ? -real : real;
- }
-
- private static float FPRoundCv(double real, CpuThreadState state)
- {
- const int minimumExp = -126;
-
- const int e = 8;
- const int f = 23;
-
- bool sign;
- double mantissa;
-
- if (real < 0d)
- {
- sign = true;
- mantissa = -real;
- }
- else
- {
- sign = false;
- mantissa = real;
- }
-
- int exponent = 0;
-
- while (mantissa < 1d)
- {
- mantissa *= 2d;
- exponent--;
- }
-
- while (mantissa >= 2d)
- {
- mantissa /= 2d;
- exponent++;
- }
-
- if (state.GetFpcrFlag(Fpcr.Fz) && exponent < minimumExp)
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- return FPZero(sign);
- }
-
- uint biasedExp = (uint)Math.Max(exponent - minimumExp + 1, 0);
-
- if (biasedExp == 0u)
- {
- mantissa /= Math.Pow(2d, minimumExp - exponent);
- }
-
- uint intMant = (uint)Math.Floor(mantissa * Math.Pow(2d, f));
- double error = mantissa * Math.Pow(2d, f) - (double)intMant;
-
- if (biasedExp == 0u && (error != 0d || state.GetFpcrFlag(Fpcr.Ufe)))
- {
- FPProcessException(FpExc.Underflow, state);
- }
-
- bool overflowToInf;
- bool roundUp;
-
- switch (state.FPRoundingMode())
- {
- default:
- case RoundMode.ToNearest:
- roundUp = (error > 0.5d || (error == 0.5d && (intMant & 1u) == 1u));
- overflowToInf = true;
- break;
-
- case RoundMode.TowardsPlusInfinity:
- roundUp = (error != 0d && !sign);
- overflowToInf = !sign;
- break;
-
- case RoundMode.TowardsMinusInfinity:
- roundUp = (error != 0d && sign);
- overflowToInf = sign;
- break;
-
- case RoundMode.TowardsZero:
- roundUp = false;
- overflowToInf = false;
- break;
- }
-
- if (roundUp)
- {
- intMant++;
-
- if (intMant == 1u << f)
- {
- biasedExp = 1u;
- }
-
- if (intMant == 1u << (f + 1))
- {
- biasedExp++;
- intMant >>= 1;
- }
- }
-
- float result;
-
- if (biasedExp >= (1u << e) - 1u)
- {
- result = overflowToInf ? FPInfinity(sign) : FPMaxNormal(sign);
-
- FPProcessException(FpExc.Overflow, state);
-
- error = 1d;
- }
- else
- {
- result = BitConverter.Int32BitsToSingle(
- (int)((sign ? 1u : 0u) << 31 | (biasedExp & 0xFFu) << 23 | (intMant & 0x007FFFFFu)));
- }
-
- if (error != 0d)
- {
- FPProcessException(FpExc.Inexact, state);
- }
-
- return result;
- }
-
- private static float FPConvertNaN(ushort valueBits)
- {
- return BitConverter.Int32BitsToSingle(
- (int)(((uint)valueBits & 0x8000u) << 16 | 0x7FC00000u | ((uint)valueBits & 0x01FFu) << 13));
- }
-
- private static void FPProcessException(FpExc exc, CpuThreadState state)
- {
- int enable = (int)exc + 8;
-
- if ((state.CFpcr & (1 << enable)) != 0)
- {
- throw new NotImplementedException("Floating-point trap handling.");
- }
- else
- {
- state.CFpsr |= 1 << (int)exc;
- }
- }
- }
-
- static class SoftFloat32_16
- {
- public static ushort FPConvert(float value, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32_16.FPConvert: state.Fpcr = 0x{state.CFpcr:X8}");
-
- double real = value.FPUnpackCv(out FpType type, out bool sign, out uint valueBits, state);
-
- bool altHp = state.GetFpcrFlag(Fpcr.Ahp);
-
- ushort resultBits;
-
- if (type == FpType.SNaN || type == FpType.QNaN)
- {
- if (altHp)
- {
- resultBits = FPZero(sign);
- }
- else if (state.GetFpcrFlag(Fpcr.Dn))
- {
- resultBits = FPDefaultNaN();
- }
- else
- {
- resultBits = FPConvertNaN(valueBits);
- }
-
- if (type == FpType.SNaN || altHp)
- {
- FPProcessException(FpExc.InvalidOp, state);
- }
- }
- else if (type == FpType.Infinity)
- {
- if (altHp)
- {
- resultBits = (ushort)((sign ? 1u : 0u) << 15 | 0x7FFFu);
-
- FPProcessException(FpExc.InvalidOp, state);
- }
- else
- {
- resultBits = FPInfinity(sign);
- }
- }
- else if (type == FpType.Zero)
- {
- resultBits = FPZero(sign);
- }
- else
- {
- resultBits = FPRoundCv(real, state);
- }
-
- return resultBits;
- }
-
- private static ushort FPDefaultNaN()
- {
- return (ushort)0x7E00u;
- }
-
- private static ushort FPInfinity(bool sign)
- {
- return sign ? (ushort)0xFC00u : (ushort)0x7C00u;
- }
-
- private static ushort FPZero(bool sign)
- {
- return sign ? (ushort)0x8000u : (ushort)0x0000u;
- }
-
- private static ushort FPMaxNormal(bool sign)
- {
- return sign ? (ushort)0xFBFFu : (ushort)0x7BFFu;
- }
-
- private static double FPUnpackCv(
- this float value,
- out FpType type,
- out bool sign,
- out uint valueBits,
- CpuThreadState state)
- {
- valueBits = (uint)BitConverter.SingleToInt32Bits(value);
-
- sign = (~valueBits & 0x80000000u) == 0u;
-
- uint exp32 = (valueBits & 0x7F800000u) >> 23;
- uint frac32 = valueBits & 0x007FFFFFu;
-
- double real;
-
- if (exp32 == 0u)
- {
- if (frac32 == 0u || state.GetFpcrFlag(Fpcr.Fz))
- {
- type = FpType.Zero;
- real = 0d;
-
- if (frac32 != 0u)
- {
- FPProcessException(FpExc.InputDenorm, state);
- }
- }
- else
- {
- type = FpType.Nonzero; // Subnormal.
- real = Math.Pow(2d, -126) * ((double)frac32 * Math.Pow(2d, -23));
- }
- }
- else if (exp32 == 0xFFu)
- {
- if (frac32 == 0u)
- {
- type = FpType.Infinity;
- real = Math.Pow(2d, 1000);
- }
- else
- {
- type = (~frac32 & 0x00400000u) == 0u ? FpType.QNaN : FpType.SNaN;
- real = 0d;
- }
- }
- else
- {
- type = FpType.Nonzero; // Normal.
- real = Math.Pow(2d, (int)exp32 - 127) * (1d + (double)frac32 * Math.Pow(2d, -23));
- }
-
- return sign ? -real : real;
- }
-
- private static ushort FPRoundCv(double real, CpuThreadState state)
- {
- const int minimumExp = -14;
-
- const int e = 5;
- const int f = 10;
-
- bool sign;
- double mantissa;
-
- if (real < 0d)
- {
- sign = true;
- mantissa = -real;
- }
- else
- {
- sign = false;
- mantissa = real;
- }
-
- int exponent = 0;
-
- while (mantissa < 1d)
- {
- mantissa *= 2d;
- exponent--;
- }
-
- while (mantissa >= 2d)
- {
- mantissa /= 2d;
- exponent++;
- }
-
- uint biasedExp = (uint)Math.Max(exponent - minimumExp + 1, 0);
-
- if (biasedExp == 0u)
- {
- mantissa /= Math.Pow(2d, minimumExp - exponent);
- }
-
- uint intMant = (uint)Math.Floor(mantissa * Math.Pow(2d, f));
- double error = mantissa * Math.Pow(2d, f) - (double)intMant;
-
- if (biasedExp == 0u && (error != 0d || state.GetFpcrFlag(Fpcr.Ufe)))
- {
- FPProcessException(FpExc.Underflow, state);
- }
-
- bool overflowToInf;
- bool roundUp;
-
- switch (state.FPRoundingMode())
- {
- default:
- case RoundMode.ToNearest:
- roundUp = (error > 0.5d || (error == 0.5d && (intMant & 1u) == 1u));
- overflowToInf = true;
- break;
-
- case RoundMode.TowardsPlusInfinity:
- roundUp = (error != 0d && !sign);
- overflowToInf = !sign;
- break;
-
- case RoundMode.TowardsMinusInfinity:
- roundUp = (error != 0d && sign);
- overflowToInf = sign;
- break;
-
- case RoundMode.TowardsZero:
- roundUp = false;
- overflowToInf = false;
- break;
- }
-
- if (roundUp)
- {
- intMant++;
-
- if (intMant == 1u << f)
- {
- biasedExp = 1u;
- }
-
- if (intMant == 1u << (f + 1))
- {
- biasedExp++;
- intMant >>= 1;
- }
- }
-
- ushort resultBits;
-
- if (!state.GetFpcrFlag(Fpcr.Ahp))
- {
- if (biasedExp >= (1u << e) - 1u)
- {
- resultBits = overflowToInf ? FPInfinity(sign) : FPMaxNormal(sign);
-
- FPProcessException(FpExc.Overflow, state);
-
- error = 1d;
- }
- else
- {
- resultBits = (ushort)((sign ? 1u : 0u) << 15 | (biasedExp & 0x1Fu) << 10 | (intMant & 0x03FFu));
- }
- }
- else
- {
- if (biasedExp >= 1u << e)
- {
- resultBits = (ushort)((sign ? 1u : 0u) << 15 | 0x7FFFu);
-
- FPProcessException(FpExc.InvalidOp, state);
-
- error = 0d;
- }
- else
- {
- resultBits = (ushort)((sign ? 1u : 0u) << 15 | (biasedExp & 0x1Fu) << 10 | (intMant & 0x03FFu));
- }
- }
-
- if (error != 0d)
- {
- FPProcessException(FpExc.Inexact, state);
- }
-
- return resultBits;
- }
-
- private static ushort FPConvertNaN(uint valueBits)
- {
- return (ushort)((valueBits & 0x80000000u) >> 16 | 0x7E00u | (valueBits & 0x003FE000u) >> 13);
- }
-
- private static void FPProcessException(FpExc exc, CpuThreadState state)
- {
- int enable = (int)exc + 8;
-
- if ((state.CFpcr & (1 << enable)) != 0)
- {
- throw new NotImplementedException("Floating-point trap handling.");
- }
- else
- {
- state.CFpsr |= 1 << (int)exc;
- }
- }
- }
-
- static class SoftFloat32
- {
- public static float FPAdd(float value1, float value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPAdd: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out uint op1, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out uint op2, state);
-
- float result = FPProcessNaNs(type1, type2, op1, op2, out bool done, state);
-
- if (!done)
- {
- bool inf1 = type1 == FpType.Infinity; bool zero1 = type1 == FpType.Zero;
- bool inf2 = type2 == FpType.Infinity; bool zero2 = type2 == FpType.Zero;
-
- if (inf1 && inf2 && sign1 == !sign2)
- {
- result = FPDefaultNaN();
-
- FPProcessException(FpExc.InvalidOp, state);
- }
- else if ((inf1 && !sign1) || (inf2 && !sign2))
- {
- result = FPInfinity(false);
- }
- else if ((inf1 && sign1) || (inf2 && sign2))
- {
- result = FPInfinity(true);
- }
- else if (zero1 && zero2 && sign1 == sign2)
- {
- result = FPZero(sign1);
- }
- else
- {
- result = value1 + value2;
-
- if (state.GetFpcrFlag(Fpcr.Fz) && float.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0f);
- }
- }
- }
-
- return result;
- }
-
- public static int FPCompare(float value1, float value2, bool signalNaNs, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPCompare: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out _, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out _, state);
-
- int result;
-
- if (type1 == FpType.SNaN || type1 == FpType.QNaN || type2 == FpType.SNaN || type2 == FpType.QNaN)
- {
- result = 0b0011;
-
- if (type1 == FpType.SNaN || type2 == FpType.SNaN || signalNaNs)
- {
- FPProcessException(FpExc.InvalidOp, state);
- }
- }
- else
- {
- if (value1 == value2)
- {
- result = 0b0110;
- }
- else if (value1 < value2)
- {
- result = 0b1000;
- }
- else
- {
- result = 0b0010;
- }
- }
-
- return result;
- }
-
- public static float FPCompareEQ(float value1, float value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPCompareEQ: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out _, out _, state);
- value2 = value2.FPUnpack(out FpType type2, out _, out _, state);
-
- float result;
-
- if (type1 == FpType.SNaN || type1 == FpType.QNaN || type2 == FpType.SNaN || type2 == FpType.QNaN)
- {
- result = ZerosOrOnes(false);
-
- if (type1 == FpType.SNaN || type2 == FpType.SNaN)
- {
- FPProcessException(FpExc.InvalidOp, state);
- }
- }
- else
- {
- result = ZerosOrOnes(value1 == value2);
- }
-
- return result;
- }
-
- public static float FPCompareGE(float value1, float value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPCompareGE: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out _, out _, state);
- value2 = value2.FPUnpack(out FpType type2, out _, out _, state);
-
- float result;
-
- if (type1 == FpType.SNaN || type1 == FpType.QNaN || type2 == FpType.SNaN || type2 == FpType.QNaN)
- {
- result = ZerosOrOnes(false);
-
- FPProcessException(FpExc.InvalidOp, state);
- }
- else
- {
- result = ZerosOrOnes(value1 >= value2);
- }
-
- return result;
- }
-
- public static float FPCompareGT(float value1, float value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPCompareGT: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out _, out _, state);
- value2 = value2.FPUnpack(out FpType type2, out _, out _, state);
-
- float result;
-
- if (type1 == FpType.SNaN || type1 == FpType.QNaN || type2 == FpType.SNaN || type2 == FpType.QNaN)
- {
- result = ZerosOrOnes(false);
-
- FPProcessException(FpExc.InvalidOp, state);
- }
- else
- {
- result = ZerosOrOnes(value1 > value2);
- }
-
- return result;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float FPCompareLE(float value1, float value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPCompareLE: state.Fpcr = 0x{state.CFpcr:X8}");
-
- return FPCompareGE(value2, value1, state);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float FPCompareLT(float value1, float value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPCompareLT: state.Fpcr = 0x{state.CFpcr:X8}");
-
- return FPCompareGT(value2, value1, state);
- }
-
- public static float FPDiv(float value1, float value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPDiv: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out uint op1, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out uint op2, state);
-
- float result = FPProcessNaNs(type1, type2, op1, op2, out bool done, state);
-
- if (!done)
- {
- bool inf1 = type1 == FpType.Infinity; bool zero1 = type1 == FpType.Zero;
- bool inf2 = type2 == FpType.Infinity; bool zero2 = type2 == FpType.Zero;
-
- if ((inf1 && inf2) || (zero1 && zero2))
- {
- result = FPDefaultNaN();
-
- FPProcessException(FpExc.InvalidOp, state);
- }
- else if (inf1 || zero2)
- {
- result = FPInfinity(sign1 ^ sign2);
-
- if (!inf1)
- {
- FPProcessException(FpExc.DivideByZero, state);
- }
- }
- else if (zero1 || inf2)
- {
- result = FPZero(sign1 ^ sign2);
- }
- else
- {
- result = value1 / value2;
-
- if (state.GetFpcrFlag(Fpcr.Fz) && float.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0f);
- }
- }
- }
-
- return result;
- }
-
- public static float FPMax(float value1, float value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPMax: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out uint op1, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out uint op2, state);
-
- float result = FPProcessNaNs(type1, type2, op1, op2, out bool done, state);
-
- if (!done)
- {
- if (value1 > value2)
- {
- if (type1 == FpType.Infinity)
- {
- result = FPInfinity(sign1);
- }
- else if (type1 == FpType.Zero)
- {
- result = FPZero(sign1 && sign2);
- }
- else
- {
- result = value1;
- }
- }
- else
- {
- if (type2 == FpType.Infinity)
- {
- result = FPInfinity(sign2);
- }
- else if (type2 == FpType.Zero)
- {
- result = FPZero(sign1 && sign2);
- }
- else
- {
- result = value2;
-
- if (state.GetFpcrFlag(Fpcr.Fz) && float.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0f);
- }
- }
- }
- }
-
- return result;
- }
-
- public static float FPMaxNum(float value1, float value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPMaxNum: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1.FPUnpack(out FpType type1, out _, out _, state);
- value2.FPUnpack(out FpType type2, out _, out _, state);
-
- if (type1 == FpType.QNaN && type2 != FpType.QNaN)
- {
- value1 = FPInfinity(true);
- }
- else if (type1 != FpType.QNaN && type2 == FpType.QNaN)
- {
- value2 = FPInfinity(true);
- }
-
- return FPMax(value1, value2, state);
- }
-
- public static float FPMin(float value1, float value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPMin: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out uint op1, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out uint op2, state);
-
- float result = FPProcessNaNs(type1, type2, op1, op2, out bool done, state);
-
- if (!done)
- {
- if (value1 < value2)
- {
- if (type1 == FpType.Infinity)
- {
- result = FPInfinity(sign1);
- }
- else if (type1 == FpType.Zero)
- {
- result = FPZero(sign1 || sign2);
- }
- else
- {
- result = value1;
- }
- }
- else
- {
- if (type2 == FpType.Infinity)
- {
- result = FPInfinity(sign2);
- }
- else if (type2 == FpType.Zero)
- {
- result = FPZero(sign1 || sign2);
- }
- else
- {
- result = value2;
-
- if (state.GetFpcrFlag(Fpcr.Fz) && float.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0f);
- }
- }
- }
- }
-
- return result;
- }
-
- public static float FPMinNum(float value1, float value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPMinNum: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1.FPUnpack(out FpType type1, out _, out _, state);
- value2.FPUnpack(out FpType type2, out _, out _, state);
-
- if (type1 == FpType.QNaN && type2 != FpType.QNaN)
- {
- value1 = FPInfinity(false);
- }
- else if (type1 != FpType.QNaN && type2 == FpType.QNaN)
- {
- value2 = FPInfinity(false);
- }
-
- return FPMin(value1, value2, state);
- }
-
- public static float FPMul(float value1, float value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPMul: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out uint op1, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out uint op2, state);
-
- float result = FPProcessNaNs(type1, type2, op1, op2, out bool done, state);
-
- if (!done)
- {
- bool inf1 = type1 == FpType.Infinity; bool zero1 = type1 == FpType.Zero;
- bool inf2 = type2 == FpType.Infinity; bool zero2 = type2 == FpType.Zero;
-
- if ((inf1 && zero2) || (zero1 && inf2))
- {
- result = FPDefaultNaN();
-
- FPProcessException(FpExc.InvalidOp, state);
- }
- else if (inf1 || inf2)
- {
- result = FPInfinity(sign1 ^ sign2);
- }
- else if (zero1 || zero2)
- {
- result = FPZero(sign1 ^ sign2);
- }
- else
- {
- result = value1 * value2;
-
- if (state.GetFpcrFlag(Fpcr.Fz) && float.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0f);
- }
- }
- }
-
- return result;
- }
-
- public static float FPMulAdd(
- float valueA,
- float value1,
- float value2,
- CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPMulAdd: state.Fpcr = 0x{state.CFpcr:X8}");
-
- valueA = valueA.FPUnpack(out FpType typeA, out bool signA, out uint addend, state);
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out uint op1, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out uint op2, state);
-
- bool inf1 = type1 == FpType.Infinity; bool zero1 = type1 == FpType.Zero;
- bool inf2 = type2 == FpType.Infinity; bool zero2 = type2 == FpType.Zero;
-
- float result = FPProcessNaNs3(typeA, type1, type2, addend, op1, op2, out bool done, state);
-
- if (typeA == FpType.QNaN && ((inf1 && zero2) || (zero1 && inf2)))
- {
- result = FPDefaultNaN();
-
- FPProcessException(FpExc.InvalidOp, state);
- }
-
- if (!done)
- {
- bool infA = typeA == FpType.Infinity; bool zeroA = typeA == FpType.Zero;
-
- bool signP = sign1 ^ sign2;
- bool infP = inf1 || inf2;
- bool zeroP = zero1 || zero2;
-
- if ((inf1 && zero2) || (zero1 && inf2) || (infA && infP && signA != signP))
- {
- result = FPDefaultNaN();
-
- FPProcessException(FpExc.InvalidOp, state);
- }
- else if ((infA && !signA) || (infP && !signP))
- {
- result = FPInfinity(false);
- }
- else if ((infA && signA) || (infP && signP))
- {
- result = FPInfinity(true);
- }
- else if (zeroA && zeroP && signA == signP)
- {
- result = FPZero(signA);
- }
- else
- {
- // TODO: When available, use: T MathF.FusedMultiplyAdd(T, T, T);
- // https://github.com/dotnet/corefx/issues/31903
-
- result = valueA + (value1 * value2);
-
- if (state.GetFpcrFlag(Fpcr.Fz) && float.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0f);
- }
- }
- }
-
- return result;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float FPMulSub(
- float valueA,
- float value1,
- float value2,
- CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPMulSub: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPNeg();
-
- return FPMulAdd(valueA, value1, value2, state);
- }
-
- public static float FPMulX(float value1, float value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPMulX: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out uint op1, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out uint op2, state);
-
- float result = FPProcessNaNs(type1, type2, op1, op2, out bool done, state);
-
- if (!done)
- {
- bool inf1 = type1 == FpType.Infinity; bool zero1 = type1 == FpType.Zero;
- bool inf2 = type2 == FpType.Infinity; bool zero2 = type2 == FpType.Zero;
-
- if ((inf1 && zero2) || (zero1 && inf2))
- {
- result = FPTwo(sign1 ^ sign2);
- }
- else if (inf1 || inf2)
- {
- result = FPInfinity(sign1 ^ sign2);
- }
- else if (zero1 || zero2)
- {
- result = FPZero(sign1 ^ sign2);
- }
- else
- {
- result = value1 * value2;
-
- if (state.GetFpcrFlag(Fpcr.Fz) && float.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0f);
- }
- }
- }
-
- return result;
- }
-
- public static float FPRecipEstimate(float value, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPRecipEstimate: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value.FPUnpack(out FpType type, out bool sign, out uint op, state);
-
- float result;
-
- if (type == FpType.SNaN || type == FpType.QNaN)
- {
- result = FPProcessNaN(type, op, state);
- }
- else if (type == FpType.Infinity)
- {
- result = FPZero(sign);
- }
- else if (type == FpType.Zero)
- {
- result = FPInfinity(sign);
-
- FPProcessException(FpExc.DivideByZero, state);
- }
- else if (MathF.Abs(value) < MathF.Pow(2f, -128))
- {
- bool overflowToInf;
-
- switch (state.FPRoundingMode())
- {
- default:
- case RoundMode.ToNearest: overflowToInf = true; break;
- case RoundMode.TowardsPlusInfinity: overflowToInf = !sign; break;
- case RoundMode.TowardsMinusInfinity: overflowToInf = sign; break;
- case RoundMode.TowardsZero: overflowToInf = false; break;
- }
-
- result = overflowToInf ? FPInfinity(sign) : FPMaxNormal(sign);
-
- FPProcessException(FpExc.Overflow, state);
- FPProcessException(FpExc.Inexact, state);
- }
- else if (state.GetFpcrFlag(Fpcr.Fz) && (MathF.Abs(value) >= MathF.Pow(2f, 126)))
- {
- result = FPZero(sign);
-
- state.SetFpsrFlag(Fpsr.Ufc);
- }
- else
- {
- ulong fraction = (ulong)(op & 0x007FFFFFu) << 29;
- uint exp = (op & 0x7F800000u) >> 23;
-
- if (exp == 0u)
- {
- if ((fraction & 0x0008000000000000ul) == 0ul)
- {
- fraction = (fraction & 0x0003FFFFFFFFFFFFul) << 2;
- exp -= 1u;
- }
- else
- {
- fraction = (fraction & 0x0007FFFFFFFFFFFFul) << 1;
- }
- }
-
- uint scaled = (uint)(((fraction & 0x000FF00000000000ul) | 0x0010000000000000ul) >> 44);
-
- uint resultExp = 253u - exp;
-
- uint estimate = (uint)SoftFloat.RecipEstimateTable[scaled - 256u] + 256u;
-
- fraction = (ulong)(estimate & 0xFFu) << 44;
-
- if (resultExp == 0u)
- {
- fraction = ((fraction & 0x000FFFFFFFFFFFFEul) | 0x0010000000000000ul) >> 1;
- }
- else if (resultExp + 1u == 0u)
- {
- fraction = ((fraction & 0x000FFFFFFFFFFFFCul) | 0x0010000000000000ul) >> 2;
- resultExp = 0u;
- }
-
- result = BitConverter.Int32BitsToSingle(
- (int)((sign ? 1u : 0u) << 31 | (resultExp & 0xFFu) << 23 | (uint)(fraction >> 29) & 0x007FFFFFu));
- }
-
- return result;
- }
-
- public static float FPRecipStepFused(float value1, float value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPRecipStepFused: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPNeg();
-
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out uint op1, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out uint op2, state);
-
- float result = FPProcessNaNs(type1, type2, op1, op2, out bool done, state);
-
- if (!done)
- {
- bool inf1 = type1 == FpType.Infinity; bool zero1 = type1 == FpType.Zero;
- bool inf2 = type2 == FpType.Infinity; bool zero2 = type2 == FpType.Zero;
-
- if ((inf1 && zero2) || (zero1 && inf2))
- {
- result = FPTwo(false);
- }
- else if (inf1 || inf2)
- {
- result = FPInfinity(sign1 ^ sign2);
- }
- else
- {
- // TODO: When available, use: T MathF.FusedMultiplyAdd(T, T, T);
- // https://github.com/dotnet/corefx/issues/31903
-
- result = 2f + (value1 * value2);
-
- if (state.GetFpcrFlag(Fpcr.Fz) && float.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0f);
- }
- }
- }
-
- return result;
- }
-
- public static float FPRecpX(float value, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPRecpX: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value.FPUnpack(out FpType type, out bool sign, out uint op, state);
-
- float result;
-
- if (type == FpType.SNaN || type == FpType.QNaN)
- {
- result = FPProcessNaN(type, op, state);
- }
- else
- {
- uint notExp = (~op >> 23) & 0xFFu;
- uint maxExp = 0xFEu;
-
- result = BitConverter.Int32BitsToSingle(
- (int)((sign ? 1u : 0u) << 31 | (notExp == 0xFFu ? maxExp : notExp) << 23));
- }
-
- return result;
- }
-
- public static float FPRSqrtEstimate(float value, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPRSqrtEstimate: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value.FPUnpack(out FpType type, out bool sign, out uint op, state);
-
- float result;
-
- if (type == FpType.SNaN || type == FpType.QNaN)
- {
- result = FPProcessNaN(type, op, state);
- }
- else if (type == FpType.Zero)
- {
- result = FPInfinity(sign);
-
- FPProcessException(FpExc.DivideByZero, state);
- }
- else if (sign)
- {
- result = FPDefaultNaN();
-
- FPProcessException(FpExc.InvalidOp, state);
- }
- else if (type == FpType.Infinity)
- {
- result = FPZero(false);
- }
- else
- {
- ulong fraction = (ulong)(op & 0x007FFFFFu) << 29;
- uint exp = (op & 0x7F800000u) >> 23;
-
- if (exp == 0u)
- {
- while ((fraction & 0x0008000000000000ul) == 0ul)
- {
- fraction = (fraction & 0x0007FFFFFFFFFFFFul) << 1;
- exp -= 1u;
- }
-
- fraction = (fraction & 0x0007FFFFFFFFFFFFul) << 1;
- }
-
- uint scaled;
-
- if ((exp & 1u) == 0u)
- {
- scaled = (uint)(((fraction & 0x000FF00000000000ul) | 0x0010000000000000ul) >> 44);
- }
- else
- {
- scaled = (uint)(((fraction & 0x000FE00000000000ul) | 0x0010000000000000ul) >> 45);
- }
-
- uint resultExp = (380u - exp) >> 1;
-
- uint estimate = (uint)SoftFloat.RecipSqrtEstimateTable[scaled - 128u] + 256u;
-
- result = BitConverter.Int32BitsToSingle((int)((resultExp & 0xFFu) << 23 | (estimate & 0xFFu) << 15));
- }
-
- return result;
- }
-
- public static float FPRSqrtStepFused(float value1, float value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPRSqrtStepFused: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPNeg();
-
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out uint op1, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out uint op2, state);
-
- float result = FPProcessNaNs(type1, type2, op1, op2, out bool done, state);
-
- if (!done)
- {
- bool inf1 = type1 == FpType.Infinity; bool zero1 = type1 == FpType.Zero;
- bool inf2 = type2 == FpType.Infinity; bool zero2 = type2 == FpType.Zero;
-
- if ((inf1 && zero2) || (zero1 && inf2))
- {
- result = FPOnePointFive(false);
- }
- else if (inf1 || inf2)
- {
- result = FPInfinity(sign1 ^ sign2);
- }
- else
- {
- // TODO: When available, use: T MathF.FusedMultiplyAdd(T, T, T);
- // https://github.com/dotnet/corefx/issues/31903
-
- result = (3f + (value1 * value2)) / 2f;
-
- if (state.GetFpcrFlag(Fpcr.Fz) && float.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0f);
- }
- }
- }
-
- return result;
- }
-
- public static float FPSqrt(float value, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPSqrt: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value = value.FPUnpack(out FpType type, out bool sign, out uint op, state);
-
- float result;
-
- if (type == FpType.SNaN || type == FpType.QNaN)
- {
- result = FPProcessNaN(type, op, state);
- }
- else if (type == FpType.Zero)
- {
- result = FPZero(sign);
- }
- else if (type == FpType.Infinity && !sign)
- {
- result = FPInfinity(sign);
- }
- else if (sign)
- {
- result = FPDefaultNaN();
-
- FPProcessException(FpExc.InvalidOp, state);
- }
- else
- {
- result = MathF.Sqrt(value);
-
- if (state.GetFpcrFlag(Fpcr.Fz) && float.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0f);
- }
- }
-
- return result;
- }
-
- public static float FPSub(float value1, float value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPSub: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out uint op1, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out uint op2, state);
-
- float result = FPProcessNaNs(type1, type2, op1, op2, out bool done, state);
-
- if (!done)
- {
- bool inf1 = type1 == FpType.Infinity; bool zero1 = type1 == FpType.Zero;
- bool inf2 = type2 == FpType.Infinity; bool zero2 = type2 == FpType.Zero;
-
- if (inf1 && inf2 && sign1 == sign2)
- {
- result = FPDefaultNaN();
-
- FPProcessException(FpExc.InvalidOp, state);
- }
- else if ((inf1 && !sign1) || (inf2 && sign2))
- {
- result = FPInfinity(false);
- }
- else if ((inf1 && sign1) || (inf2 && !sign2))
- {
- result = FPInfinity(true);
- }
- else if (zero1 && zero2 && sign1 == !sign2)
- {
- result = FPZero(sign1);
- }
- else
- {
- result = value1 - value2;
-
- if (state.GetFpcrFlag(Fpcr.Fz) && float.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0f);
- }
- }
- }
-
- return result;
- }
-
- private static float FPDefaultNaN()
- {
- return -float.NaN;
- }
-
- private static float FPInfinity(bool sign)
- {
- return sign ? float.NegativeInfinity : float.PositiveInfinity;
- }
-
- private static float FPZero(bool sign)
- {
- return sign ? -0f : +0f;
- }
-
- private static float FPMaxNormal(bool sign)
- {
- return sign ? float.MinValue : float.MaxValue;
- }
-
- private static float FPTwo(bool sign)
- {
- return sign ? -2f : +2f;
- }
-
- private static float FPOnePointFive(bool sign)
- {
- return sign ? -1.5f : +1.5f;
- }
-
- private static float FPNeg(this float value)
- {
- return -value;
- }
-
- private static float ZerosOrOnes(bool ones)
- {
- return BitConverter.Int32BitsToSingle(ones ? -1 : 0);
- }
-
- private static float FPUnpack(
- this float value,
- out FpType type,
- out bool sign,
- out uint valueBits,
- CpuThreadState state)
- {
- valueBits = (uint)BitConverter.SingleToInt32Bits(value);
-
- sign = (~valueBits & 0x80000000u) == 0u;
-
- if ((valueBits & 0x7F800000u) == 0u)
- {
- if ((valueBits & 0x007FFFFFu) == 0u || state.GetFpcrFlag(Fpcr.Fz))
- {
- type = FpType.Zero;
- value = FPZero(sign);
-
- if ((valueBits & 0x007FFFFFu) != 0u)
- {
- FPProcessException(FpExc.InputDenorm, state);
- }
- }
- else
- {
- type = FpType.Nonzero;
- }
- }
- else if ((~valueBits & 0x7F800000u) == 0u)
- {
- if ((valueBits & 0x007FFFFFu) == 0u)
- {
- type = FpType.Infinity;
- }
- else
- {
- type = (~valueBits & 0x00400000u) == 0u ? FpType.QNaN : FpType.SNaN;
- value = FPZero(sign);
- }
- }
- else
- {
- type = FpType.Nonzero;
- }
-
- return value;
- }
-
- private static float FPProcessNaNs(
- FpType type1,
- FpType type2,
- uint op1,
- uint op2,
- out bool done,
- CpuThreadState state)
- {
- done = true;
-
- if (type1 == FpType.SNaN)
- {
- return FPProcessNaN(type1, op1, state);
- }
- else if (type2 == FpType.SNaN)
- {
- return FPProcessNaN(type2, op2, state);
- }
- else if (type1 == FpType.QNaN)
- {
- return FPProcessNaN(type1, op1, state);
- }
- else if (type2 == FpType.QNaN)
- {
- return FPProcessNaN(type2, op2, state);
- }
-
- done = false;
-
- return FPZero(false);
- }
-
- private static float FPProcessNaNs3(
- FpType type1,
- FpType type2,
- FpType type3,
- uint op1,
- uint op2,
- uint op3,
- out bool done,
- CpuThreadState state)
- {
- done = true;
-
- if (type1 == FpType.SNaN)
- {
- return FPProcessNaN(type1, op1, state);
- }
- else if (type2 == FpType.SNaN)
- {
- return FPProcessNaN(type2, op2, state);
- }
- else if (type3 == FpType.SNaN)
- {
- return FPProcessNaN(type3, op3, state);
- }
- else if (type1 == FpType.QNaN)
- {
- return FPProcessNaN(type1, op1, state);
- }
- else if (type2 == FpType.QNaN)
- {
- return FPProcessNaN(type2, op2, state);
- }
- else if (type3 == FpType.QNaN)
- {
- return FPProcessNaN(type3, op3, state);
- }
-
- done = false;
-
- return FPZero(false);
- }
-
- private static float FPProcessNaN(FpType type, uint op, CpuThreadState state)
- {
- if (type == FpType.SNaN)
- {
- op |= 1u << 22;
-
- FPProcessException(FpExc.InvalidOp, state);
- }
-
- if (state.GetFpcrFlag(Fpcr.Dn))
- {
- return FPDefaultNaN();
- }
-
- return BitConverter.Int32BitsToSingle((int)op);
- }
-
- private static void FPProcessException(FpExc exc, CpuThreadState state)
- {
- int enable = (int)exc + 8;
-
- if ((state.CFpcr & (1 << enable)) != 0)
- {
- throw new NotImplementedException("Floating-point trap handling.");
- }
- else
- {
- state.CFpsr |= 1 << (int)exc;
- }
- }
- }
-
- static class SoftFloat64
- {
- public static double FPAdd(double value1, double value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPAdd: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out ulong op1, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out ulong op2, state);
-
- double result = FPProcessNaNs(type1, type2, op1, op2, out bool done, state);
-
- if (!done)
- {
- bool inf1 = type1 == FpType.Infinity; bool zero1 = type1 == FpType.Zero;
- bool inf2 = type2 == FpType.Infinity; bool zero2 = type2 == FpType.Zero;
-
- if (inf1 && inf2 && sign1 == !sign2)
- {
- result = FPDefaultNaN();
-
- FPProcessException(FpExc.InvalidOp, state);
- }
- else if ((inf1 && !sign1) || (inf2 && !sign2))
- {
- result = FPInfinity(false);
- }
- else if ((inf1 && sign1) || (inf2 && sign2))
- {
- result = FPInfinity(true);
- }
- else if (zero1 && zero2 && sign1 == sign2)
- {
- result = FPZero(sign1);
- }
- else
- {
- result = value1 + value2;
-
- if (state.GetFpcrFlag(Fpcr.Fz) && double.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0d);
- }
- }
- }
-
- return result;
- }
-
- public static int FPCompare(double value1, double value2, bool signalNaNs, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPCompare: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out _, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out _, state);
-
- int result;
-
- if (type1 == FpType.SNaN || type1 == FpType.QNaN || type2 == FpType.SNaN || type2 == FpType.QNaN)
- {
- result = 0b0011;
-
- if (type1 == FpType.SNaN || type2 == FpType.SNaN || signalNaNs)
- {
- FPProcessException(FpExc.InvalidOp, state);
- }
- }
- else
- {
- if (value1 == value2)
- {
- result = 0b0110;
- }
- else if (value1 < value2)
- {
- result = 0b1000;
- }
- else
- {
- result = 0b0010;
- }
- }
-
- return result;
- }
-
- public static double FPCompareEQ(double value1, double value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPCompareEQ: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out _, out _, state);
- value2 = value2.FPUnpack(out FpType type2, out _, out _, state);
-
- double result;
-
- if (type1 == FpType.SNaN || type1 == FpType.QNaN || type2 == FpType.SNaN || type2 == FpType.QNaN)
- {
- result = ZerosOrOnes(false);
-
- if (type1 == FpType.SNaN || type2 == FpType.SNaN)
- {
- FPProcessException(FpExc.InvalidOp, state);
- }
- }
- else
- {
- result = ZerosOrOnes(value1 == value2);
- }
-
- return result;
- }
-
- public static double FPCompareGE(double value1, double value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPCompareGE: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out _, out _, state);
- value2 = value2.FPUnpack(out FpType type2, out _, out _, state);
-
- double result;
-
- if (type1 == FpType.SNaN || type1 == FpType.QNaN || type2 == FpType.SNaN || type2 == FpType.QNaN)
- {
- result = ZerosOrOnes(false);
-
- FPProcessException(FpExc.InvalidOp, state);
- }
- else
- {
- result = ZerosOrOnes(value1 >= value2);
- }
-
- return result;
- }
-
- public static double FPCompareGT(double value1, double value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPCompareGT: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out _, out _, state);
- value2 = value2.FPUnpack(out FpType type2, out _, out _, state);
-
- double result;
-
- if (type1 == FpType.SNaN || type1 == FpType.QNaN || type2 == FpType.SNaN || type2 == FpType.QNaN)
- {
- result = ZerosOrOnes(false);
-
- FPProcessException(FpExc.InvalidOp, state);
- }
- else
- {
- result = ZerosOrOnes(value1 > value2);
- }
-
- return result;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double FPCompareLE(double value1, double value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPCompareLE: state.Fpcr = 0x{state.CFpcr:X8}");
-
- return FPCompareGE(value2, value1, state);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double FPCompareLT(double value1, double value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPCompareLT: state.Fpcr = 0x{state.CFpcr:X8}");
-
- return FPCompareGT(value2, value1, state);
- }
-
- public static double FPDiv(double value1, double value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPDiv: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out ulong op1, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out ulong op2, state);
-
- double result = FPProcessNaNs(type1, type2, op1, op2, out bool done, state);
-
- if (!done)
- {
- bool inf1 = type1 == FpType.Infinity; bool zero1 = type1 == FpType.Zero;
- bool inf2 = type2 == FpType.Infinity; bool zero2 = type2 == FpType.Zero;
-
- if ((inf1 && inf2) || (zero1 && zero2))
- {
- result = FPDefaultNaN();
-
- FPProcessException(FpExc.InvalidOp, state);
- }
- else if (inf1 || zero2)
- {
- result = FPInfinity(sign1 ^ sign2);
-
- if (!inf1)
- {
- FPProcessException(FpExc.DivideByZero, state);
- }
- }
- else if (zero1 || inf2)
- {
- result = FPZero(sign1 ^ sign2);
- }
- else
- {
- result = value1 / value2;
-
- if (state.GetFpcrFlag(Fpcr.Fz) && double.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0d);
- }
- }
- }
-
- return result;
- }
-
- public static double FPMax(double value1, double value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPMax: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out ulong op1, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out ulong op2, state);
-
- double result = FPProcessNaNs(type1, type2, op1, op2, out bool done, state);
-
- if (!done)
- {
- if (value1 > value2)
- {
- if (type1 == FpType.Infinity)
- {
- result = FPInfinity(sign1);
- }
- else if (type1 == FpType.Zero)
- {
- result = FPZero(sign1 && sign2);
- }
- else
- {
- result = value1;
- }
- }
- else
- {
- if (type2 == FpType.Infinity)
- {
- result = FPInfinity(sign2);
- }
- else if (type2 == FpType.Zero)
- {
- result = FPZero(sign1 && sign2);
- }
- else
- {
- result = value2;
-
- if (state.GetFpcrFlag(Fpcr.Fz) && double.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0d);
- }
- }
- }
- }
-
- return result;
- }
-
- public static double FPMaxNum(double value1, double value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPMaxNum: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1.FPUnpack(out FpType type1, out _, out _, state);
- value2.FPUnpack(out FpType type2, out _, out _, state);
-
- if (type1 == FpType.QNaN && type2 != FpType.QNaN)
- {
- value1 = FPInfinity(true);
- }
- else if (type1 != FpType.QNaN && type2 == FpType.QNaN)
- {
- value2 = FPInfinity(true);
- }
-
- return FPMax(value1, value2, state);
- }
-
- public static double FPMin(double value1, double value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPMin: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out ulong op1, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out ulong op2, state);
-
- double result = FPProcessNaNs(type1, type2, op1, op2, out bool done, state);
-
- if (!done)
- {
- if (value1 < value2)
- {
- if (type1 == FpType.Infinity)
- {
- result = FPInfinity(sign1);
- }
- else if (type1 == FpType.Zero)
- {
- result = FPZero(sign1 || sign2);
- }
- else
- {
- result = value1;
- }
- }
- else
- {
- if (type2 == FpType.Infinity)
- {
- result = FPInfinity(sign2);
- }
- else if (type2 == FpType.Zero)
- {
- result = FPZero(sign1 || sign2);
- }
- else
- {
- result = value2;
-
- if (state.GetFpcrFlag(Fpcr.Fz) && double.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0d);
- }
- }
- }
- }
-
- return result;
- }
-
- public static double FPMinNum(double value1, double value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPMinNum: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1.FPUnpack(out FpType type1, out _, out _, state);
- value2.FPUnpack(out FpType type2, out _, out _, state);
-
- if (type1 == FpType.QNaN && type2 != FpType.QNaN)
- {
- value1 = FPInfinity(false);
- }
- else if (type1 != FpType.QNaN && type2 == FpType.QNaN)
- {
- value2 = FPInfinity(false);
- }
-
- return FPMin(value1, value2, state);
- }
-
- public static double FPMul(double value1, double value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPMul: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out ulong op1, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out ulong op2, state);
-
- double result = FPProcessNaNs(type1, type2, op1, op2, out bool done, state);
-
- if (!done)
- {
- bool inf1 = type1 == FpType.Infinity; bool zero1 = type1 == FpType.Zero;
- bool inf2 = type2 == FpType.Infinity; bool zero2 = type2 == FpType.Zero;
-
- if ((inf1 && zero2) || (zero1 && inf2))
- {
- result = FPDefaultNaN();
-
- FPProcessException(FpExc.InvalidOp, state);
- }
- else if (inf1 || inf2)
- {
- result = FPInfinity(sign1 ^ sign2);
- }
- else if (zero1 || zero2)
- {
- result = FPZero(sign1 ^ sign2);
- }
- else
- {
- result = value1 * value2;
-
- if (state.GetFpcrFlag(Fpcr.Fz) && double.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0d);
- }
- }
- }
-
- return result;
- }
-
- public static double FPMulAdd(
- double valueA,
- double value1,
- double value2,
- CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPMulAdd: state.Fpcr = 0x{state.CFpcr:X8}");
-
- valueA = valueA.FPUnpack(out FpType typeA, out bool signA, out ulong addend, state);
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out ulong op1, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out ulong op2, state);
-
- bool inf1 = type1 == FpType.Infinity; bool zero1 = type1 == FpType.Zero;
- bool inf2 = type2 == FpType.Infinity; bool zero2 = type2 == FpType.Zero;
-
- double result = FPProcessNaNs3(typeA, type1, type2, addend, op1, op2, out bool done, state);
-
- if (typeA == FpType.QNaN && ((inf1 && zero2) || (zero1 && inf2)))
- {
- result = FPDefaultNaN();
-
- FPProcessException(FpExc.InvalidOp, state);
- }
-
- if (!done)
- {
- bool infA = typeA == FpType.Infinity; bool zeroA = typeA == FpType.Zero;
-
- bool signP = sign1 ^ sign2;
- bool infP = inf1 || inf2;
- bool zeroP = zero1 || zero2;
-
- if ((inf1 && zero2) || (zero1 && inf2) || (infA && infP && signA != signP))
- {
- result = FPDefaultNaN();
-
- FPProcessException(FpExc.InvalidOp, state);
- }
- else if ((infA && !signA) || (infP && !signP))
- {
- result = FPInfinity(false);
- }
- else if ((infA && signA) || (infP && signP))
- {
- result = FPInfinity(true);
- }
- else if (zeroA && zeroP && signA == signP)
- {
- result = FPZero(signA);
- }
- else
- {
- // TODO: When available, use: T Math.FusedMultiplyAdd(T, T, T);
- // https://github.com/dotnet/corefx/issues/31903
-
- result = valueA + (value1 * value2);
-
- if (state.GetFpcrFlag(Fpcr.Fz) && double.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0d);
- }
- }
- }
-
- return result;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double FPMulSub(
- double valueA,
- double value1,
- double value2,
- CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPMulSub: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPNeg();
-
- return FPMulAdd(valueA, value1, value2, state);
- }
-
- public static double FPMulX(double value1, double value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPMulX: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out ulong op1, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out ulong op2, state);
-
- double result = FPProcessNaNs(type1, type2, op1, op2, out bool done, state);
-
- if (!done)
- {
- bool inf1 = type1 == FpType.Infinity; bool zero1 = type1 == FpType.Zero;
- bool inf2 = type2 == FpType.Infinity; bool zero2 = type2 == FpType.Zero;
-
- if ((inf1 && zero2) || (zero1 && inf2))
- {
- result = FPTwo(sign1 ^ sign2);
- }
- else if (inf1 || inf2)
- {
- result = FPInfinity(sign1 ^ sign2);
- }
- else if (zero1 || zero2)
- {
- result = FPZero(sign1 ^ sign2);
- }
- else
- {
- result = value1 * value2;
-
- if (state.GetFpcrFlag(Fpcr.Fz) && double.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0d);
- }
- }
- }
-
- return result;
- }
-
- public static double FPRecipEstimate(double value, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPRecipEstimate: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value.FPUnpack(out FpType type, out bool sign, out ulong op, state);
-
- double result;
-
- if (type == FpType.SNaN || type == FpType.QNaN)
- {
- result = FPProcessNaN(type, op, state);
- }
- else if (type == FpType.Infinity)
- {
- result = FPZero(sign);
- }
- else if (type == FpType.Zero)
- {
- result = FPInfinity(sign);
-
- FPProcessException(FpExc.DivideByZero, state);
- }
- else if (Math.Abs(value) < Math.Pow(2d, -1024))
- {
- bool overflowToInf;
-
- switch (state.FPRoundingMode())
- {
- default:
- case RoundMode.ToNearest: overflowToInf = true; break;
- case RoundMode.TowardsPlusInfinity: overflowToInf = !sign; break;
- case RoundMode.TowardsMinusInfinity: overflowToInf = sign; break;
- case RoundMode.TowardsZero: overflowToInf = false; break;
- }
-
- result = overflowToInf ? FPInfinity(sign) : FPMaxNormal(sign);
-
- FPProcessException(FpExc.Overflow, state);
- FPProcessException(FpExc.Inexact, state);
- }
- else if (state.GetFpcrFlag(Fpcr.Fz) && (Math.Abs(value) >= Math.Pow(2d, 1022)))
- {
- result = FPZero(sign);
-
- state.SetFpsrFlag(Fpsr.Ufc);
- }
- else
- {
- ulong fraction = op & 0x000FFFFFFFFFFFFFul;
- uint exp = (uint)((op & 0x7FF0000000000000ul) >> 52);
-
- if (exp == 0u)
- {
- if ((fraction & 0x0008000000000000ul) == 0ul)
- {
- fraction = (fraction & 0x0003FFFFFFFFFFFFul) << 2;
- exp -= 1u;
- }
- else
- {
- fraction = (fraction & 0x0007FFFFFFFFFFFFul) << 1;
- }
- }
-
- uint scaled = (uint)(((fraction & 0x000FF00000000000ul) | 0x0010000000000000ul) >> 44);
-
- uint resultExp = 2045u - exp;
-
- uint estimate = (uint)SoftFloat.RecipEstimateTable[scaled - 256u] + 256u;
-
- fraction = (ulong)(estimate & 0xFFu) << 44;
-
- if (resultExp == 0u)
- {
- fraction = ((fraction & 0x000FFFFFFFFFFFFEul) | 0x0010000000000000ul) >> 1;
- }
- else if (resultExp + 1u == 0u)
- {
- fraction = ((fraction & 0x000FFFFFFFFFFFFCul) | 0x0010000000000000ul) >> 2;
- resultExp = 0u;
- }
-
- result = BitConverter.Int64BitsToDouble(
- (long)((sign ? 1ul : 0ul) << 63 | (resultExp & 0x7FFul) << 52 | (fraction & 0x000FFFFFFFFFFFFFul)));
- }
-
- return result;
- }
-
- public static double FPRecipStepFused(double value1, double value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPRecipStepFused: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPNeg();
-
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out ulong op1, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out ulong op2, state);
-
- double result = FPProcessNaNs(type1, type2, op1, op2, out bool done, state);
-
- if (!done)
- {
- bool inf1 = type1 == FpType.Infinity; bool zero1 = type1 == FpType.Zero;
- bool inf2 = type2 == FpType.Infinity; bool zero2 = type2 == FpType.Zero;
-
- if ((inf1 && zero2) || (zero1 && inf2))
- {
- result = FPTwo(false);
- }
- else if (inf1 || inf2)
- {
- result = FPInfinity(sign1 ^ sign2);
- }
- else
- {
- // TODO: When available, use: T Math.FusedMultiplyAdd(T, T, T);
- // https://github.com/dotnet/corefx/issues/31903
-
- result = 2d + (value1 * value2);
-
- if (state.GetFpcrFlag(Fpcr.Fz) && double.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0d);
- }
- }
- }
-
- return result;
- }
-
- public static double FPRecpX(double value, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPRecpX: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value.FPUnpack(out FpType type, out bool sign, out ulong op, state);
-
- double result;
-
- if (type == FpType.SNaN || type == FpType.QNaN)
- {
- result = FPProcessNaN(type, op, state);
- }
- else
- {
- ulong notExp = (~op >> 52) & 0x7FFul;
- ulong maxExp = 0x7FEul;
-
- result = BitConverter.Int64BitsToDouble(
- (long)((sign ? 1ul : 0ul) << 63 | (notExp == 0x7FFul ? maxExp : notExp) << 52));
- }
-
- return result;
- }
-
- public static double FPRSqrtEstimate(double value, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPRSqrtEstimate: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value.FPUnpack(out FpType type, out bool sign, out ulong op, state);
-
- double result;
-
- if (type == FpType.SNaN || type == FpType.QNaN)
- {
- result = FPProcessNaN(type, op, state);
- }
- else if (type == FpType.Zero)
- {
- result = FPInfinity(sign);
-
- FPProcessException(FpExc.DivideByZero, state);
- }
- else if (sign)
- {
- result = FPDefaultNaN();
-
- FPProcessException(FpExc.InvalidOp, state);
- }
- else if (type == FpType.Infinity)
- {
- result = FPZero(false);
- }
- else
- {
- ulong fraction = op & 0x000FFFFFFFFFFFFFul;
- uint exp = (uint)((op & 0x7FF0000000000000ul) >> 52);
-
- if (exp == 0u)
- {
- while ((fraction & 0x0008000000000000ul) == 0ul)
- {
- fraction = (fraction & 0x0007FFFFFFFFFFFFul) << 1;
- exp -= 1u;
- }
-
- fraction = (fraction & 0x0007FFFFFFFFFFFFul) << 1;
- }
-
- uint scaled;
-
- if ((exp & 1u) == 0u)
- {
- scaled = (uint)(((fraction & 0x000FF00000000000ul) | 0x0010000000000000ul) >> 44);
- }
- else
- {
- scaled = (uint)(((fraction & 0x000FE00000000000ul) | 0x0010000000000000ul) >> 45);
- }
-
- uint resultExp = (3068u - exp) >> 1;
-
- uint estimate = (uint)SoftFloat.RecipSqrtEstimateTable[scaled - 128u] + 256u;
-
- result = BitConverter.Int64BitsToDouble((long)((resultExp & 0x7FFul) << 52 | (estimate & 0xFFul) << 44));
- }
-
- return result;
- }
-
- public static double FPRSqrtStepFused(double value1, double value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPRSqrtStepFused: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPNeg();
-
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out ulong op1, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out ulong op2, state);
-
- double result = FPProcessNaNs(type1, type2, op1, op2, out bool done, state);
-
- if (!done)
- {
- bool inf1 = type1 == FpType.Infinity; bool zero1 = type1 == FpType.Zero;
- bool inf2 = type2 == FpType.Infinity; bool zero2 = type2 == FpType.Zero;
-
- if ((inf1 && zero2) || (zero1 && inf2))
- {
- result = FPOnePointFive(false);
- }
- else if (inf1 || inf2)
- {
- result = FPInfinity(sign1 ^ sign2);
- }
- else
- {
- // TODO: When available, use: T Math.FusedMultiplyAdd(T, T, T);
- // https://github.com/dotnet/corefx/issues/31903
-
- result = (3d + (value1 * value2)) / 2d;
-
- if (state.GetFpcrFlag(Fpcr.Fz) && double.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0d);
- }
- }
- }
-
- return result;
- }
-
- public static double FPSqrt(double value, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPSqrt: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value = value.FPUnpack(out FpType type, out bool sign, out ulong op, state);
-
- double result;
-
- if (type == FpType.SNaN || type == FpType.QNaN)
- {
- result = FPProcessNaN(type, op, state);
- }
- else if (type == FpType.Zero)
- {
- result = FPZero(sign);
- }
- else if (type == FpType.Infinity && !sign)
- {
- result = FPInfinity(sign);
- }
- else if (sign)
- {
- result = FPDefaultNaN();
-
- FPProcessException(FpExc.InvalidOp, state);
- }
- else
- {
- result = Math.Sqrt(value);
-
- if (state.GetFpcrFlag(Fpcr.Fz) && double.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0d);
- }
- }
-
- return result;
- }
-
- public static double FPSub(double value1, double value2, CpuThreadState state)
- {
- Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPSub: state.Fpcr = 0x{state.CFpcr:X8}");
-
- value1 = value1.FPUnpack(out FpType type1, out bool sign1, out ulong op1, state);
- value2 = value2.FPUnpack(out FpType type2, out bool sign2, out ulong op2, state);
-
- double result = FPProcessNaNs(type1, type2, op1, op2, out bool done, state);
-
- if (!done)
- {
- bool inf1 = type1 == FpType.Infinity; bool zero1 = type1 == FpType.Zero;
- bool inf2 = type2 == FpType.Infinity; bool zero2 = type2 == FpType.Zero;
-
- if (inf1 && inf2 && sign1 == sign2)
- {
- result = FPDefaultNaN();
-
- FPProcessException(FpExc.InvalidOp, state);
- }
- else if ((inf1 && !sign1) || (inf2 && sign2))
- {
- result = FPInfinity(false);
- }
- else if ((inf1 && sign1) || (inf2 && !sign2))
- {
- result = FPInfinity(true);
- }
- else if (zero1 && zero2 && sign1 == !sign2)
- {
- result = FPZero(sign1);
- }
- else
- {
- result = value1 - value2;
-
- if (state.GetFpcrFlag(Fpcr.Fz) && double.IsSubnormal(result))
- {
- state.SetFpsrFlag(Fpsr.Ufc);
-
- result = FPZero(result < 0d);
- }
- }
- }
-
- return result;
- }
-
- private static double FPDefaultNaN()
- {
- return -double.NaN;
- }
-
- private static double FPInfinity(bool sign)
- {
- return sign ? double.NegativeInfinity : double.PositiveInfinity;
- }
-
- private static double FPZero(bool sign)
- {
- return sign ? -0d : +0d;
- }
-
- private static double FPMaxNormal(bool sign)
- {
- return sign ? double.MinValue : double.MaxValue;
- }
-
- private static double FPTwo(bool sign)
- {
- return sign ? -2d : +2d;
- }
-
- private static double FPOnePointFive(bool sign)
- {
- return sign ? -1.5d : +1.5d;
- }
-
- private static double FPNeg(this double value)
- {
- return -value;
- }
-
- private static double ZerosOrOnes(bool ones)
- {
- return BitConverter.Int64BitsToDouble(ones ? -1L : 0L);
- }
-
- private static double FPUnpack(
- this double value,
- out FpType type,
- out bool sign,
- out ulong valueBits,
- CpuThreadState state)
- {
- valueBits = (ulong)BitConverter.DoubleToInt64Bits(value);
-
- sign = (~valueBits & 0x8000000000000000ul) == 0ul;
-
- if ((valueBits & 0x7FF0000000000000ul) == 0ul)
- {
- if ((valueBits & 0x000FFFFFFFFFFFFFul) == 0ul || state.GetFpcrFlag(Fpcr.Fz))
- {
- type = FpType.Zero;
- value = FPZero(sign);
-
- if ((valueBits & 0x000FFFFFFFFFFFFFul) != 0ul)
- {
- FPProcessException(FpExc.InputDenorm, state);
- }
- }
- else
- {
- type = FpType.Nonzero;
- }
- }
- else if ((~valueBits & 0x7FF0000000000000ul) == 0ul)
- {
- if ((valueBits & 0x000FFFFFFFFFFFFFul) == 0ul)
- {
- type = FpType.Infinity;
- }
- else
- {
- type = (~valueBits & 0x0008000000000000ul) == 0ul ? FpType.QNaN : FpType.SNaN;
- value = FPZero(sign);
- }
- }
- else
- {
- type = FpType.Nonzero;
- }
-
- return value;
- }
-
- private static double FPProcessNaNs(
- FpType type1,
- FpType type2,
- ulong op1,
- ulong op2,
- out bool done,
- CpuThreadState state)
- {
- done = true;
-
- if (type1 == FpType.SNaN)
- {
- return FPProcessNaN(type1, op1, state);
- }
- else if (type2 == FpType.SNaN)
- {
- return FPProcessNaN(type2, op2, state);
- }
- else if (type1 == FpType.QNaN)
- {
- return FPProcessNaN(type1, op1, state);
- }
- else if (type2 == FpType.QNaN)
- {
- return FPProcessNaN(type2, op2, state);
- }
-
- done = false;
-
- return FPZero(false);
- }
-
- private static double FPProcessNaNs3(
- FpType type1,
- FpType type2,
- FpType type3,
- ulong op1,
- ulong op2,
- ulong op3,
- out bool done,
- CpuThreadState state)
- {
- done = true;
-
- if (type1 == FpType.SNaN)
- {
- return FPProcessNaN(type1, op1, state);
- }
- else if (type2 == FpType.SNaN)
- {
- return FPProcessNaN(type2, op2, state);
- }
- else if (type3 == FpType.SNaN)
- {
- return FPProcessNaN(type3, op3, state);
- }
- else if (type1 == FpType.QNaN)
- {
- return FPProcessNaN(type1, op1, state);
- }
- else if (type2 == FpType.QNaN)
- {
- return FPProcessNaN(type2, op2, state);
- }
- else if (type3 == FpType.QNaN)
- {
- return FPProcessNaN(type3, op3, state);
- }
-
- done = false;
-
- return FPZero(false);
- }
-
- private static double FPProcessNaN(FpType type, ulong op, CpuThreadState state)
- {
- if (type == FpType.SNaN)
- {
- op |= 1ul << 51;
-
- FPProcessException(FpExc.InvalidOp, state);
- }
-
- if (state.GetFpcrFlag(Fpcr.Dn))
- {
- return FPDefaultNaN();
- }
-
- return BitConverter.Int64BitsToDouble((long)op);
- }
-
- private static void FPProcessException(FpExc exc, CpuThreadState state)
- {
- int enable = (int)exc + 8;
-
- if ((state.CFpcr & (1 << enable)) != 0)
- {
- throw new NotImplementedException("Floating-point trap handling.");
- }
- else
- {
- state.CFpsr |= 1 << (int)exc;
- }
- }
- }
-}
diff --git a/ChocolArm64/Instructions/VectorHelper.cs b/ChocolArm64/Instructions/VectorHelper.cs
deleted file mode 100644
index 4d57e285..00000000
--- a/ChocolArm64/Instructions/VectorHelper.cs
+++ /dev/null
@@ -1,646 +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
-{
- static class VectorHelper
- {
- public static void EmitCall(ILEmitterCtx context, string name64, string name128)
- {
- bool isSimd64 = context.CurrOp.RegisterSize == RegisterSize.Simd64;
-
- context.EmitCall(typeof(VectorHelper), isSimd64 ? name64 : name128);
- }
-
- public static void EmitCall(ILEmitterCtx context, string mthdName)
- {
- context.EmitCall(typeof(VectorHelper), mthdName);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static int SatF32ToS32(float value)
- {
- if (float.IsNaN(value)) return 0;
-
- return value >= int.MaxValue ? int.MaxValue :
- value <= int.MinValue ? int.MinValue : (int)value;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static long SatF32ToS64(float value)
- {
- if (float.IsNaN(value)) return 0;
-
- return value >= long.MaxValue ? long.MaxValue :
- value <= long.MinValue ? long.MinValue : (long)value;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static uint SatF32ToU32(float value)
- {
- if (float.IsNaN(value)) return 0;
-
- return value >= uint.MaxValue ? uint.MaxValue :
- value <= uint.MinValue ? uint.MinValue : (uint)value;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ulong SatF32ToU64(float value)
- {
- if (float.IsNaN(value)) return 0;
-
- return value >= ulong.MaxValue ? ulong.MaxValue :
- value <= ulong.MinValue ? ulong.MinValue : (ulong)value;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static int SatF64ToS32(double value)
- {
- if (double.IsNaN(value)) return 0;
-
- return value >= int.MaxValue ? int.MaxValue :
- value <= int.MinValue ? int.MinValue : (int)value;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static long SatF64ToS64(double value)
- {
- if (double.IsNaN(value)) return 0;
-
- return value >= long.MaxValue ? long.MaxValue :
- value <= long.MinValue ? long.MinValue : (long)value;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static uint SatF64ToU32(double value)
- {
- if (double.IsNaN(value)) return 0;
-
- return value >= uint.MaxValue ? uint.MaxValue :
- value <= uint.MinValue ? uint.MinValue : (uint)value;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ulong SatF64ToU64(double value)
- {
- if (double.IsNaN(value)) return 0;
-
- return value >= ulong.MaxValue ? ulong.MaxValue :
- value <= ulong.MinValue ? ulong.MinValue : (ulong)value;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double Round(double value, CpuThreadState state)
- {
- RoundMode roundMode = state.FPRoundingMode();
-
- if (roundMode == RoundMode.ToNearest)
- {
- return Math.Round(value); // even
- }
- else if (roundMode == RoundMode.TowardsPlusInfinity)
- {
- return Math.Ceiling(value);
- }
- else if (roundMode == RoundMode.TowardsMinusInfinity)
- {
- return Math.Floor(value);
- }
- else /* if (roundMode == RoundMode.TowardsZero) */
- {
- return Math.Truncate(value);
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float RoundF(float value, CpuThreadState state)
- {
- RoundMode roundMode = state.FPRoundingMode();
-
- if (roundMode == RoundMode.ToNearest)
- {
- return MathF.Round(value); // even
- }
- else if (roundMode == RoundMode.TowardsPlusInfinity)
- {
- return MathF.Ceiling(value);
- }
- else if (roundMode == RoundMode.TowardsMinusInfinity)
- {
- return MathF.Floor(value);
- }
- else /* if (roundMode == RoundMode.TowardsZero) */
- {
- return MathF.Truncate(value);
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector128<double> Sse41ScalarRound(Vector128<double> upper, Vector128<double> value, CpuThreadState state)
- {
- if (!Sse41.IsSupported)
- {
- throw new PlatformNotSupportedException();
- }
-
- RoundMode roundMode = state.FPRoundingMode();
-
- if (roundMode == RoundMode.ToNearest)
- {
- return Sse41.RoundToNearestIntegerScalar(upper, value); // even
- }
- else if (roundMode == RoundMode.TowardsPlusInfinity)
- {
- return Sse41.RoundToPositiveInfinityScalar(upper, value);
- }
- else if (roundMode == RoundMode.TowardsMinusInfinity)
- {
- return Sse41.RoundToNegativeInfinityScalar(upper, value);
- }
- else /* if (roundMode == RoundMode.TowardsZero) */
- {
- return Sse41.RoundToZeroScalar(upper, value);
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector128<float> Sse41ScalarRoundF(Vector128<float> upper, Vector128<float> value, CpuThreadState state)
- {
- if (!Sse41.IsSupported)
- {
- throw new PlatformNotSupportedException();
- }
-
- RoundMode roundMode = state.FPRoundingMode();
-
- if (roundMode == RoundMode.ToNearest)
- {
- return Sse41.RoundToNearestIntegerScalar(upper, value); // even
- }
- else if (roundMode == RoundMode.TowardsPlusInfinity)
- {
- return Sse41.RoundToPositiveInfinityScalar(upper, value);
- }
- else if (roundMode == RoundMode.TowardsMinusInfinity)
- {
- return Sse41.RoundToNegativeInfinityScalar(upper, value);
- }
- else /* if (roundMode == RoundMode.TowardsZero) */
- {
- return Sse41.RoundToZeroScalar(upper, value);
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector128<double> Sse41VectorRound(Vector128<double> value, CpuThreadState state)
- {
- if (!Sse41.IsSupported)
- {
- throw new PlatformNotSupportedException();
- }
-
- RoundMode roundMode = state.FPRoundingMode();
-
- if (roundMode == RoundMode.ToNearest)
- {
- return Sse41.RoundToNearestInteger(value); // even
- }
- else if (roundMode == RoundMode.TowardsPlusInfinity)
- {
- return Sse41.RoundToPositiveInfinity(value);
- }
- else if (roundMode == RoundMode.TowardsMinusInfinity)
- {
- return Sse41.RoundToNegativeInfinity(value);
- }
- else /* if (roundMode == RoundMode.TowardsZero) */
- {
- return Sse41.RoundToZero(value);
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector128<float> Sse41VectorRoundF(Vector128<float> value, CpuThreadState state)
- {
- if (!Sse41.IsSupported)
- {
- throw new PlatformNotSupportedException();
- }
-
- RoundMode roundMode = state.FPRoundingMode();
-
- if (roundMode == RoundMode.ToNearest)
- {
- return Sse41.RoundToNearestInteger(value); // even
- }
- else if (roundMode == RoundMode.TowardsPlusInfinity)
- {
- return Sse41.RoundToPositiveInfinity(value);
- }
- else if (roundMode == RoundMode.TowardsMinusInfinity)
- {
- return Sse41.RoundToNegativeInfinity(value);
- }
- else /* if (roundMode == RoundMode.TowardsZero) */
- {
- return Sse41.RoundToZero(value);
- }
- }
-
- public static Vector128<float> Tbl1_V64(
- Vector128<float> vector,
- Vector128<float> tb0)
- {
- return Tbl(vector, 8, tb0);
- }
-
- public static Vector128<float> Tbl1_V128(
- Vector128<float> vector,
- Vector128<float> tb0)
- {
- return Tbl(vector, 16, tb0);
- }
-
- public static Vector128<float> Tbl2_V64(
- Vector128<float> vector,
- Vector128<float> tb0,
- Vector128<float> tb1)
- {
- return Tbl(vector, 8, tb0, tb1);
- }
-
- public static Vector128<float> Tbl2_V128(
- Vector128<float> vector,
- Vector128<float> tb0,
- Vector128<float> tb1)
- {
- return Tbl(vector, 16, tb0, tb1);
- }
-
- public static Vector128<float> Tbl3_V64(
- Vector128<float> vector,
- Vector128<float> tb0,
- Vector128<float> tb1,
- Vector128<float> tb2)
- {
- return Tbl(vector, 8, tb0, tb1, tb2);
- }
-
- public static Vector128<float> Tbl3_V128(
- Vector128<float> vector,
- Vector128<float> tb0,
- Vector128<float> tb1,
- Vector128<float> tb2)
- {
- return Tbl(vector, 16, tb0, tb1, tb2);
- }
-
- public static Vector128<float> Tbl4_V64(
- Vector128<float> vector,
- Vector128<float> tb0,
- Vector128<float> tb1,
- Vector128<float> tb2,
- Vector128<float> tb3)
- {
- return Tbl(vector, 8, tb0, tb1, tb2, tb3);
- }
-
- public static Vector128<float> Tbl4_V128(
- Vector128<float> vector,
- Vector128<float> tb0,
- Vector128<float> tb1,
- Vector128<float> tb2,
- Vector128<float> tb3)
- {
- return Tbl(vector, 16, tb0, tb1, tb2, tb3);
- }
-
- private static Vector128<float> Tbl(Vector128<float> vector, int bytes, params Vector128<float>[] tb)
- {
- Vector128<float> res = new Vector128<float>();
-
- byte[] table = new byte[tb.Length * 16];
-
- for (byte index = 0; index < tb.Length; index++)
- for (byte index2 = 0; index2 < 16; index2++)
- {
- table[index * 16 + index2] = (byte)VectorExtractIntZx(tb[index], index2, 0);
- }
-
- for (byte index = 0; index < bytes; index++)
- {
- byte tblIdx = (byte)VectorExtractIntZx(vector, index, 0);
-
- if (tblIdx < table.Length)
- {
- res = VectorInsertInt(table[tblIdx], res, index, 0);
- }
- }
-
- return res;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double VectorExtractDouble(Vector128<float> vector, byte index)
- {
- if (Sse41.IsSupported)
- {
- return BitConverter.Int64BitsToDouble(Sse41.Extract(Sse.StaticCast<float, long>(vector), index));
- }
- else if (Sse2.IsSupported)
- {
- return BitConverter.Int64BitsToDouble((long)VectorExtractIntZx(vector, index, 3));
- }
-
- throw new PlatformNotSupportedException();
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static long VectorExtractIntSx(Vector128<float> vector, byte index, int size)
- {
- if (Sse41.IsSupported)
- {
- if (size == 0)
- {
- return (sbyte)Sse41.Extract(Sse.StaticCast<float, byte>(vector), index);
- }
- else if (size == 1)
- {
- return (short)Sse2.Extract(Sse.StaticCast<float, ushort>(vector), index);
- }
- else if (size == 2)
- {
- return Sse41.Extract(Sse.StaticCast<float, int>(vector), index);
- }
- else if (size == 3)
- {
- return Sse41.Extract(Sse.StaticCast<float, long>(vector), index);
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(size));
- }
- }
- else if (Sse2.IsSupported)
- {
- if (size == 0)
- {
- return (sbyte)VectorExtractIntZx(vector, index, size);
- }
- else if (size == 1)
- {
- return (short)VectorExtractIntZx(vector, index, size);
- }
- else if (size == 2)
- {
- return (int)VectorExtractIntZx(vector, index, size);
- }
- else if (size == 3)
- {
- return (long)VectorExtractIntZx(vector, index, size);
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(size));
- }
- }
-
- throw new PlatformNotSupportedException();
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ulong VectorExtractIntZx(Vector128<float> vector, byte index, int size)
- {
- if (Sse41.IsSupported)
- {
- if (size == 0)
- {
- return Sse41.Extract(Sse.StaticCast<float, byte>(vector), index);
- }
- else if (size == 1)
- {
- return Sse2.Extract(Sse.StaticCast<float, ushort>(vector), index);
- }
- else if (size == 2)
- {
- return Sse41.Extract(Sse.StaticCast<float, uint>(vector), index);
- }
- else if (size == 3)
- {
- return Sse41.Extract(Sse.StaticCast<float, ulong>(vector), index);
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(size));
- }
- }
- else if (Sse2.IsSupported)
- {
- int shortIdx = size == 0
- ? index >> 1
- : index << (size - 1);
-
- ushort value = Sse2.Extract(Sse.StaticCast<float, ushort>(vector), (byte)shortIdx);
-
- if (size == 0)
- {
- return (byte)(value >> (index & 1) * 8);
- }
- else if (size == 1)
- {
- return value;
- }
- else if (size == 2 || size == 3)
- {
- ushort value1 = Sse2.Extract(Sse.StaticCast<float, ushort>(vector), (byte)(shortIdx + 1));
-
- if (size == 2)
- {
- return (uint)(value | (value1 << 16));
- }
-
- ushort value2 = Sse2.Extract(Sse.StaticCast<float, ushort>(vector), (byte)(shortIdx + 2));
- ushort value3 = Sse2.Extract(Sse.StaticCast<float, ushort>(vector), (byte)(shortIdx + 3));
-
- return ((ulong)value << 0) |
- ((ulong)value1 << 16) |
- ((ulong)value2 << 32) |
- ((ulong)value3 << 48);
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(size));
- }
- }
-
- throw new PlatformNotSupportedException();
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float VectorExtractSingle(Vector128<float> vector, byte index)
- {
- if (Sse41.IsSupported)
- {
- return Sse41.Extract(vector, index);
- }
- else if (Sse2.IsSupported)
- {
- Vector128<ushort> shortVector = Sse.StaticCast<float, ushort>(vector);
-
- int low = Sse2.Extract(shortVector, (byte)(index * 2 + 0));
- int high = Sse2.Extract(shortVector, (byte)(index * 2 + 1));
-
- return BitConverter.Int32BitsToSingle(low | (high << 16));
- }
-
- throw new PlatformNotSupportedException();
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector128<float> VectorInsertDouble(double value, Vector128<float> vector, byte index)
- {
- return VectorInsertInt((ulong)BitConverter.DoubleToInt64Bits(value), vector, index, 3);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector128<float> VectorInsertInt(ulong value, Vector128<float> vector, byte index, int size)
- {
- if (Sse41.IsSupported)
- {
- if (size == 0)
- {
- return Sse.StaticCast<byte, float>(Sse41.Insert(Sse.StaticCast<float, byte>(vector), (byte)value, index));
- }
- else if (size == 1)
- {
- return Sse.StaticCast<ushort, float>(Sse2.Insert(Sse.StaticCast<float, ushort>(vector), (ushort)value, index));
- }
- else if (size == 2)
- {
- return Sse.StaticCast<uint, float>(Sse41.Insert(Sse.StaticCast<float, uint>(vector), (uint)value, index));
- }
- else if (size == 3)
- {
- return Sse.StaticCast<ulong, float>(Sse41.Insert(Sse.StaticCast<float, ulong>(vector), value, index));
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(size));
- }
- }
- else if (Sse2.IsSupported)
- {
- Vector128<ushort> shortVector = Sse.StaticCast<float, ushort>(vector);
-
- int shortIdx = size == 0
- ? index >> 1
- : index << (size - 1);
-
- if (size == 0)
- {
- ushort shortVal = Sse2.Extract(Sse.StaticCast<float, ushort>(vector), (byte)shortIdx);
-
- int shift = (index & 1) * 8;
-
- shortVal &= (ushort)(0xff00 >> shift);
-
- shortVal |= (ushort)((byte)value << shift);
-
- return Sse.StaticCast<ushort, float>(Sse2.Insert(shortVector, shortVal, (byte)shortIdx));
- }
- else if (size == 1)
- {
- return Sse.StaticCast<ushort, float>(Sse2.Insert(Sse.StaticCast<float, ushort>(vector), (ushort)value, index));
- }
- else if (size == 2 || size == 3)
- {
- shortVector = Sse2.Insert(shortVector, (ushort)(value >> 0), (byte)(shortIdx + 0));
- shortVector = Sse2.Insert(shortVector, (ushort)(value >> 16), (byte)(shortIdx + 1));
-
- if (size == 3)
- {
- shortVector = Sse2.Insert(shortVector, (ushort)(value >> 32), (byte)(shortIdx + 2));
- shortVector = Sse2.Insert(shortVector, (ushort)(value >> 48), (byte)(shortIdx + 3));
- }
-
- return Sse.StaticCast<ushort, float>(shortVector);
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(size));
- }
- }
-
- throw new PlatformNotSupportedException();
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector128<float> VectorInsertSingle(float value, Vector128<float> vector, byte index)
- {
- if (Sse41.IsSupported)
- {
- // Note: The if/else if is necessary to enable the JIT to
- // produce a single INSERTPS instruction instead of the
- // jump table fallback.
- if (index == 0)
- {
- return Sse41.Insert(vector, value, 0x00);
- }
- else if (index == 1)
- {
- return Sse41.Insert(vector, value, 0x10);
- }
- else if (index == 2)
- {
- return Sse41.Insert(vector, value, 0x20);
- }
- else if (index == 3)
- {
- return Sse41.Insert(vector, value, 0x30);
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- }
- else if (Sse2.IsSupported)
- {
- int intValue = BitConverter.SingleToInt32Bits(value);
-
- ushort low = (ushort)(intValue >> 0);
- ushort high = (ushort)(intValue >> 16);
-
- Vector128<ushort> shortVector = Sse.StaticCast<float, ushort>(vector);
-
- shortVector = Sse2.Insert(shortVector, low, (byte)(index * 2 + 0));
- shortVector = Sse2.Insert(shortVector, high, (byte)(index * 2 + 1));
-
- return Sse.StaticCast<ushort, float>(shortVector);
- }
-
- throw new PlatformNotSupportedException();
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector128<float> Sse41VectorInsertScalarSingle(float value, Vector128<float> vector)
- {
- // Note: 0b1110 is the mask to zero the upper bits.
- return Sse41.Insert(vector, value, 0b1110);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector128<float> VectorSingleZero()
- {
- if (Sse.IsSupported)
- {
- return Sse.SetZeroVector128();
- }
-
- throw new PlatformNotSupportedException();
- }
- }
-}
diff --git a/ChocolArm64/IntermediateRepresentation/BasicBlock.cs b/ChocolArm64/IntermediateRepresentation/BasicBlock.cs
deleted file mode 100644
index ce39fddb..00000000
--- a/ChocolArm64/IntermediateRepresentation/BasicBlock.cs
+++ /dev/null
@@ -1,122 +0,0 @@
-using ChocolArm64.State;
-using System;
-using System.Collections.Generic;
-
-using static ChocolArm64.State.RegisterConsts;
-
-namespace ChocolArm64.IntermediateRepresentation
-{
- class BasicBlock
- {
- public int Index { get; set; }
-
- public RegisterMask RegInputs { get; private set; }
- public RegisterMask RegOutputs { get; private set; }
-
- public bool HasStateLoad { get; private set; }
-
- private List<Operation> _operations;
-
- public int Count => _operations.Count;
-
- private BasicBlock _next;
- private BasicBlock _branch;
-
- public BasicBlock Next
- {
- get => _next;
- set => _next = AddSuccessor(_next, value);
- }
-
- public BasicBlock Branch
- {
- get => _branch;
- set => _branch = AddSuccessor(_branch, value);
- }
-
- public List<BasicBlock> Predecessors { get; }
-
- public BasicBlock(int index = 0)
- {
- Index = index;
-
- _operations = new List<Operation>();
-
- Predecessors = new List<BasicBlock>();
- }
-
- private BasicBlock AddSuccessor(BasicBlock oldBlock, BasicBlock newBlock)
- {
- oldBlock?.Predecessors.Remove(this);
- newBlock?.Predecessors.Add(this);
-
- return newBlock;
- }
-
- public void Add(Operation operation)
- {
- if (operation.Type == OperationType.LoadLocal ||
- operation.Type == OperationType.StoreLocal)
- {
- int index = operation.GetArg<int>(0);
-
- if (IsRegIndex(index))
- {
- long intMask = 0;
- long vecMask = 0;
-
- switch (operation.GetArg<RegisterType>(1))
- {
- case RegisterType.Flag: intMask = (1L << RegsCount) << index; break;
- case RegisterType.Int: intMask = 1L << index; break;
- case RegisterType.Vector: vecMask = 1L << index; break;
- }
-
- RegisterMask mask = new RegisterMask(intMask, vecMask);
-
- if (operation.Type == OperationType.LoadLocal)
- {
- RegInputs |= mask & ~RegOutputs;
- }
- else
- {
- RegOutputs |= mask;
- }
- }
- }
- else if (operation.Type == OperationType.LoadContext)
- {
- HasStateLoad = true;
- }
-
- operation.Parent = this;
-
- _operations.Add(operation);
- }
-
- public static bool IsRegIndex(int index)
- {
- return (uint)index < RegsCount;
- }
-
- public Operation GetOperation(int index)
- {
- if ((uint)index >= _operations.Count)
- {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
-
- return _operations[index];
- }
-
- public Operation GetLastOp()
- {
- if (Count == 0)
- {
- return null;
- }
-
- return _operations[Count - 1];
- }
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/IntermediateRepresentation/ILLabel.cs b/ChocolArm64/IntermediateRepresentation/ILLabel.cs
deleted file mode 100644
index 70c576cd..00000000
--- a/ChocolArm64/IntermediateRepresentation/ILLabel.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace ChocolArm64.IntermediateRepresentation
-{
- class ILLabel { }
-} \ No newline at end of file
diff --git a/ChocolArm64/IntermediateRepresentation/Operation.cs b/ChocolArm64/IntermediateRepresentation/Operation.cs
deleted file mode 100644
index dcd01bcd..00000000
--- a/ChocolArm64/IntermediateRepresentation/Operation.cs
+++ /dev/null
@@ -1,112 +0,0 @@
-using ChocolArm64.State;
-using System;
-using System.Reflection;
-using System.Reflection.Emit;
-
-namespace ChocolArm64.IntermediateRepresentation
-{
- class Operation
- {
- public BasicBlock Parent { get; set; }
-
- public OperationType Type { get; }
-
- private object[] _arguments { get; }
-
- private Operation(OperationType type, params object[] arguments)
- {
- Type = type;
- _arguments = arguments;
- }
-
- public T GetArg<T>(int index)
- {
- return (T)GetArg(index);
- }
-
- public object GetArg(int index)
- {
- if ((uint)index >= _arguments.Length)
- {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
-
- return _arguments[index];
- }
-
- public static Operation Call(MethodInfo info)
- {
- return new Operation(OperationType.Call, info);
- }
-
- public static Operation CallVirtual(MethodInfo info)
- {
- return new Operation(OperationType.CallVirtual, info);
- }
-
- public static Operation IL(OpCode ilOp)
- {
- return new Operation(OperationType.IL, ilOp);
- }
-
- public static Operation ILBranch(OpCode ilOp, ILLabel target)
- {
- return new Operation(OperationType.ILBranch, ilOp, target);
- }
-
- public static Operation LoadArgument(int index)
- {
- return new Operation(OperationType.LoadArgument, index);
- }
-
- public static Operation LoadConstant(int value)
- {
- return new Operation(OperationType.LoadConstant, value);
- }
-
- public static Operation LoadConstant(long value)
- {
- return new Operation(OperationType.LoadConstant, value);
- }
-
- public static Operation LoadConstant(float value)
- {
- return new Operation(OperationType.LoadConstant, value);
- }
-
- public static Operation LoadConstant(double value)
- {
- return new Operation(OperationType.LoadConstant, value);
- }
-
- public static Operation LoadContext()
- {
- return new Operation(OperationType.LoadContext);
- }
-
- public static Operation LoadField(FieldInfo info)
- {
- return new Operation(OperationType.LoadField, info);
- }
-
- public static Operation LoadLocal(int index, RegisterType type, RegisterSize size)
- {
- return new Operation(OperationType.LoadLocal, index, type, size);
- }
-
- public static Operation MarkLabel(ILLabel label)
- {
- return new Operation(OperationType.MarkLabel, label);
- }
-
- public static Operation StoreContext()
- {
- return new Operation(OperationType.StoreContext);
- }
-
- public static Operation StoreLocal(int index, RegisterType type, RegisterSize size)
- {
- return new Operation(OperationType.StoreLocal, index, type, size);
- }
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/IntermediateRepresentation/OperationType.cs b/ChocolArm64/IntermediateRepresentation/OperationType.cs
deleted file mode 100644
index 644f1716..00000000
--- a/ChocolArm64/IntermediateRepresentation/OperationType.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace ChocolArm64.IntermediateRepresentation
-{
- enum OperationType
- {
- Call,
- CallVirtual,
- IL,
- ILBranch,
- LoadArgument,
- LoadConstant,
- LoadContext,
- LoadField,
- LoadLocal,
- MarkLabel,
- StoreContext,
- StoreLocal
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/IntermediateRepresentation/RegisterMask.cs b/ChocolArm64/IntermediateRepresentation/RegisterMask.cs
deleted file mode 100644
index aea6ab36..00000000
--- a/ChocolArm64/IntermediateRepresentation/RegisterMask.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-using System;
-
-namespace ChocolArm64.IntermediateRepresentation
-{
- struct RegisterMask : IEquatable<RegisterMask>
- {
- public long IntMask { get; set; }
- public long VecMask { get; set; }
-
- public RegisterMask(long intMask, long vecMask)
- {
- IntMask = intMask;
- VecMask = vecMask;
- }
-
- public static RegisterMask operator &(RegisterMask x, RegisterMask y)
- {
- return new RegisterMask(x.IntMask & y.IntMask, x.VecMask & y.VecMask);
- }
-
- public static RegisterMask operator |(RegisterMask x, RegisterMask y)
- {
- return new RegisterMask(x.IntMask | y.IntMask, x.VecMask | y.VecMask);
- }
-
- public static RegisterMask operator ~(RegisterMask x)
- {
- return new RegisterMask(~x.IntMask, ~x.VecMask);
- }
-
- public static bool operator ==(RegisterMask x, RegisterMask y)
- {
- return x.Equals(y);
- }
-
- public static bool operator !=(RegisterMask x, RegisterMask y)
- {
- return !x.Equals(y);
- }
-
- public override bool Equals(object obj)
- {
- return obj is RegisterMask regMask && Equals(regMask);
- }
-
- public bool Equals(RegisterMask other)
- {
- return IntMask == other.IntMask && VecMask == other.VecMask;
- }
-
- public override int GetHashCode()
- {
- return HashCode.Combine(IntMask, VecMask);
- }
- }
-}
diff --git a/ChocolArm64/Memory/CompareExchange128.cs b/ChocolArm64/Memory/CompareExchange128.cs
deleted file mode 100644
index 1618ff0f..00000000
--- a/ChocolArm64/Memory/CompareExchange128.cs
+++ /dev/null
@@ -1,151 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-
-namespace ChocolArm64.Memory
-{
- static class CompareExchange128
- {
- private struct Int128
- {
- public ulong Low { get; }
- public ulong High { get; }
-
- public Int128(ulong low, ulong high)
- {
- Low = low;
- High = high;
- }
- }
-
- private delegate Int128 InterlockedCompareExchange(IntPtr address, Int128 expected, Int128 desired);
-
- private delegate int GetCpuId();
-
- private static InterlockedCompareExchange _interlockedCompareExchange;
-
- static CompareExchange128()
- {
- if (RuntimeInformation.OSArchitecture != Architecture.X64 || !IsCmpxchg16bSupported())
- {
- throw new PlatformNotSupportedException();
- }
-
- byte[] interlockedCompareExchange128Code;
-
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- interlockedCompareExchange128Code = new byte[]
- {
- 0x53, // push rbx
- 0x49, 0x8b, 0x00, // mov rax, [r8]
- 0x49, 0x8b, 0x19, // mov rbx, [r9]
- 0x49, 0x89, 0xca, // mov r10, rcx
- 0x49, 0x89, 0xd3, // mov r11, rdx
- 0x49, 0x8b, 0x49, 0x08, // mov rcx, [r9+8]
- 0x49, 0x8b, 0x50, 0x08, // mov rdx, [r8+8]
- 0xf0, 0x49, 0x0f, 0xc7, 0x0b, // lock cmpxchg16b [r11]
- 0x49, 0x89, 0x02, // mov [r10], rax
- 0x4c, 0x89, 0xd0, // mov rax, r10
- 0x49, 0x89, 0x52, 0x08, // mov [r10+8], rdx
- 0x5b, // pop rbx
- 0xc3 // ret
- };
- }
- else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ||
- RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
- {
- interlockedCompareExchange128Code = new byte[]
- {
- 0x53, // push rbx
- 0x49, 0x89, 0xd1, // mov r9, rdx
- 0x48, 0x89, 0xcb, // mov rbx, rcx
- 0x48, 0x89, 0xf0, // mov rax, rsi
- 0x4c, 0x89, 0xca, // mov rdx, r9
- 0x4c, 0x89, 0xc1, // mov rcx, r8
- 0xf0, 0x48, 0x0f, 0xc7, 0x0f, // lock cmpxchg16b [rdi]
- 0x5b, // pop rbx
- 0xc3 // ret
- };
- }
- else
- {
- throw new PlatformNotSupportedException();
- }
-
- IntPtr funcPtr = MapCodeAsExecutable(interlockedCompareExchange128Code);
-
- _interlockedCompareExchange = Marshal.GetDelegateForFunctionPointer<InterlockedCompareExchange>(funcPtr);
- }
-
- private static bool IsCmpxchg16bSupported()
- {
- byte[] getCpuIdCode = new byte[]
- {
- 0x53, // push rbx
- 0xb8, 0x01, 0x00, 0x00, 0x00, // mov eax, 0x1
- 0x0f, 0xa2, // cpuid
- 0x89, 0xc8, // mov eax, ecx
- 0x5b, // pop rbx
- 0xc3 // ret
- };
-
- IntPtr funcPtr = MapCodeAsExecutable(getCpuIdCode);
-
- GetCpuId getCpuId = Marshal.GetDelegateForFunctionPointer<GetCpuId>(funcPtr);
-
- int cpuId = getCpuId();
-
- MemoryManagement.Free(funcPtr);
-
- return (cpuId & (1 << 13)) != 0;
- }
-
- private static IntPtr MapCodeAsExecutable(byte[] code)
- {
- ulong codeLength = (ulong)code.Length;
-
- IntPtr funcPtr = MemoryManagement.Allocate(codeLength);
-
- unsafe
- {
- fixed (byte* codePtr = code)
- {
- byte* dest = (byte*)funcPtr;
-
- long size = (long)codeLength;
-
- Buffer.MemoryCopy(codePtr, dest, size, size);
- }
- }
-
- MemoryManagement.Reprotect(funcPtr, codeLength, MemoryProtection.Execute);
-
- return funcPtr;
- }
-
- public static bool InterlockedCompareExchange128(
- IntPtr address,
- ulong expectedLow,
- ulong expectedHigh,
- ulong desiredLow,
- ulong desiredHigh)
- {
- Int128 expected = new Int128(expectedLow, expectedHigh);
- Int128 desired = new Int128(desiredLow, desiredHigh);
-
- Int128 old = _interlockedCompareExchange(address, expected, desired);
-
- return old.Low == expected.Low && old.High == expected.High;
- }
-
- public static void InterlockedRead128(IntPtr address, out ulong low, out ulong high)
- {
- Int128 zero = new Int128(0, 0);
-
- Int128 old = _interlockedCompareExchange(address, zero, zero);
-
- low = old.Low;
- high = old.High;
- }
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/Memory/IMemory.cs b/ChocolArm64/Memory/IMemory.cs
deleted file mode 100644
index dc582155..00000000
--- a/ChocolArm64/Memory/IMemory.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-namespace ChocolArm64.Memory
-{
- public interface IMemory
- {
- sbyte ReadSByte(long position);
-
- short ReadInt16(long position);
-
- int ReadInt32(long position);
-
- long ReadInt64(long position);
-
- byte ReadByte(long position);
-
- ushort ReadUInt16(long position);
-
- uint ReadUInt32(long position);
-
- ulong ReadUInt64(long position);
-
- void WriteSByte(long position, sbyte value);
-
- void WriteInt16(long position, short value);
-
- void WriteInt32(long position, int value);
-
- void WriteInt64(long position, long value);
-
- void WriteByte(long position, byte value);
-
- void WriteUInt16(long position, ushort value);
-
- void WriteUInt32(long position, uint value);
-
- void WriteUInt64(long position, ulong value);
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/Memory/MemoryHelper.cs b/ChocolArm64/Memory/MemoryHelper.cs
deleted file mode 100644
index 1c436dd8..00000000
--- a/ChocolArm64/Memory/MemoryHelper.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-using System;
-using System.IO;
-using System.Runtime.InteropServices;
-using System.Text;
-
-namespace ChocolArm64.Memory
-{
- public static class MemoryHelper
- {
- public static void FillWithZeros(MemoryManager memory, long position, int size)
- {
- int size8 = size & ~(8 - 1);
-
- for (int offs = 0; offs < size8; offs += 8)
- {
- memory.WriteInt64(position + offs, 0);
- }
-
- for (int offs = size8; offs < (size - size8); offs++)
- {
- memory.WriteByte(position + offs, 0);
- }
- }
-
- public unsafe static T Read<T>(MemoryManager memory, long position) where T : struct
- {
- long size = Marshal.SizeOf<T>();
-
- byte[] data = memory.ReadBytes(position, size);
-
- fixed (byte* ptr = data)
- {
- return Marshal.PtrToStructure<T>((IntPtr)ptr);
- }
- }
-
- public unsafe static void Write<T>(MemoryManager memory, long position, T value) where T : struct
- {
- long size = Marshal.SizeOf<T>();
-
- byte[] data = new byte[size];
-
- fixed (byte* ptr = data)
- {
- Marshal.StructureToPtr<T>(value, (IntPtr)ptr, false);
- }
-
- memory.WriteBytes(position, data);
- }
-
- public static string ReadAsciiString(MemoryManager memory, long position, long maxSize = -1)
- {
- using (MemoryStream ms = new MemoryStream())
- {
- for (long offs = 0; offs < maxSize || maxSize == -1; offs++)
- {
- byte value = (byte)memory.ReadByte(position + offs);
-
- if (value == 0)
- {
- break;
- }
-
- ms.WriteByte(value);
- }
-
- return Encoding.ASCII.GetString(ms.ToArray());
- }
- }
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/Memory/MemoryManagement.cs b/ChocolArm64/Memory/MemoryManagement.cs
deleted file mode 100644
index 80585791..00000000
--- a/ChocolArm64/Memory/MemoryManagement.cs
+++ /dev/null
@@ -1,114 +0,0 @@
-using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-namespace ChocolArm64.Memory
-{
- public static class MemoryManagement
- {
- public static bool HasWriteWatchSupport => RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
-
- public static IntPtr Allocate(ulong size)
- {
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- IntPtr sizeNint = new IntPtr((long)size);
-
- return MemoryManagementWindows.Allocate(sizeNint);
- }
- else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ||
- RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
- {
- return MemoryManagementUnix.Allocate(size);
- }
- else
- {
- throw new PlatformNotSupportedException();
- }
- }
-
- public static IntPtr AllocateWriteTracked(ulong size)
- {
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- IntPtr sizeNint = new IntPtr((long)size);
-
- return MemoryManagementWindows.AllocateWriteTracked(sizeNint);
- }
- else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ||
- RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
- {
- return MemoryManagementUnix.Allocate(size);
- }
- else
- {
- throw new PlatformNotSupportedException();
- }
- }
-
- public static void Reprotect(IntPtr address, ulong size, MemoryProtection permission)
- {
- bool result;
-
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- IntPtr sizeNint = new IntPtr((long)size);
-
- result = MemoryManagementWindows.Reprotect(address, sizeNint, permission);
- }
- else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ||
- RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
- {
- result = MemoryManagementUnix.Reprotect(address, size, permission);
- }
- else
- {
- throw new PlatformNotSupportedException();
- }
-
- if (!result)
- {
- throw new MemoryProtectionException(permission);
- }
- }
-
- public static bool Free(IntPtr address)
- {
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- return MemoryManagementWindows.Free(address);
- }
- else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ||
- RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
- {
- return MemoryManagementUnix.Free(address);
- }
- else
- {
- throw new PlatformNotSupportedException();
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool GetModifiedPages(
- IntPtr address,
- IntPtr size,
- IntPtr[] addresses,
- out ulong count)
- {
- // This is only supported on windows, but returning
- // false (failed) is also valid for platforms without
- // write tracking support on the OS.
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- return MemoryManagementWindows.GetModifiedPages(address, size, addresses, out count);
- }
- else
- {
- count = 0;
-
- return false;
- }
- }
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/Memory/MemoryManagementUnix.cs b/ChocolArm64/Memory/MemoryManagementUnix.cs
deleted file mode 100644
index fe3cfb7e..00000000
--- a/ChocolArm64/Memory/MemoryManagementUnix.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-using Mono.Unix.Native;
-using System;
-
-namespace ChocolArm64.Memory
-{
- static class MemoryManagementUnix
- {
- public static IntPtr Allocate(ulong size)
- {
- ulong pageSize = (ulong)Syscall.sysconf(SysconfName._SC_PAGESIZE);
-
- const MmapProts prot = MmapProts.PROT_READ | MmapProts.PROT_WRITE;
-
- const MmapFlags flags = MmapFlags.MAP_PRIVATE | MmapFlags.MAP_ANONYMOUS;
-
- IntPtr ptr = Syscall.mmap(IntPtr.Zero, size + pageSize, prot, flags, -1, 0);
-
- if (ptr == IntPtr.Zero)
- {
- throw new OutOfMemoryException();
- }
-
- unsafe
- {
- ptr = new IntPtr(ptr.ToInt64() + (long)pageSize);
-
- *((ulong*)ptr - 1) = size;
- }
-
- return ptr;
- }
-
- public static bool Reprotect(IntPtr address, ulong size, MemoryProtection protection)
- {
- MmapProts prot = GetProtection(protection);
-
- return Syscall.mprotect(address, size, prot) == 0;
- }
-
- private static MmapProts GetProtection(MemoryProtection protection)
- {
- switch (protection)
- {
- case MemoryProtection.None: return MmapProts.PROT_NONE;
- case MemoryProtection.Read: return MmapProts.PROT_READ;
- case MemoryProtection.ReadAndWrite: return MmapProts.PROT_READ | MmapProts.PROT_WRITE;
- case MemoryProtection.ReadAndExecute: return MmapProts.PROT_READ | MmapProts.PROT_EXEC;
- case MemoryProtection.Execute: return MmapProts.PROT_EXEC;
-
- default: throw new ArgumentException($"Invalid permission \"{protection}\".");
- }
- }
-
- public static bool Free(IntPtr address)
- {
- ulong pageSize = (ulong)Syscall.sysconf(SysconfName._SC_PAGESIZE);
-
- ulong size;
-
- unsafe
- {
- size = *((ulong*)address - 1);
-
- address = new IntPtr(address.ToInt64() - (long)pageSize);
- }
-
- return Syscall.munmap(address, size + pageSize) == 0;
- }
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/Memory/MemoryManagementWindows.cs b/ChocolArm64/Memory/MemoryManagementWindows.cs
deleted file mode 100644
index 6cee1342..00000000
--- a/ChocolArm64/Memory/MemoryManagementWindows.cs
+++ /dev/null
@@ -1,155 +0,0 @@
-using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-namespace ChocolArm64.Memory
-{
- static class MemoryManagementWindows
- {
- [Flags]
- private enum AllocationType : uint
- {
- Commit = 0x1000,
- Reserve = 0x2000,
- Decommit = 0x4000,
- Release = 0x8000,
- Reset = 0x80000,
- Physical = 0x400000,
- TopDown = 0x100000,
- WriteWatch = 0x200000,
- LargePages = 0x20000000
- }
-
- [Flags]
- private enum MemoryProtection : uint
- {
- NoAccess = 0x01,
- ReadOnly = 0x02,
- ReadWrite = 0x04,
- WriteCopy = 0x08,
- Execute = 0x10,
- ExecuteRead = 0x20,
- ExecuteReadWrite = 0x40,
- ExecuteWriteCopy = 0x80,
- GuardModifierflag = 0x100,
- NoCacheModifierflag = 0x200,
- WriteCombineModifierflag = 0x400
- }
-
- private enum WriteWatchFlags : uint
- {
- None = 0,
- Reset = 1
- }
-
- [DllImport("kernel32.dll")]
- private static extern IntPtr VirtualAlloc(
- IntPtr lpAddress,
- IntPtr dwSize,
- AllocationType flAllocationType,
- MemoryProtection flProtect);
-
- [DllImport("kernel32.dll")]
- private static extern bool VirtualProtect(
- IntPtr lpAddress,
- IntPtr dwSize,
- MemoryProtection flNewProtect,
- out MemoryProtection lpflOldProtect);
-
- [DllImport("kernel32.dll")]
- private static extern bool VirtualFree(
- IntPtr lpAddress,
- IntPtr dwSize,
- AllocationType dwFreeType);
-
- [DllImport("kernel32.dll")]
- private static extern int GetWriteWatch(
- WriteWatchFlags dwFlags,
- IntPtr lpBaseAddress,
- IntPtr dwRegionSize,
- IntPtr[] lpAddresses,
- ref ulong lpdwCount,
- out uint lpdwGranularity);
-
- public static IntPtr Allocate(IntPtr size)
- {
- const AllocationType flags =
- AllocationType.Reserve |
- AllocationType.Commit;
-
- IntPtr ptr = VirtualAlloc(IntPtr.Zero, size, flags, MemoryProtection.ReadWrite);
-
- if (ptr == IntPtr.Zero)
- {
- throw new OutOfMemoryException();
- }
-
- return ptr;
- }
-
- public static IntPtr AllocateWriteTracked(IntPtr size)
- {
- const AllocationType flags =
- AllocationType.Reserve |
- AllocationType.Commit |
- AllocationType.WriteWatch;
-
- IntPtr ptr = VirtualAlloc(IntPtr.Zero, size, flags, MemoryProtection.ReadWrite);
-
- if (ptr == IntPtr.Zero)
- {
- throw new OutOfMemoryException();
- }
-
- return ptr;
- }
-
- public static bool Reprotect(IntPtr address, IntPtr size, Memory.MemoryProtection protection)
- {
- MemoryProtection prot = GetProtection(protection);
-
- return VirtualProtect(address, size, prot, out _);
- }
-
- private static MemoryProtection GetProtection(Memory.MemoryProtection protection)
- {
- switch (protection)
- {
- case Memory.MemoryProtection.None: return MemoryProtection.NoAccess;
- case Memory.MemoryProtection.Read: return MemoryProtection.ReadOnly;
- case Memory.MemoryProtection.ReadAndWrite: return MemoryProtection.ReadWrite;
- case Memory.MemoryProtection.ReadAndExecute: return MemoryProtection.ExecuteRead;
- case Memory.MemoryProtection.Execute: return MemoryProtection.Execute;
-
- default: throw new ArgumentException($"Invalid permission \"{protection}\".");
- }
- }
-
- public static bool Free(IntPtr address)
- {
- return VirtualFree(address, IntPtr.Zero, AllocationType.Release);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool GetModifiedPages(
- IntPtr address,
- IntPtr size,
- IntPtr[] addresses,
- out ulong count)
- {
- ulong pagesCount = (ulong)addresses.Length;
-
- int result = GetWriteWatch(
- WriteWatchFlags.Reset,
- address,
- size,
- addresses,
- ref pagesCount,
- out uint granularity);
-
- count = pagesCount;
-
- return result == 0;
- }
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/Memory/MemoryManager.cs b/ChocolArm64/Memory/MemoryManager.cs
deleted file mode 100644
index 2347f1eb..00000000
--- a/ChocolArm64/Memory/MemoryManager.cs
+++ /dev/null
@@ -1,1017 +0,0 @@
-using ChocolArm64.Instructions;
-using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-using System.Threading;
-
-using static ChocolArm64.Memory.CompareExchange128;
-using static ChocolArm64.Memory.MemoryManagement;
-
-namespace ChocolArm64.Memory
-{
- public unsafe class MemoryManager : ARMeilleure.Memory.IMemoryManager
- {
- public const int PageBits = 12;
- public const int PageSize = 1 << PageBits;
- public const int PageMask = PageSize - 1;
-
- private const long PteFlagNotModified = 1;
-
- internal const long PteFlagsMask = 7;
-
- public IntPtr Ram { get; private set; }
-
- private byte* _ramPtr;
-
- private IntPtr _pageTable;
-
- internal IntPtr PageTable => _pageTable;
-
- internal int PtLevelBits { get; }
- internal int PtLevelSize { get; }
- internal int PtLevelMask { get; }
-
- public bool HasWriteWatchSupport => MemoryManagement.HasWriteWatchSupport;
-
- public int AddressSpaceBits { get; }
- public long AddressSpaceSize { get; }
-
- public MemoryManager(
- IntPtr ram,
- int addressSpaceBits = 48,
- bool useFlatPageTable = false)
- {
- Ram = ram;
-
- _ramPtr = (byte*)ram;
-
- AddressSpaceBits = addressSpaceBits;
- AddressSpaceSize = 1L << addressSpaceBits;
-
- // When flat page table is requested, we use a single
- // array for the mappings of the entire address space.
- // This has better performance, but also high memory usage.
- // The multi level page table uses 9 bits per level, so
- // the memory usage is lower, but the performance is also
- // lower, since each address translation requires multiple reads.
- if (useFlatPageTable)
- {
- PtLevelBits = addressSpaceBits - PageBits;
- }
- else
- {
- PtLevelBits = 9;
- }
-
- PtLevelSize = 1 << PtLevelBits;
- PtLevelMask = PtLevelSize - 1;
-
- _pageTable = Allocate((ulong)(PtLevelSize * IntPtr.Size));
- }
-
- public void Map(long va, long pa, long size)
- {
- SetPtEntries(va, _ramPtr + pa, size);
- }
-
- public void Unmap(long position, long size)
- {
- SetPtEntries(position, null, size);
- }
-
- public bool IsMapped(long position)
- {
- return Translate(position) != IntPtr.Zero;
- }
-
- public long GetPhysicalAddress(long virtualAddress)
- {
- byte* ptr = (byte*)Translate(virtualAddress);
-
- return (long)(ptr - _ramPtr);
- }
-
- private IntPtr Translate(long position)
- {
- if (!IsValidPosition(position))
- {
- return IntPtr.Zero;
- }
-
- byte* ptr = GetPtEntry(position);
-
- ulong ptrUlong = (ulong)ptr;
-
- if ((ptrUlong & PteFlagsMask) != 0)
- {
- ptrUlong &= ~(ulong)PteFlagsMask;
-
- ptr = (byte*)ptrUlong;
- }
-
- return new IntPtr(ptr + (position & PageMask));
- }
-
- private IntPtr TranslateWrite(long position)
- {
- if (!IsValidPosition(position))
- {
- return IntPtr.Zero;
- }
-
- byte* ptr = GetPtEntry(position);
-
- ulong ptrUlong = (ulong)ptr;
-
- if ((ptrUlong & PteFlagsMask) != 0)
- {
- if ((ptrUlong & PteFlagNotModified) != 0)
- {
- ClearPtEntryFlag(position, PteFlagNotModified);
- }
-
- ptrUlong &= ~(ulong)PteFlagsMask;
-
- ptr = (byte*)ptrUlong;
- }
-
- return new IntPtr(ptr + (position & PageMask));
- }
-
- private byte* GetPtEntry(long position)
- {
- return *(byte**)GetPtPtr(position);
- }
-
- private void SetPtEntries(long va, byte* ptr, long size)
- {
- long endPosition = (va + size + PageMask) & ~PageMask;
-
- while ((ulong)va < (ulong)endPosition)
- {
- SetPtEntry(va, ptr);
-
- va += PageSize;
-
- if (ptr != null)
- {
- ptr += PageSize;
- }
- }
- }
-
- private void SetPtEntry(long position, byte* ptr)
- {
- *(byte**)GetPtPtr(position) = ptr;
- }
-
- private void SetPtEntryFlag(long position, long flag)
- {
- ModifyPtEntryFlag(position, flag, setFlag: true);
- }
-
- private void ClearPtEntryFlag(long position, long flag)
- {
- ModifyPtEntryFlag(position, flag, setFlag: false);
- }
-
- private void ModifyPtEntryFlag(long position, long flag, bool setFlag)
- {
- IntPtr* pt = (IntPtr*)_pageTable;
-
- while (true)
- {
- IntPtr* ptPtr = GetPtPtr(position);
-
- IntPtr old = *ptPtr;
-
- long modified = old.ToInt64();
-
- if (setFlag)
- {
- modified |= flag;
- }
- else
- {
- modified &= ~flag;
- }
-
- IntPtr origValue = Interlocked.CompareExchange(ref *ptPtr, new IntPtr(modified), old);
-
- if (origValue == old)
- {
- break;
- }
- }
- }
-
- private IntPtr* GetPtPtr(long position)
- {
- if (!IsValidPosition(position))
- {
- throw new ArgumentOutOfRangeException(nameof(position));
- }
-
- IntPtr nextPtr = _pageTable;
-
- IntPtr* ptePtr = null;
-
- int bit = PageBits;
-
- while (true)
- {
- long index = (position >> bit) & PtLevelMask;
-
- ptePtr = &((IntPtr*)nextPtr)[index];
-
- bit += PtLevelBits;
-
- if (bit >= AddressSpaceBits)
- {
- break;
- }
-
- nextPtr = *ptePtr;
-
- if (nextPtr == IntPtr.Zero)
- {
- // Entry does not yet exist, allocate a new one.
- IntPtr newPtr = Allocate((ulong)(PtLevelSize * IntPtr.Size));
-
- // Try to swap the current pointer (should be zero), with the allocated one.
- nextPtr = Interlocked.Exchange(ref *ptePtr, newPtr);
-
- // If the old pointer is not null, then another thread already has set it.
- if (nextPtr != IntPtr.Zero)
- {
- Free(newPtr);
- }
- else
- {
- nextPtr = newPtr;
- }
- }
- }
-
- return ptePtr;
- }
-
- public bool IsRegionModified(long position, long size)
- {
- if (!HasWriteWatchSupport)
- {
- return IsRegionModifiedFallback(position, size);
- }
-
- IntPtr address = Translate(position);
-
- IntPtr baseAddr = address;
- IntPtr expectedAddr = address;
-
- long pendingPages = 0;
-
- long pages = size / PageSize;
-
- bool modified = false;
-
- bool IsAnyPageModified()
- {
- IntPtr pendingSize = new IntPtr(pendingPages * PageSize);
-
- IntPtr[] addresses = new IntPtr[pendingPages];
-
- bool result = GetModifiedPages(baseAddr, pendingSize, addresses, out ulong count);
-
- if (result)
- {
- return count != 0;
- }
- else
- {
- return true;
- }
- }
-
- while (pages-- > 0)
- {
- if (address != expectedAddr)
- {
- modified |= IsAnyPageModified();
-
- baseAddr = address;
-
- pendingPages = 0;
- }
-
- expectedAddr = address + PageSize;
-
- pendingPages++;
-
- if (pages == 0)
- {
- break;
- }
-
- position += PageSize;
-
- address = Translate(position);
- }
-
- if (pendingPages != 0)
- {
- modified |= IsAnyPageModified();
- }
-
- return modified;
- }
-
- private unsafe bool IsRegionModifiedFallback(long position, long size)
- {
- long endAddr = (position + size + PageMask) & ~PageMask;
-
- bool modified = false;
-
- while ((ulong)position < (ulong)endAddr)
- {
- if (IsValidPosition(position))
- {
- byte* ptr = ((byte**)_pageTable)[position >> PageBits];
-
- ulong ptrUlong = (ulong)ptr;
-
- if ((ptrUlong & PteFlagNotModified) == 0)
- {
- modified = true;
-
- SetPtEntryFlag(position, PteFlagNotModified);
- }
- }
- else
- {
- modified = true;
- }
-
- position += PageSize;
- }
-
- return modified;
- }
-
- public bool TryGetHostAddress(long position, long size, out IntPtr ptr)
- {
- if (IsContiguous(position, size))
- {
- ptr = (IntPtr)Translate(position);
-
- return true;
- }
-
- ptr = IntPtr.Zero;
-
- return false;
- }
-
- private bool IsContiguous(long position, long size)
- {
- long endPos = position + size;
-
- position &= ~PageMask;
-
- long expectedPa = GetPhysicalAddress(position);
-
- while ((ulong)position < (ulong)endPos)
- {
- long pa = GetPhysicalAddress(position);
-
- if (pa != expectedPa)
- {
- return false;
- }
-
- position += PageSize;
- expectedPa += PageSize;
- }
-
- return true;
- }
-
- public bool IsValidPosition(long position)
- {
- return (ulong)position < (ulong)AddressSpaceSize;
- }
-
- internal bool AtomicCompareExchange2xInt32(
- long position,
- int expectedLow,
- int expectedHigh,
- int desiredLow,
- int desiredHigh)
- {
- long expected = (uint)expectedLow;
- long desired = (uint)desiredLow;
-
- expected |= (long)expectedHigh << 32;
- desired |= (long)desiredHigh << 32;
-
- return AtomicCompareExchangeInt64(position, expected, desired);
- }
-
- internal bool AtomicCompareExchangeInt128(
- long position,
- ulong expectedLow,
- ulong expectedHigh,
- ulong desiredLow,
- ulong desiredHigh)
- {
- if ((position & 0xf) != 0)
- {
- AbortWithAlignmentFault(position);
- }
-
- IntPtr ptr = TranslateWrite(position);
-
- return InterlockedCompareExchange128(ptr, expectedLow, expectedHigh, desiredLow, desiredHigh);
- }
-
- internal Vector128<float> AtomicReadInt128(long position)
- {
- if ((position & 0xf) != 0)
- {
- AbortWithAlignmentFault(position);
- }
-
- IntPtr ptr = Translate(position);
-
- InterlockedRead128(ptr, out ulong low, out ulong high);
-
- Vector128<float> vector = default(Vector128<float>);
-
- vector = VectorHelper.VectorInsertInt(low, vector, 0, 3);
- vector = VectorHelper.VectorInsertInt(high, vector, 1, 3);
-
- return vector;
- }
-
- public bool AtomicCompareExchangeByte(long position, byte expected, byte desired)
- {
- int* ptr = (int*)Translate(position);
-
- int currentValue = *ptr;
-
- int expected32 = (currentValue & ~byte.MaxValue) | expected;
- int desired32 = (currentValue & ~byte.MaxValue) | desired;
-
- return Interlocked.CompareExchange(ref *ptr, desired32, expected32) == expected32;
- }
-
- public bool AtomicCompareExchangeInt16(long position, short expected, short desired)
- {
- if ((position & 1) != 0)
- {
- AbortWithAlignmentFault(position);
- }
-
- int* ptr = (int*)Translate(position);
-
- int currentValue = *ptr;
-
- int expected32 = (currentValue & ~ushort.MaxValue) | (ushort)expected;
- int desired32 = (currentValue & ~ushort.MaxValue) | (ushort)desired;
-
- return Interlocked.CompareExchange(ref *ptr, desired32, expected32) == expected32;
- }
-
- public bool AtomicCompareExchangeInt32(long position, int expected, int desired)
- {
- if ((position & 3) != 0)
- {
- AbortWithAlignmentFault(position);
- }
-
- int* ptr = (int*)TranslateWrite(position);
-
- return Interlocked.CompareExchange(ref *ptr, desired, expected) == expected;
- }
-
- public bool AtomicCompareExchangeInt64(long position, long expected, long desired)
- {
- if ((position & 7) != 0)
- {
- AbortWithAlignmentFault(position);
- }
-
- long* ptr = (long*)TranslateWrite(position);
-
- return Interlocked.CompareExchange(ref *ptr, desired, expected) == expected;
- }
-
- public int AtomicIncrementInt32(long position)
- {
- if ((position & 3) != 0)
- {
- AbortWithAlignmentFault(position);
- }
-
- int* ptr = (int*)TranslateWrite(position);
-
- return Interlocked.Increment(ref *ptr);
- }
-
- public int AtomicDecrementInt32(long position)
- {
- if ((position & 3) != 0)
- {
- AbortWithAlignmentFault(position);
- }
-
- int* ptr = (int*)TranslateWrite(position);
-
- return Interlocked.Decrement(ref *ptr);
- }
-
- private void AbortWithAlignmentFault(long position)
- {
- // TODO: Abort mode and exception support on the CPU.
- throw new InvalidOperationException($"Tried to compare exchange a misaligned address 0x{position:X16}.");
- }
-
- public sbyte ReadSByte(long position)
- {
- return (sbyte)ReadByte(position);
- }
-
- public short ReadInt16(long position)
- {
- return (short)ReadUInt16(position);
- }
-
- public int ReadInt32(long position)
- {
- return (int)ReadUInt32(position);
- }
-
- public long ReadInt64(long position)
- {
- return (long)ReadUInt64(position);
- }
-
- public byte ReadByte(long position)
- {
- return *((byte*)Translate(position));
- }
-
- public ushort ReadUInt16(long position)
- {
- if ((position & 1) == 0)
- {
- return *((ushort*)Translate(position));
- }
- else
- {
- return (ushort)(ReadByte(position + 0) << 0 |
- ReadByte(position + 1) << 8);
- }
- }
-
- public uint ReadUInt32(long position)
- {
- if ((position & 3) == 0)
- {
- return *((uint*)Translate(position));
- }
- else
- {
- return (uint)(ReadUInt16(position + 0) << 0 |
- ReadUInt16(position + 2) << 16);
- }
- }
-
- public ulong ReadUInt64(long position)
- {
- if ((position & 7) == 0)
- {
- return *((ulong*)Translate(position));
- }
- else
- {
- return (ulong)ReadUInt32(position + 0) << 0 |
- (ulong)ReadUInt32(position + 4) << 32;
- }
- }
-
- public Vector128<float> ReadVector8(long position)
- {
- if (Sse2.IsSupported)
- {
- return Sse.StaticCast<byte, float>(Sse2.SetVector128(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ReadByte(position)));
- }
- else
- {
- Vector128<float> value = VectorHelper.VectorSingleZero();
-
- value = VectorHelper.VectorInsertInt(ReadByte(position), value, 0, 0);
-
- return value;
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Vector128<float> ReadVector16(long position)
- {
- if (Sse2.IsSupported && (position & 1) == 0)
- {
- return Sse.StaticCast<ushort, float>(Sse2.Insert(Sse2.SetZeroVector128<ushort>(), ReadUInt16(position), 0));
- }
- else
- {
- Vector128<float> value = VectorHelper.VectorSingleZero();
-
- value = VectorHelper.VectorInsertInt(ReadUInt16(position), value, 0, 1);
-
- return value;
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Vector128<float> ReadVector32(long position)
- {
- if (Sse.IsSupported && (position & 3) == 0)
- {
- return Sse.LoadScalarVector128((float*)Translate(position));
- }
- else
- {
- Vector128<float> value = VectorHelper.VectorSingleZero();
-
- value = VectorHelper.VectorInsertInt(ReadUInt32(position), value, 0, 2);
-
- return value;
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Vector128<float> ReadVector64(long position)
- {
- if (Sse2.IsSupported && (position & 7) == 0)
- {
- return Sse.StaticCast<double, float>(Sse2.LoadScalarVector128((double*)Translate(position)));
- }
- else
- {
- Vector128<float> value = VectorHelper.VectorSingleZero();
-
- value = VectorHelper.VectorInsertInt(ReadUInt64(position), value, 0, 3);
-
- return value;
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Vector128<float> ReadVector128(long position)
- {
- if (Sse.IsSupported && (position & 15) == 0)
- {
- return Sse.LoadVector128((float*)Translate(position));
- }
- else
- {
- Vector128<float> value = VectorHelper.VectorSingleZero();
-
- value = VectorHelper.VectorInsertInt(ReadUInt64(position + 0), value, 0, 3);
- value = VectorHelper.VectorInsertInt(ReadUInt64(position + 8), value, 1, 3);
-
- return value;
- }
- }
-
- public byte[] ReadBytes(long position, long size)
- {
- long endAddr = position + size;
-
- if ((ulong)size > int.MaxValue)
- {
- throw new ArgumentOutOfRangeException(nameof(size));
- }
-
- if ((ulong)endAddr < (ulong)position)
- {
- throw new ArgumentOutOfRangeException(nameof(position));
- }
-
- byte[] data = new byte[size];
-
- int offset = 0;
-
- while ((ulong)position < (ulong)endAddr)
- {
- long pageLimit = (position + PageSize) & ~(long)PageMask;
-
- if ((ulong)pageLimit > (ulong)endAddr)
- {
- pageLimit = endAddr;
- }
-
- int copySize = (int)(pageLimit - position);
-
- Marshal.Copy(Translate(position), data, offset, copySize);
-
- position += copySize;
- offset += copySize;
- }
-
- return data;
- }
-
- public void ReadBytes(long position, byte[] data, int startIndex, int size)
- {
- // Note: This will be moved later.
- long endAddr = position + size;
-
- if ((ulong)size > int.MaxValue)
- {
- throw new ArgumentOutOfRangeException(nameof(size));
- }
-
- if ((ulong)endAddr < (ulong)position)
- {
- throw new ArgumentOutOfRangeException(nameof(position));
- }
-
- int offset = startIndex;
-
- while ((ulong)position < (ulong)endAddr)
- {
- long pageLimit = (position + PageSize) & ~(long)PageMask;
-
- if ((ulong)pageLimit > (ulong)endAddr)
- {
- pageLimit = endAddr;
- }
-
- int copySize = (int)(pageLimit - position);
-
- Marshal.Copy(Translate(position), data, offset, copySize);
-
- position += copySize;
- offset += copySize;
- }
- }
-
- public void WriteSByte(long position, sbyte value)
- {
- WriteByte(position, (byte)value);
- }
-
- public void WriteInt16(long position, short value)
- {
- WriteUInt16(position, (ushort)value);
- }
-
- public void WriteInt32(long position, int value)
- {
- WriteUInt32(position, (uint)value);
- }
-
- public void WriteInt64(long position, long value)
- {
- WriteUInt64(position, (ulong)value);
- }
-
- public void WriteByte(long position, byte value)
- {
- *((byte*)TranslateWrite(position)) = value;
- }
-
- public void WriteUInt16(long position, ushort value)
- {
- if ((position & 1) == 0)
- {
- *((ushort*)TranslateWrite(position)) = value;
- }
- else
- {
- WriteByte(position + 0, (byte)(value >> 0));
- WriteByte(position + 1, (byte)(value >> 8));
- }
- }
-
- public void WriteUInt32(long position, uint value)
- {
- if ((position & 3) == 0)
- {
- *((uint*)TranslateWrite(position)) = value;
- }
- else
- {
- WriteUInt16(position + 0, (ushort)(value >> 0));
- WriteUInt16(position + 2, (ushort)(value >> 16));
- }
- }
-
- public void WriteUInt64(long position, ulong value)
- {
- if ((position & 7) == 0)
- {
- *((ulong*)TranslateWrite(position)) = value;
- }
- else
- {
- WriteUInt32(position + 0, (uint)(value >> 0));
- WriteUInt32(position + 4, (uint)(value >> 32));
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void WriteVector8(long position, Vector128<float> value)
- {
- if (Sse41.IsSupported)
- {
- WriteByte(position, Sse41.Extract(Sse.StaticCast<float, byte>(value), 0));
- }
- else if (Sse2.IsSupported)
- {
- WriteByte(position, (byte)Sse2.Extract(Sse.StaticCast<float, ushort>(value), 0));
- }
- else
- {
- WriteByte(position, (byte)VectorHelper.VectorExtractIntZx(value, 0, 0));
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void WriteVector16(long position, Vector128<float> value)
- {
- if (Sse2.IsSupported)
- {
- WriteUInt16(position, Sse2.Extract(Sse.StaticCast<float, ushort>(value), 0));
- }
- else
- {
- WriteUInt16(position, (ushort)VectorHelper.VectorExtractIntZx(value, 0, 1));
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void WriteVector32(long position, Vector128<float> value)
- {
- if (Sse.IsSupported && (position & 3) == 0)
- {
- Sse.StoreScalar((float*)TranslateWrite(position), value);
- }
- else
- {
- WriteUInt32(position, (uint)VectorHelper.VectorExtractIntZx(value, 0, 2));
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void WriteVector64(long position, Vector128<float> value)
- {
- if (Sse2.IsSupported && (position & 7) == 0)
- {
- Sse2.StoreScalar((double*)TranslateWrite(position), Sse.StaticCast<float, double>(value));
- }
- else
- {
- WriteUInt64(position, VectorHelper.VectorExtractIntZx(value, 0, 3));
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void WriteVector128Internal(long position, Vector128<float> value)
- {
- if (Sse.IsSupported && (position & 15) == 0)
- {
- Sse.Store((float*)TranslateWrite(position), value);
- }
- else
- {
- WriteUInt64(position + 0, VectorHelper.VectorExtractIntZx(value, 0, 3));
- WriteUInt64(position + 8, VectorHelper.VectorExtractIntZx(value, 1, 3));
- }
- }
-
- public void WriteVector128(long position, ARMeilleure.State.V128 value)
- {
- WriteUInt64(position + 0, value.GetUInt64(0));
- WriteUInt64(position + 8, value.GetUInt64(1));
- }
-
- public void WriteBytes(long position, byte[] data)
- {
- long endAddr = position + data.Length;
-
- if ((ulong)endAddr < (ulong)position)
- {
- throw new ArgumentOutOfRangeException(nameof(position));
- }
-
- int offset = 0;
-
- while ((ulong)position < (ulong)endAddr)
- {
- long pageLimit = (position + PageSize) & ~(long)PageMask;
-
- if ((ulong)pageLimit > (ulong)endAddr)
- {
- pageLimit = endAddr;
- }
-
- int copySize = (int)(pageLimit - position);
-
- Marshal.Copy(data, offset, TranslateWrite(position), copySize);
-
- position += copySize;
- offset += copySize;
- }
- }
-
- public void WriteBytes(long position, byte[] data, int startIndex, int size)
- {
- // Note: This will be moved later.
- long endAddr = position + size;
-
- if ((ulong)endAddr < (ulong)position)
- {
- throw new ArgumentOutOfRangeException(nameof(position));
- }
-
- int offset = startIndex;
-
- while ((ulong)position < (ulong)endAddr)
- {
- long pageLimit = (position + PageSize) & ~(long)PageMask;
-
- if ((ulong)pageLimit > (ulong)endAddr)
- {
- pageLimit = endAddr;
- }
-
- int copySize = (int)(pageLimit - position);
-
- Marshal.Copy(data, offset, Translate(position), copySize);
-
- position += copySize;
- offset += copySize;
- }
- }
-
- public void CopyBytes(long src, long dst, long size)
- {
- // Note: This will be moved later.
- if (IsContiguous(src, size) &&
- IsContiguous(dst, size))
- {
- byte* srcPtr = (byte*)Translate(src);
- byte* dstPtr = (byte*)Translate(dst);
-
- Buffer.MemoryCopy(srcPtr, dstPtr, size, size);
- }
- else
- {
- WriteBytes(dst, ReadBytes(src, size));
- }
- }
-
- public void Dispose()
- {
- Dispose(true);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- IntPtr ptr = Interlocked.Exchange(ref _pageTable, IntPtr.Zero);
-
- if (ptr != IntPtr.Zero)
- {
- FreePageTableEntry(ptr, PageBits);
- }
- }
-
- private void FreePageTableEntry(IntPtr ptr, int levelBitEnd)
- {
- levelBitEnd += PtLevelBits;
-
- if (levelBitEnd >= AddressSpaceBits)
- {
- Free(ptr);
-
- return;
- }
-
- for (int index = 0; index < PtLevelSize; index++)
- {
- IntPtr ptePtr = ((IntPtr*)ptr)[index];
-
- if (ptePtr != IntPtr.Zero)
- {
- FreePageTableEntry(ptePtr, levelBitEnd);
- }
- }
-
- Free(ptr);
- }
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/Memory/MemoryProtection.cs b/ChocolArm64/Memory/MemoryProtection.cs
deleted file mode 100644
index d0874bfc..00000000
--- a/ChocolArm64/Memory/MemoryProtection.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-
-namespace ChocolArm64.Memory
-{
- [Flags]
- public enum MemoryProtection
- {
- None = 0,
- Read = 1 << 0,
- Write = 1 << 1,
- Execute = 1 << 2,
-
- ReadAndWrite = Read | Write,
- ReadAndExecute = Read | Execute
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/Memory/MemoryProtectionException.cs b/ChocolArm64/Memory/MemoryProtectionException.cs
deleted file mode 100644
index 3d2cebad..00000000
--- a/ChocolArm64/Memory/MemoryProtectionException.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System;
-
-namespace ChocolArm64.Memory
-{
- class MemoryProtectionException : Exception
- {
- public MemoryProtectionException(MemoryProtection protection) :
- base($"Failed to set memory protection to \"{protection}\".") { }
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/OpCodeTable.cs b/ChocolArm64/OpCodeTable.cs
deleted file mode 100644
index 94272d51..00000000
--- a/ChocolArm64/OpCodeTable.cs
+++ /dev/null
@@ -1,792 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.Instructions;
-using ChocolArm64.State;
-using System;
-using System.Collections.Generic;
-
-namespace ChocolArm64
-{
- static class OpCodeTable
- {
- private const int FastLookupSize = 0x1000;
-
- private class InstInfo
- {
- public int Mask;
- public int Value;
-
- public Inst Inst;
-
- public InstInfo(int mask, int value, Inst inst)
- {
- Mask = mask;
- Value = value;
- Inst = inst;
- }
- }
-
- private static List<InstInfo> _allInstA32 = new List<InstInfo>();
- private static List<InstInfo> _allInstT32 = new List<InstInfo>();
- private static List<InstInfo> _allInstA64 = new List<InstInfo>();
-
- private static InstInfo[][] _instA32FastLookup = new InstInfo[FastLookupSize][];
- private static InstInfo[][] _instT32FastLookup = new InstInfo[FastLookupSize][];
- private static InstInfo[][] _instA64FastLookup = new InstInfo[FastLookupSize][];
-
- static OpCodeTable()
- {
-#region "OpCode Table (AArch32)"
- // Integer
- SetA32("<<<<0010100xxxxxxxxxxxxxxxxxxxxx", InstEmit32.Add, typeof(OpCode32AluImm));
- SetA32("<<<<0000100xxxxxxxxxxxxxxxx0xxxx", InstEmit32.Add, typeof(OpCode32AluRsImm));
- SetA32("<<<<1010xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit32.B, typeof(OpCode32BImm));
- SetA32("<<<<1011xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit32.Bl, typeof(OpCode32BImm));
- SetA32("1111101xxxxxxxxxxxxxxxxxxxxxxxxx", InstEmit32.Blx, typeof(OpCode32BImm));
- SetA32("<<<<000100101111111111110001xxxx", InstEmit32.Bx, typeof(OpCode32BReg));
- SetT32("010001110xxxx000", InstEmit32.Bx, typeof(OpCodeT16BReg));
- SetA32("<<<<00110101xxxx0000xxxxxxxxxxxx", InstEmit32.Cmp, typeof(OpCode32AluImm));
- SetA32("<<<<00010101xxxx0000xxxxxxx0xxxx", InstEmit32.Cmp, typeof(OpCode32AluRsImm));
- SetA32("<<<<100xx0x1xxxxxxxxxxxxxxxxxxxx", InstEmit32.Ldm, typeof(OpCode32MemMult));
- SetA32("<<<<010xx0x1xxxxxxxxxxxxxxxxxxxx", InstEmit32.Ldr, typeof(OpCode32MemImm));
- SetA32("<<<<010xx1x1xxxxxxxxxxxxxxxxxxxx", InstEmit32.Ldrb, typeof(OpCode32MemImm));
- SetA32("<<<<000xx1x0xxxxxxxxxxxx1101xxxx", InstEmit32.Ldrd, typeof(OpCode32MemImm8));
- SetA32("<<<<000xx1x1xxxxxxxxxxxx1011xxxx", InstEmit32.Ldrh, typeof(OpCode32MemImm8));
- SetA32("<<<<000xx1x1xxxxxxxxxxxx1101xxxx", InstEmit32.Ldrsb, typeof(OpCode32MemImm8));
- SetA32("<<<<000xx1x1xxxxxxxxxxxx1111xxxx", InstEmit32.Ldrsh, typeof(OpCode32MemImm8));
- SetA32("<<<<0011101x0000xxxxxxxxxxxxxxxx", InstEmit32.Mov, typeof(OpCode32AluImm));
- SetA32("<<<<0001101x0000xxxxxxxxxxx0xxxx", InstEmit32.Mov, typeof(OpCode32AluRsImm));
- SetT32("00100xxxxxxxxxxx", InstEmit32.Mov, typeof(OpCodeT16AluImm8));
- SetA32("<<<<100xx0x0xxxxxxxxxxxxxxxxxxxx", InstEmit32.Stm, typeof(OpCode32MemMult));
- SetA32("<<<<010xx0x0xxxxxxxxxxxxxxxxxxxx", InstEmit32.Str, typeof(OpCode32MemImm));
- SetA32("<<<<010xx1x0xxxxxxxxxxxxxxxxxxxx", InstEmit32.Strb, typeof(OpCode32MemImm));
- SetA32("<<<<000xx1x0xxxxxxxxxxxx1111xxxx", InstEmit32.Strd, typeof(OpCode32MemImm8));
- SetA32("<<<<000xx1x0xxxxxxxxxxxx1011xxxx", InstEmit32.Strh, typeof(OpCode32MemImm8));
- SetA32("<<<<0010010xxxxxxxxxxxxxxxxxxxxx", InstEmit32.Sub, typeof(OpCode32AluImm));
- SetA32("<<<<0000010xxxxxxxxxxxxxxxx0xxxx", InstEmit32.Sub, typeof(OpCode32AluRsImm));
-#endregion
-
-#region "OpCode Table (AArch64)"
- // Integer
- SetA64("x0011010000xxxxx000000xxxxxxxxxx", InstEmit.Adc, typeof(OpCodeAluRs64));
- SetA64("x0111010000xxxxx000000xxxxxxxxxx", InstEmit.Adcs, typeof(OpCodeAluRs64));
- SetA64("x00100010xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Add, typeof(OpCodeAluImm64));
- SetA64("00001011<<0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Add, typeof(OpCodeAluRs64));
- SetA64("10001011<<0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Add, typeof(OpCodeAluRs64));
- SetA64("x0001011001xxxxxxxx0xxxxxxxxxxxx", InstEmit.Add, typeof(OpCodeAluRx64));
- SetA64("x0001011001xxxxxxxx100xxxxxxxxxx", InstEmit.Add, typeof(OpCodeAluRx64));
- SetA64("x01100010xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Adds, typeof(OpCodeAluImm64));
- SetA64("00101011<<0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Adds, typeof(OpCodeAluRs64));
- SetA64("10101011<<0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Adds, typeof(OpCodeAluRs64));
- SetA64("x0101011001xxxxxxxx0xxxxxxxxxxxx", InstEmit.Adds, typeof(OpCodeAluRx64));
- SetA64("x0101011001xxxxxxxx100xxxxxxxxxx", InstEmit.Adds, typeof(OpCodeAluRx64));
- SetA64("0xx10000xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Adr, typeof(OpCodeAdr64));
- SetA64("1xx10000xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Adrp, typeof(OpCodeAdr64));
- SetA64("0001001000xxxxxxxxxxxxxxxxxxxxxx", InstEmit.And, typeof(OpCodeAluImm64));
- SetA64("100100100xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.And, typeof(OpCodeAluImm64));
- SetA64("00001010xx0xxxxx0xxxxxxxxxxxxxxx", InstEmit.And, typeof(OpCodeAluRs64));
- SetA64("10001010xx0xxxxxxxxxxxxxxxxxxxxx", InstEmit.And, typeof(OpCodeAluRs64));
- SetA64("0111001000xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ands, typeof(OpCodeAluImm64));
- SetA64("111100100xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ands, typeof(OpCodeAluImm64));
- SetA64("01101010xx0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Ands, typeof(OpCodeAluRs64));
- SetA64("11101010xx0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Ands, typeof(OpCodeAluRs64));
- SetA64("x0011010110xxxxx001010xxxxxxxxxx", InstEmit.Asrv, typeof(OpCodeAluRs64));
- SetA64("000101xxxxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.B, typeof(OpCodeBImmAl64));
- SetA64("01010100xxxxxxxxxxxxxxxxxxx0xxxx", InstEmit.B_Cond, typeof(OpCodeBImmCond64));
- SetA64("00110011000xxxxx0xxxxxxxxxxxxxxx", InstEmit.Bfm, typeof(OpCodeBfm64));
- SetA64("1011001101xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Bfm, typeof(OpCodeBfm64));
- SetA64("00001010xx1xxxxx0xxxxxxxxxxxxxxx", InstEmit.Bic, typeof(OpCodeAluRs64));
- SetA64("10001010xx1xxxxxxxxxxxxxxxxxxxxx", InstEmit.Bic, typeof(OpCodeAluRs64));
- SetA64("01101010xx1xxxxx0xxxxxxxxxxxxxxx", InstEmit.Bics, typeof(OpCodeAluRs64));
- SetA64("11101010xx1xxxxxxxxxxxxxxxxxxxxx", InstEmit.Bics, typeof(OpCodeAluRs64));
- SetA64("100101xxxxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Bl, typeof(OpCodeBImmAl64));
- SetA64("1101011000111111000000xxxxx00000", InstEmit.Blr, typeof(OpCodeBReg64));
- SetA64("1101011000011111000000xxxxx00000", InstEmit.Br, typeof(OpCodeBReg64));
- SetA64("11010100001xxxxxxxxxxxxxxxx00000", InstEmit.Brk, typeof(OpCodeException64));
- SetA64("x0110101xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Cbnz, typeof(OpCodeBImmCmp64));
- SetA64("x0110100xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Cbz, typeof(OpCodeBImmCmp64));
- SetA64("x0111010010xxxxxxxxx10xxxxx0xxxx", InstEmit.Ccmn, typeof(OpCodeCcmpImm64));
- SetA64("x0111010010xxxxxxxxx00xxxxx0xxxx", InstEmit.Ccmn, typeof(OpCodeCcmpReg64));
- SetA64("x1111010010xxxxxxxxx10xxxxx0xxxx", InstEmit.Ccmp, typeof(OpCodeCcmpImm64));
- SetA64("x1111010010xxxxxxxxx00xxxxx0xxxx", InstEmit.Ccmp, typeof(OpCodeCcmpReg64));
- SetA64("11010101000000110011xxxx01011111", InstEmit.Clrex, typeof(OpCodeSystem64));
- SetA64("x101101011000000000101xxxxxxxxxx", InstEmit.Cls, typeof(OpCodeAlu64));
- SetA64("x101101011000000000100xxxxxxxxxx", InstEmit.Clz, typeof(OpCodeAlu64));
- SetA64("00011010110xxxxx010000xxxxxxxxxx", InstEmit.Crc32b, typeof(OpCodeAluRs64));
- SetA64("00011010110xxxxx010001xxxxxxxxxx", InstEmit.Crc32h, typeof(OpCodeAluRs64));
- SetA64("00011010110xxxxx010010xxxxxxxxxx", InstEmit.Crc32w, typeof(OpCodeAluRs64));
- SetA64("10011010110xxxxx010011xxxxxxxxxx", InstEmit.Crc32x, typeof(OpCodeAluRs64));
- SetA64("00011010110xxxxx010100xxxxxxxxxx", InstEmit.Crc32cb, typeof(OpCodeAluRs64));
- SetA64("00011010110xxxxx010101xxxxxxxxxx", InstEmit.Crc32ch, typeof(OpCodeAluRs64));
- SetA64("00011010110xxxxx010110xxxxxxxxxx", InstEmit.Crc32cw, typeof(OpCodeAluRs64));
- SetA64("10011010110xxxxx010111xxxxxxxxxx", InstEmit.Crc32cx, typeof(OpCodeAluRs64));
- SetA64("x0011010100xxxxxxxxx00xxxxxxxxxx", InstEmit.Csel, typeof(OpCodeCsel64));
- SetA64("x0011010100xxxxxxxxx01xxxxxxxxxx", InstEmit.Csinc, typeof(OpCodeCsel64));
- SetA64("x1011010100xxxxxxxxx00xxxxxxxxxx", InstEmit.Csinv, typeof(OpCodeCsel64));
- SetA64("x1011010100xxxxxxxxx01xxxxxxxxxx", InstEmit.Csneg, typeof(OpCodeCsel64));
- SetA64("11010101000000110011xxxx10111111", InstEmit.Dmb, typeof(OpCodeSystem64));
- SetA64("11010101000000110011xxxx10011111", InstEmit.Dsb, typeof(OpCodeSystem64));
- SetA64("01001010xx1xxxxx0xxxxxxxxxxxxxxx", InstEmit.Eon, typeof(OpCodeAluRs64));
- SetA64("11001010xx1xxxxxxxxxxxxxxxxxxxxx", InstEmit.Eon, typeof(OpCodeAluRs64));
- SetA64("0101001000xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Eor, typeof(OpCodeAluImm64));
- SetA64("110100100xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Eor, typeof(OpCodeAluImm64));
- SetA64("01001010xx0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Eor, typeof(OpCodeAluRs64));
- SetA64("11001010xx0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Eor, typeof(OpCodeAluRs64));
- SetA64("00010011100xxxxx0xxxxxxxxxxxxxxx", InstEmit.Extr, typeof(OpCodeAluRs64));
- SetA64("10010011110xxxxxxxxxxxxxxxxxxxxx", InstEmit.Extr, typeof(OpCodeAluRs64));
- SetA64("11010101000000110010xxxxxxx11111", InstEmit.Hint, typeof(OpCodeSystem64));
- SetA64("11010101000000110011xxxx11011111", InstEmit.Isb, typeof(OpCodeSystem64));
- SetA64("xx001000110xxxxx1xxxxxxxxxxxxxxx", InstEmit.Ldar, typeof(OpCodeMemEx64));
- SetA64("1x001000011xxxxx1xxxxxxxxxxxxxxx", InstEmit.Ldaxp, typeof(OpCodeMemEx64));
- SetA64("xx001000010xxxxx1xxxxxxxxxxxxxxx", InstEmit.Ldaxr, typeof(OpCodeMemEx64));
- SetA64("<<10100xx1xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldp, typeof(OpCodeMemPair64));
- SetA64("xx111000010xxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldr, typeof(OpCodeMemImm64));
- SetA64("xx11100101xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldr, typeof(OpCodeMemImm64));
- SetA64("xx111000011xxxxxxxxx10xxxxxxxxxx", InstEmit.Ldr, typeof(OpCodeMemReg64));
- SetA64("xx011000xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldr_Literal, typeof(OpCodeMemLit64));
- SetA64("0x1110001x0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldrs, typeof(OpCodeMemImm64));
- SetA64("0x1110011xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldrs, typeof(OpCodeMemImm64));
- SetA64("10111000100xxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldrs, typeof(OpCodeMemImm64));
- SetA64("1011100110xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldrs, typeof(OpCodeMemImm64));
- SetA64("0x1110001x1xxxxxxxxx10xxxxxxxxxx", InstEmit.Ldrs, typeof(OpCodeMemReg64));
- SetA64("10111000101xxxxxxxxx10xxxxxxxxxx", InstEmit.Ldrs, typeof(OpCodeMemReg64));
- SetA64("xx001000010xxxxx0xxxxxxxxxxxxxxx", InstEmit.Ldxr, typeof(OpCodeMemEx64));
- SetA64("1x001000011xxxxx0xxxxxxxxxxxxxxx", InstEmit.Ldxp, typeof(OpCodeMemEx64));
- SetA64("x0011010110xxxxx001000xxxxxxxxxx", InstEmit.Lslv, typeof(OpCodeAluRs64));
- SetA64("x0011010110xxxxx001001xxxxxxxxxx", InstEmit.Lsrv, typeof(OpCodeAluRs64));
- SetA64("x0011011000xxxxx0xxxxxxxxxxxxxxx", InstEmit.Madd, typeof(OpCodeMul64));
- SetA64("0111001010xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Movk, typeof(OpCodeMov64));
- SetA64("111100101xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Movk, typeof(OpCodeMov64));
- SetA64("0001001010xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Movn, typeof(OpCodeMov64));
- SetA64("100100101xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Movn, typeof(OpCodeMov64));
- SetA64("0101001010xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Movz, typeof(OpCodeMov64));
- SetA64("110100101xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Movz, typeof(OpCodeMov64));
- SetA64("110101010011xxxxxxxxxxxxxxxxxxxx", InstEmit.Mrs, typeof(OpCodeSystem64));
- SetA64("110101010001xxxxxxxxxxxxxxxxxxxx", InstEmit.Msr, typeof(OpCodeSystem64));
- SetA64("x0011011000xxxxx1xxxxxxxxxxxxxxx", InstEmit.Msub, typeof(OpCodeMul64));
- SetA64("11010101000000110010000000011111", InstEmit.Nop, typeof(OpCodeSystem64));
- SetA64("00101010xx1xxxxx0xxxxxxxxxxxxxxx", InstEmit.Orn, typeof(OpCodeAluRs64));
- SetA64("10101010xx1xxxxxxxxxxxxxxxxxxxxx", InstEmit.Orn, typeof(OpCodeAluRs64));
- SetA64("0011001000xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Orr, typeof(OpCodeAluImm64));
- SetA64("101100100xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Orr, typeof(OpCodeAluImm64));
- SetA64("00101010xx0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Orr, typeof(OpCodeAluRs64));
- SetA64("10101010xx0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Orr, typeof(OpCodeAluRs64));
- SetA64("1111100110xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Pfrm, typeof(OpCodeMemImm64));
- SetA64("11111000100xxxxxxxxx00xxxxxxxxxx", InstEmit.Pfrm, typeof(OpCodeMemImm64));
- SetA64("11011000xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Pfrm, typeof(OpCodeMemLit64));
- SetA64("x101101011000000000000xxxxxxxxxx", InstEmit.Rbit, typeof(OpCodeAlu64));
- SetA64("1101011001011111000000xxxxx00000", InstEmit.Ret, typeof(OpCodeBReg64));
- SetA64("x101101011000000000001xxxxxxxxxx", InstEmit.Rev16, typeof(OpCodeAlu64));
- SetA64("x101101011000000000010xxxxxxxxxx", InstEmit.Rev32, typeof(OpCodeAlu64));
- SetA64("1101101011000000000011xxxxxxxxxx", InstEmit.Rev64, typeof(OpCodeAlu64));
- SetA64("x0011010110xxxxx001011xxxxxxxxxx", InstEmit.Rorv, typeof(OpCodeAluRs64));
- SetA64("x1011010000xxxxx000000xxxxxxxxxx", InstEmit.Sbc, typeof(OpCodeAluRs64));
- SetA64("x1111010000xxxxx000000xxxxxxxxxx", InstEmit.Sbcs, typeof(OpCodeAluRs64));
- SetA64("00010011000xxxxx0xxxxxxxxxxxxxxx", InstEmit.Sbfm, typeof(OpCodeBfm64));
- SetA64("1001001101xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Sbfm, typeof(OpCodeBfm64));
- SetA64("x0011010110xxxxx000011xxxxxxxxxx", InstEmit.Sdiv, typeof(OpCodeAluRs64));
- SetA64("10011011001xxxxx0xxxxxxxxxxxxxxx", InstEmit.Smaddl, typeof(OpCodeMul64));
- SetA64("10011011001xxxxx1xxxxxxxxxxxxxxx", InstEmit.Smsubl, typeof(OpCodeMul64));
- SetA64("10011011010xxxxx0xxxxxxxxxxxxxxx", InstEmit.Smulh, typeof(OpCodeMul64));
- SetA64("xx001000100xxxxx1xxxxxxxxxxxxxxx", InstEmit.Stlr, typeof(OpCodeMemEx64));
- SetA64("1x001000001xxxxx1xxxxxxxxxxxxxxx", InstEmit.Stlxp, typeof(OpCodeMemEx64));
- SetA64("xx001000000xxxxx1xxxxxxxxxxxxxxx", InstEmit.Stlxr, typeof(OpCodeMemEx64));
- SetA64("x010100xx0xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Stp, typeof(OpCodeMemPair64));
- SetA64("xx111000000xxxxxxxxxxxxxxxxxxxxx", InstEmit.Str, typeof(OpCodeMemImm64));
- SetA64("xx11100100xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Str, typeof(OpCodeMemImm64));
- SetA64("xx111000001xxxxxxxxx10xxxxxxxxxx", InstEmit.Str, typeof(OpCodeMemReg64));
- SetA64("1x001000001xxxxx0xxxxxxxxxxxxxxx", InstEmit.Stxp, typeof(OpCodeMemEx64));
- SetA64("xx001000000xxxxx0xxxxxxxxxxxxxxx", InstEmit.Stxr, typeof(OpCodeMemEx64));
- SetA64("x10100010xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Sub, typeof(OpCodeAluImm64));
- SetA64("01001011<<0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Sub, typeof(OpCodeAluRs64));
- SetA64("11001011<<0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Sub, typeof(OpCodeAluRs64));
- SetA64("x1001011001xxxxxxxx0xxxxxxxxxxxx", InstEmit.Sub, typeof(OpCodeAluRx64));
- SetA64("x1001011001xxxxxxxx100xxxxxxxxxx", InstEmit.Sub, typeof(OpCodeAluRx64));
- SetA64("x11100010xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Subs, typeof(OpCodeAluImm64));
- SetA64("01101011<<0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Subs, typeof(OpCodeAluRs64));
- SetA64("11101011<<0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Subs, typeof(OpCodeAluRs64));
- SetA64("x1101011001xxxxxxxx0xxxxxxxxxxxx", InstEmit.Subs, typeof(OpCodeAluRx64));
- SetA64("x1101011001xxxxxxxx100xxxxxxxxxx", InstEmit.Subs, typeof(OpCodeAluRx64));
- SetA64("11010100000xxxxxxxxxxxxxxxx00001", InstEmit.Svc, typeof(OpCodeException64));
- SetA64("1101010100001xxxxxxxxxxxxxxxxxxx", InstEmit.Sys, typeof(OpCodeSystem64));
- SetA64("x0110111xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Tbnz, typeof(OpCodeBImmTest64));
- SetA64("x0110110xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Tbz, typeof(OpCodeBImmTest64));
- SetA64("01010011000xxxxx0xxxxxxxxxxxxxxx", InstEmit.Ubfm, typeof(OpCodeBfm64));
- SetA64("1101001101xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ubfm, typeof(OpCodeBfm64));
- SetA64("x0011010110xxxxx000010xxxxxxxxxx", InstEmit.Udiv, typeof(OpCodeAluRs64));
- SetA64("10011011101xxxxx0xxxxxxxxxxxxxxx", InstEmit.Umaddl, typeof(OpCodeMul64));
- SetA64("10011011101xxxxx1xxxxxxxxxxxxxxx", InstEmit.Umsubl, typeof(OpCodeMul64));
- SetA64("10011011110xxxxx0xxxxxxxxxxxxxxx", InstEmit.Umulh, typeof(OpCodeMul64));
-
- // Vector
- SetA64("0101111011100000101110xxxxxxxxxx", InstEmit.Abs_S, typeof(OpCodeSimd64));
- SetA64("0>001110<<100000101110xxxxxxxxxx", InstEmit.Abs_V, typeof(OpCodeSimd64));
- SetA64("01011110111xxxxx100001xxxxxxxxxx", InstEmit.Add_S, typeof(OpCodeSimdReg64));
- SetA64("0>001110<<1xxxxx100001xxxxxxxxxx", InstEmit.Add_V, typeof(OpCodeSimdReg64));
- SetA64("0x001110<<1xxxxx010000xxxxxxxxxx", InstEmit.Addhn_V, typeof(OpCodeSimdReg64));
- SetA64("0101111011110001101110xxxxxxxxxx", InstEmit.Addp_S, typeof(OpCodeSimd64));
- SetA64("0>001110<<1xxxxx101111xxxxxxxxxx", InstEmit.Addp_V, typeof(OpCodeSimdReg64));
- SetA64("000011100x110001101110xxxxxxxxxx", InstEmit.Addv_V, typeof(OpCodeSimd64));
- SetA64("01001110<<110001101110xxxxxxxxxx", InstEmit.Addv_V, typeof(OpCodeSimd64));
- SetA64("0100111000101000010110xxxxxxxxxx", InstEmit.Aesd_V, typeof(OpCodeSimd64));
- SetA64("0100111000101000010010xxxxxxxxxx", InstEmit.Aese_V, typeof(OpCodeSimd64));
- SetA64("0100111000101000011110xxxxxxxxxx", InstEmit.Aesimc_V, typeof(OpCodeSimd64));
- SetA64("0100111000101000011010xxxxxxxxxx", InstEmit.Aesmc_V, typeof(OpCodeSimd64));
- SetA64("0x001110001xxxxx000111xxxxxxxxxx", InstEmit.And_V, typeof(OpCodeSimdReg64));
- SetA64("0x001110011xxxxx000111xxxxxxxxxx", InstEmit.Bic_V, typeof(OpCodeSimdReg64));
- SetA64("0x10111100000xxx0xx101xxxxxxxxxx", InstEmit.Bic_Vi, typeof(OpCodeSimdImm64));
- SetA64("0x10111100000xxx10x101xxxxxxxxxx", InstEmit.Bic_Vi, typeof(OpCodeSimdImm64));
- SetA64("0x101110111xxxxx000111xxxxxxxxxx", InstEmit.Bif_V, typeof(OpCodeSimdReg64));
- SetA64("0x101110101xxxxx000111xxxxxxxxxx", InstEmit.Bit_V, typeof(OpCodeSimdReg64));
- SetA64("0x101110011xxxxx000111xxxxxxxxxx", InstEmit.Bsl_V, typeof(OpCodeSimdReg64));
- SetA64("0x001110<<100000010010xxxxxxxxxx", InstEmit.Cls_V, typeof(OpCodeSimd64));
- SetA64("0x101110<<100000010010xxxxxxxxxx", InstEmit.Clz_V, typeof(OpCodeSimd64));
- SetA64("01111110111xxxxx100011xxxxxxxxxx", InstEmit.Cmeq_S, typeof(OpCodeSimdReg64));
- SetA64("0101111011100000100110xxxxxxxxxx", InstEmit.Cmeq_S, typeof(OpCodeSimd64));
- SetA64("0>101110<<1xxxxx100011xxxxxxxxxx", InstEmit.Cmeq_V, typeof(OpCodeSimdReg64));
- SetA64("0>001110<<100000100110xxxxxxxxxx", InstEmit.Cmeq_V, typeof(OpCodeSimd64));
- SetA64("01011110111xxxxx001111xxxxxxxxxx", InstEmit.Cmge_S, typeof(OpCodeSimdReg64));
- SetA64("0111111011100000100010xxxxxxxxxx", InstEmit.Cmge_S, typeof(OpCodeSimd64));
- SetA64("0>001110<<1xxxxx001111xxxxxxxxxx", InstEmit.Cmge_V, typeof(OpCodeSimdReg64));
- SetA64("0>101110<<100000100010xxxxxxxxxx", InstEmit.Cmge_V, typeof(OpCodeSimd64));
- SetA64("01011110111xxxxx001101xxxxxxxxxx", InstEmit.Cmgt_S, typeof(OpCodeSimdReg64));
- SetA64("0101111011100000100010xxxxxxxxxx", InstEmit.Cmgt_S, typeof(OpCodeSimd64));
- SetA64("0>001110<<1xxxxx001101xxxxxxxxxx", InstEmit.Cmgt_V, typeof(OpCodeSimdReg64));
- SetA64("0>001110<<100000100010xxxxxxxxxx", InstEmit.Cmgt_V, typeof(OpCodeSimd64));
- SetA64("01111110111xxxxx001101xxxxxxxxxx", InstEmit.Cmhi_S, typeof(OpCodeSimdReg64));
- SetA64("0>101110<<1xxxxx001101xxxxxxxxxx", InstEmit.Cmhi_V, typeof(OpCodeSimdReg64));
- SetA64("01111110111xxxxx001111xxxxxxxxxx", InstEmit.Cmhs_S, typeof(OpCodeSimdReg64));
- SetA64("0>101110<<1xxxxx001111xxxxxxxxxx", InstEmit.Cmhs_V, typeof(OpCodeSimdReg64));
- SetA64("0111111011100000100110xxxxxxxxxx", InstEmit.Cmle_S, typeof(OpCodeSimd64));
- SetA64("0>101110<<100000100110xxxxxxxxxx", InstEmit.Cmle_V, typeof(OpCodeSimd64));
- SetA64("0101111011100000101010xxxxxxxxxx", InstEmit.Cmlt_S, typeof(OpCodeSimd64));
- SetA64("0>001110<<100000101010xxxxxxxxxx", InstEmit.Cmlt_V, typeof(OpCodeSimd64));
- SetA64("01011110111xxxxx100011xxxxxxxxxx", InstEmit.Cmtst_S, typeof(OpCodeSimdReg64));
- SetA64("0>001110<<1xxxxx100011xxxxxxxxxx", InstEmit.Cmtst_V, typeof(OpCodeSimdReg64));
- SetA64("0x00111000100000010110xxxxxxxxxx", InstEmit.Cnt_V, typeof(OpCodeSimd64));
- SetA64("0>001110000x<>>>000011xxxxxxxxxx", InstEmit.Dup_Gp, typeof(OpCodeSimdIns64));
- SetA64("01011110000xxxxx000001xxxxxxxxxx", InstEmit.Dup_S, typeof(OpCodeSimdIns64));
- SetA64("0>001110000x<>>>000001xxxxxxxxxx", InstEmit.Dup_V, typeof(OpCodeSimdIns64));
- SetA64("0x101110001xxxxx000111xxxxxxxxxx", InstEmit.Eor_V, typeof(OpCodeSimdReg64));
- SetA64("0>101110000xxxxx0<xxx0xxxxxxxxxx", InstEmit.Ext_V, typeof(OpCodeSimdExt64));
- SetA64("011111101x1xxxxx110101xxxxxxxxxx", InstEmit.Fabd_S, typeof(OpCodeSimdReg64));
- SetA64("0>1011101<1xxxxx110101xxxxxxxxxx", InstEmit.Fabd_V, typeof(OpCodeSimdReg64));
- SetA64("000111100x100000110000xxxxxxxxxx", InstEmit.Fabs_S, typeof(OpCodeSimd64));
- SetA64("0>0011101<100000111110xxxxxxxxxx", InstEmit.Fabs_V, typeof(OpCodeSimd64));
- SetA64("000111100x1xxxxx001010xxxxxxxxxx", InstEmit.Fadd_S, typeof(OpCodeSimdReg64));
- SetA64("0>0011100<1xxxxx110101xxxxxxxxxx", InstEmit.Fadd_V, typeof(OpCodeSimdReg64));
- SetA64("011111100x110000110110xxxxxxxxxx", InstEmit.Faddp_S, typeof(OpCodeSimd64));
- SetA64("0>1011100<1xxxxx110101xxxxxxxxxx", InstEmit.Faddp_V, typeof(OpCodeSimdReg64));
- SetA64("000111100x1xxxxxxxxx01xxxxx0xxxx", InstEmit.Fccmp_S, typeof(OpCodeSimdFcond64));
- SetA64("000111100x1xxxxxxxxx01xxxxx1xxxx", InstEmit.Fccmpe_S, typeof(OpCodeSimdFcond64));
- SetA64("010111100x1xxxxx111001xxxxxxxxxx", InstEmit.Fcmeq_S, typeof(OpCodeSimdReg64));
- SetA64("010111101x100000110110xxxxxxxxxx", InstEmit.Fcmeq_S, typeof(OpCodeSimd64));
- SetA64("0>0011100<1xxxxx111001xxxxxxxxxx", InstEmit.Fcmeq_V, typeof(OpCodeSimdReg64));
- SetA64("0>0011101<100000110110xxxxxxxxxx", InstEmit.Fcmeq_V, typeof(OpCodeSimd64));
- SetA64("011111100x1xxxxx111001xxxxxxxxxx", InstEmit.Fcmge_S, typeof(OpCodeSimdReg64));
- SetA64("011111101x100000110010xxxxxxxxxx", InstEmit.Fcmge_S, typeof(OpCodeSimd64));
- SetA64("0>1011100<1xxxxx111001xxxxxxxxxx", InstEmit.Fcmge_V, typeof(OpCodeSimdReg64));
- SetA64("0>1011101<100000110010xxxxxxxxxx", InstEmit.Fcmge_V, typeof(OpCodeSimd64));
- SetA64("011111101x1xxxxx111001xxxxxxxxxx", InstEmit.Fcmgt_S, typeof(OpCodeSimdReg64));
- SetA64("010111101x100000110010xxxxxxxxxx", InstEmit.Fcmgt_S, typeof(OpCodeSimd64));
- SetA64("0>1011101<1xxxxx111001xxxxxxxxxx", InstEmit.Fcmgt_V, typeof(OpCodeSimdReg64));
- SetA64("0>0011101<100000110010xxxxxxxxxx", InstEmit.Fcmgt_V, typeof(OpCodeSimd64));
- SetA64("011111101x100000110110xxxxxxxxxx", InstEmit.Fcmle_S, typeof(OpCodeSimd64));
- SetA64("0>1011101<100000110110xxxxxxxxxx", InstEmit.Fcmle_V, typeof(OpCodeSimd64));
- SetA64("010111101x100000111010xxxxxxxxxx", InstEmit.Fcmlt_S, typeof(OpCodeSimd64));
- SetA64("0>0011101<100000111010xxxxxxxxxx", InstEmit.Fcmlt_V, typeof(OpCodeSimd64));
- SetA64("000111100x1xxxxx001000xxxxx0x000", InstEmit.Fcmp_S, typeof(OpCodeSimdReg64));
- SetA64("000111100x1xxxxx001000xxxxx1x000", InstEmit.Fcmpe_S, typeof(OpCodeSimdReg64));
- SetA64("000111100x1xxxxxxxxx11xxxxxxxxxx", InstEmit.Fcsel_S, typeof(OpCodeSimdFcond64));
- SetA64("00011110xx10001xx10000xxxxxxxxxx", InstEmit.Fcvt_S, typeof(OpCodeSimd64));
- SetA64("x00111100x100100000000xxxxxxxxxx", InstEmit.Fcvtas_Gp, typeof(OpCodeSimdCvt64));
- SetA64("x00111100x100101000000xxxxxxxxxx", InstEmit.Fcvtau_Gp, typeof(OpCodeSimdCvt64));
- SetA64("0x0011100x100001011110xxxxxxxxxx", InstEmit.Fcvtl_V, typeof(OpCodeSimd64));
- SetA64("x00111100x110000000000xxxxxxxxxx", InstEmit.Fcvtms_Gp, typeof(OpCodeSimdCvt64));
- SetA64("x00111100x110001000000xxxxxxxxxx", InstEmit.Fcvtmu_Gp, typeof(OpCodeSimdCvt64));
- SetA64("0x0011100x100001011010xxxxxxxxxx", InstEmit.Fcvtn_V, typeof(OpCodeSimd64));
- SetA64("010111100x100001101010xxxxxxxxxx", InstEmit.Fcvtns_S, typeof(OpCodeSimd64));
- SetA64("0>0011100<100001101010xxxxxxxxxx", InstEmit.Fcvtns_V, typeof(OpCodeSimd64));
- SetA64("011111100x100001101010xxxxxxxxxx", InstEmit.Fcvtnu_S, typeof(OpCodeSimd64));
- SetA64("0>1011100<100001101010xxxxxxxxxx", InstEmit.Fcvtnu_V, typeof(OpCodeSimd64));
- SetA64("x00111100x101000000000xxxxxxxxxx", InstEmit.Fcvtps_Gp, typeof(OpCodeSimdCvt64));
- SetA64("x00111100x101001000000xxxxxxxxxx", InstEmit.Fcvtpu_Gp, typeof(OpCodeSimdCvt64));
- SetA64("x00111100x111000000000xxxxxxxxxx", InstEmit.Fcvtzs_Gp, typeof(OpCodeSimdCvt64));
- SetA64(">00111100x011000>xxxxxxxxxxxxxxx", InstEmit.Fcvtzs_Gp_Fixed, typeof(OpCodeSimdCvt64));
- SetA64("010111101x100001101110xxxxxxxxxx", InstEmit.Fcvtzs_S, typeof(OpCodeSimd64));
- SetA64("0>0011101<100001101110xxxxxxxxxx", InstEmit.Fcvtzs_V, typeof(OpCodeSimd64));
- SetA64("0x001111001xxxxx111111xxxxxxxxxx", InstEmit.Fcvtzs_V_Fixed, typeof(OpCodeSimdShImm64));
- SetA64("0100111101xxxxxx111111xxxxxxxxxx", InstEmit.Fcvtzs_V_Fixed, typeof(OpCodeSimdShImm64));
- SetA64("x00111100x111001000000xxxxxxxxxx", InstEmit.Fcvtzu_Gp, typeof(OpCodeSimdCvt64));
- SetA64(">00111100x011001>xxxxxxxxxxxxxxx", InstEmit.Fcvtzu_Gp_Fixed, typeof(OpCodeSimdCvt64));
- SetA64("011111101x100001101110xxxxxxxxxx", InstEmit.Fcvtzu_S, typeof(OpCodeSimd64));
- SetA64("0>1011101<100001101110xxxxxxxxxx", InstEmit.Fcvtzu_V, typeof(OpCodeSimd64));
- SetA64("0x101111001xxxxx111111xxxxxxxxxx", InstEmit.Fcvtzu_V_Fixed, typeof(OpCodeSimdShImm64));
- SetA64("0110111101xxxxxx111111xxxxxxxxxx", InstEmit.Fcvtzu_V_Fixed, typeof(OpCodeSimdShImm64));
- SetA64("000111100x1xxxxx000110xxxxxxxxxx", InstEmit.Fdiv_S, typeof(OpCodeSimdReg64));
- SetA64("0>1011100<1xxxxx111111xxxxxxxxxx", InstEmit.Fdiv_V, typeof(OpCodeSimdReg64));
- SetA64("000111110x0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Fmadd_S, typeof(OpCodeSimdReg64));
- SetA64("000111100x1xxxxx010010xxxxxxxxxx", InstEmit.Fmax_S, typeof(OpCodeSimdReg64));
- SetA64("0>0011100<1xxxxx111101xxxxxxxxxx", InstEmit.Fmax_V, typeof(OpCodeSimdReg64));
- SetA64("000111100x1xxxxx011010xxxxxxxxxx", InstEmit.Fmaxnm_S, typeof(OpCodeSimdReg64));
- SetA64("0>0011100<1xxxxx110001xxxxxxxxxx", InstEmit.Fmaxnm_V, typeof(OpCodeSimdReg64));
- SetA64("0>1011100<1xxxxx111101xxxxxxxxxx", InstEmit.Fmaxp_V, typeof(OpCodeSimdReg64));
- SetA64("000111100x1xxxxx010110xxxxxxxxxx", InstEmit.Fmin_S, typeof(OpCodeSimdReg64));
- SetA64("0>0011101<1xxxxx111101xxxxxxxxxx", InstEmit.Fmin_V, typeof(OpCodeSimdReg64));
- SetA64("000111100x1xxxxx011110xxxxxxxxxx", InstEmit.Fminnm_S, typeof(OpCodeSimdReg64));
- SetA64("0>0011101<1xxxxx110001xxxxxxxxxx", InstEmit.Fminnm_V, typeof(OpCodeSimdReg64));
- SetA64("0>1011101<1xxxxx111101xxxxxxxxxx", InstEmit.Fminp_V, typeof(OpCodeSimdReg64));
- SetA64("010111111xxxxxxx0001x0xxxxxxxxxx", InstEmit.Fmla_Se, typeof(OpCodeSimdRegElemF64));
- SetA64("0>0011100<1xxxxx110011xxxxxxxxxx", InstEmit.Fmla_V, typeof(OpCodeSimdReg64));
- SetA64("0>0011111<xxxxxx0001x0xxxxxxxxxx", InstEmit.Fmla_Ve, typeof(OpCodeSimdRegElemF64));
- SetA64("010111111xxxxxxx0101x0xxxxxxxxxx", InstEmit.Fmls_Se, typeof(OpCodeSimdRegElemF64));
- SetA64("0>0011101<1xxxxx110011xxxxxxxxxx", InstEmit.Fmls_V, typeof(OpCodeSimdReg64));
- SetA64("0>0011111<xxxxxx0101x0xxxxxxxxxx", InstEmit.Fmls_Ve, typeof(OpCodeSimdRegElemF64));
- SetA64("000111100x100000010000xxxxxxxxxx", InstEmit.Fmov_S, typeof(OpCodeSimd64));
- SetA64("000111100x1xxxxxxxx10000000xxxxx", InstEmit.Fmov_Si, typeof(OpCodeSimdFmov64));
- SetA64("0x00111100000xxx111101xxxxxxxxxx", InstEmit.Fmov_Vi, typeof(OpCodeSimdImm64));
- SetA64("0110111100000xxx111101xxxxxxxxxx", InstEmit.Fmov_Vi, typeof(OpCodeSimdImm64));
- SetA64("0001111000100110000000xxxxxxxxxx", InstEmit.Fmov_Ftoi, typeof(OpCodeSimd64));
- SetA64("1001111001100110000000xxxxxxxxxx", InstEmit.Fmov_Ftoi, typeof(OpCodeSimd64));
- SetA64("0001111000100111000000xxxxxxxxxx", InstEmit.Fmov_Itof, typeof(OpCodeSimd64));
- SetA64("1001111001100111000000xxxxxxxxxx", InstEmit.Fmov_Itof, typeof(OpCodeSimd64));
- SetA64("1001111010101110000000xxxxxxxxxx", InstEmit.Fmov_Ftoi1, typeof(OpCodeSimd64));
- SetA64("1001111010101111000000xxxxxxxxxx", InstEmit.Fmov_Itof1, typeof(OpCodeSimd64));
- SetA64("000111110x0xxxxx1xxxxxxxxxxxxxxx", InstEmit.Fmsub_S, typeof(OpCodeSimdReg64));
- SetA64("000111100x1xxxxx000010xxxxxxxxxx", InstEmit.Fmul_S, typeof(OpCodeSimdReg64));
- SetA64("010111111xxxxxxx1001x0xxxxxxxxxx", InstEmit.Fmul_Se, typeof(OpCodeSimdRegElemF64));
- SetA64("0>1011100<1xxxxx110111xxxxxxxxxx", InstEmit.Fmul_V, typeof(OpCodeSimdReg64));
- SetA64("0>0011111<xxxxxx1001x0xxxxxxxxxx", InstEmit.Fmul_Ve, typeof(OpCodeSimdRegElemF64));
- SetA64("010111100x1xxxxx110111xxxxxxxxxx", InstEmit.Fmulx_S, typeof(OpCodeSimdReg64));
- SetA64("011111111xxxxxxx1001x0xxxxxxxxxx", InstEmit.Fmulx_Se, typeof(OpCodeSimdRegElemF64));
- SetA64("0>0011100<1xxxxx110111xxxxxxxxxx", InstEmit.Fmulx_V, typeof(OpCodeSimdReg64));
- SetA64("0>1011111<xxxxxx1001x0xxxxxxxxxx", InstEmit.Fmulx_Ve, typeof(OpCodeSimdRegElemF64));
- SetA64("000111100x100001010000xxxxxxxxxx", InstEmit.Fneg_S, typeof(OpCodeSimd64));
- SetA64("0>1011101<100000111110xxxxxxxxxx", InstEmit.Fneg_V, typeof(OpCodeSimd64));
- SetA64("000111110x1xxxxx0xxxxxxxxxxxxxxx", InstEmit.Fnmadd_S, typeof(OpCodeSimdReg64));
- SetA64("000111110x1xxxxx1xxxxxxxxxxxxxxx", InstEmit.Fnmsub_S, typeof(OpCodeSimdReg64));
- SetA64("000111100x1xxxxx100010xxxxxxxxxx", InstEmit.Fnmul_S, typeof(OpCodeSimdReg64));
- SetA64("010111101x100001110110xxxxxxxxxx", InstEmit.Frecpe_S, typeof(OpCodeSimd64));
- SetA64("0>0011101<100001110110xxxxxxxxxx", InstEmit.Frecpe_V, typeof(OpCodeSimd64));
- SetA64("010111100x1xxxxx111111xxxxxxxxxx", InstEmit.Frecps_S, typeof(OpCodeSimdReg64));
- SetA64("0>0011100<1xxxxx111111xxxxxxxxxx", InstEmit.Frecps_V, typeof(OpCodeSimdReg64));
- SetA64("010111101x100001111110xxxxxxxxxx", InstEmit.Frecpx_S, typeof(OpCodeSimd64));
- SetA64("000111100x100110010000xxxxxxxxxx", InstEmit.Frinta_S, typeof(OpCodeSimd64));
- SetA64("0>1011100<100001100010xxxxxxxxxx", InstEmit.Frinta_V, typeof(OpCodeSimd64));
- SetA64("000111100x100111110000xxxxxxxxxx", InstEmit.Frinti_S, typeof(OpCodeSimd64));
- SetA64("0>1011101<100001100110xxxxxxxxxx", InstEmit.Frinti_V, typeof(OpCodeSimd64));
- SetA64("000111100x100101010000xxxxxxxxxx", InstEmit.Frintm_S, typeof(OpCodeSimd64));
- SetA64("0>0011100<100001100110xxxxxxxxxx", InstEmit.Frintm_V, typeof(OpCodeSimd64));
- SetA64("000111100x100100010000xxxxxxxxxx", InstEmit.Frintn_S, typeof(OpCodeSimd64));
- SetA64("0>0011100<100001100010xxxxxxxxxx", InstEmit.Frintn_V, typeof(OpCodeSimd64));
- SetA64("000111100x100100110000xxxxxxxxxx", InstEmit.Frintp_S, typeof(OpCodeSimd64));
- SetA64("0>0011101<100001100010xxxxxxxxxx", InstEmit.Frintp_V, typeof(OpCodeSimd64));
- SetA64("000111100x100111010000xxxxxxxxxx", InstEmit.Frintx_S, typeof(OpCodeSimd64));
- SetA64("0>1011100<100001100110xxxxxxxxxx", InstEmit.Frintx_V, typeof(OpCodeSimd64));
- SetA64("000111100x100101110000xxxxxxxxxx", InstEmit.Frintz_S, typeof(OpCodeSimd64));
- SetA64("0>0011101<100001100110xxxxxxxxxx", InstEmit.Frintz_V, typeof(OpCodeSimd64));
- SetA64("011111101x100001110110xxxxxxxxxx", InstEmit.Frsqrte_S, typeof(OpCodeSimd64));
- SetA64("0>1011101<100001110110xxxxxxxxxx", InstEmit.Frsqrte_V, typeof(OpCodeSimd64));
- SetA64("010111101x1xxxxx111111xxxxxxxxxx", InstEmit.Frsqrts_S, typeof(OpCodeSimdReg64));
- SetA64("0>0011101<1xxxxx111111xxxxxxxxxx", InstEmit.Frsqrts_V, typeof(OpCodeSimdReg64));
- SetA64("000111100x100001110000xxxxxxxxxx", InstEmit.Fsqrt_S, typeof(OpCodeSimd64));
- SetA64("0>1011101<100001111110xxxxxxxxxx", InstEmit.Fsqrt_V, typeof(OpCodeSimd64));
- SetA64("000111100x1xxxxx001110xxxxxxxxxx", InstEmit.Fsub_S, typeof(OpCodeSimdReg64));
- SetA64("0>0011101<1xxxxx110101xxxxxxxxxx", InstEmit.Fsub_V, typeof(OpCodeSimdReg64));
- SetA64("01001110000xxxxx000111xxxxxxxxxx", InstEmit.Ins_Gp, typeof(OpCodeSimdIns64));
- SetA64("01101110000xxxxx0xxxx1xxxxxxxxxx", InstEmit.Ins_V, typeof(OpCodeSimdIns64));
- SetA64("0x00110001000000xxxxxxxxxxxxxxxx", InstEmit.Ld__Vms, typeof(OpCodeSimdMemMs64));
- SetA64("0x001100110xxxxxxxxxxxxxxxxxxxxx", InstEmit.Ld__Vms, typeof(OpCodeSimdMemMs64));
- SetA64("0x00110101x00000xxxxxxxxxxxxxxxx", InstEmit.Ld__Vss, typeof(OpCodeSimdMemSs64));
- SetA64("0x00110111xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ld__Vss, typeof(OpCodeSimdMemSs64));
- SetA64("xx10110xx1xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldp, typeof(OpCodeSimdMemPair64));
- SetA64("xx111100x10xxxxxxxxx00xxxxxxxxxx", InstEmit.Ldr, typeof(OpCodeSimdMemImm64));
- SetA64("xx111100x10xxxxxxxxx01xxxxxxxxxx", InstEmit.Ldr, typeof(OpCodeSimdMemImm64));
- SetA64("xx111100x10xxxxxxxxx11xxxxxxxxxx", InstEmit.Ldr, typeof(OpCodeSimdMemImm64));
- SetA64("xx111101x1xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldr, typeof(OpCodeSimdMemImm64));
- SetA64("xx111100x11xxxxxxxxx10xxxxxxxxxx", InstEmit.Ldr, typeof(OpCodeSimdMemReg64));
- SetA64("xx011100xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldr_Literal, typeof(OpCodeSimdMemLit64));
- SetA64("0x001110<<1xxxxx100101xxxxxxxxxx", InstEmit.Mla_V, typeof(OpCodeSimdReg64));
- SetA64("0x101111xxxxxxxx0000x0xxxxxxxxxx", InstEmit.Mla_Ve, typeof(OpCodeSimdRegElem64));
- SetA64("0x101110<<1xxxxx100101xxxxxxxxxx", InstEmit.Mls_V, typeof(OpCodeSimdReg64));
- SetA64("0x101111xxxxxxxx0100x0xxxxxxxxxx", InstEmit.Mls_Ve, typeof(OpCodeSimdRegElem64));
- SetA64("0x00111100000xxx0xx001xxxxxxxxxx", InstEmit.Movi_V, typeof(OpCodeSimdImm64));
- SetA64("0x00111100000xxx10x001xxxxxxxxxx", InstEmit.Movi_V, typeof(OpCodeSimdImm64));
- SetA64("0x00111100000xxx110x01xxxxxxxxxx", InstEmit.Movi_V, typeof(OpCodeSimdImm64));
- SetA64("0xx0111100000xxx111001xxxxxxxxxx", InstEmit.Movi_V, typeof(OpCodeSimdImm64));
- SetA64("0x001110<<1xxxxx100111xxxxxxxxxx", InstEmit.Mul_V, typeof(OpCodeSimdReg64));
- SetA64("0x001111xxxxxxxx1000x0xxxxxxxxxx", InstEmit.Mul_Ve, typeof(OpCodeSimdRegElem64));
- SetA64("0x10111100000xxx0xx001xxxxxxxxxx", InstEmit.Mvni_V, typeof(OpCodeSimdImm64));
- SetA64("0x10111100000xxx10x001xxxxxxxxxx", InstEmit.Mvni_V, typeof(OpCodeSimdImm64));
- SetA64("0x10111100000xxx110x01xxxxxxxxxx", InstEmit.Mvni_V, typeof(OpCodeSimdImm64));
- SetA64("0111111011100000101110xxxxxxxxxx", InstEmit.Neg_S, typeof(OpCodeSimd64));
- SetA64("0>101110<<100000101110xxxxxxxxxx", InstEmit.Neg_V, typeof(OpCodeSimd64));
- SetA64("0x10111000100000010110xxxxxxxxxx", InstEmit.Not_V, typeof(OpCodeSimd64));
- SetA64("0x001110111xxxxx000111xxxxxxxxxx", InstEmit.Orn_V, typeof(OpCodeSimdReg64));
- SetA64("0x001110101xxxxx000111xxxxxxxxxx", InstEmit.Orr_V, typeof(OpCodeSimdReg64));
- SetA64("0x00111100000xxx0xx101xxxxxxxxxx", InstEmit.Orr_Vi, typeof(OpCodeSimdImm64));
- SetA64("0x00111100000xxx10x101xxxxxxxxxx", InstEmit.Orr_Vi, typeof(OpCodeSimdImm64));
- SetA64("0x101110<<1xxxxx010000xxxxxxxxxx", InstEmit.Raddhn_V, typeof(OpCodeSimdReg64));
- SetA64("0x10111001100000010110xxxxxxxxxx", InstEmit.Rbit_V, typeof(OpCodeSimd64));
- SetA64("0x00111000100000000110xxxxxxxxxx", InstEmit.Rev16_V, typeof(OpCodeSimd64));
- SetA64("0x1011100x100000000010xxxxxxxxxx", InstEmit.Rev32_V, typeof(OpCodeSimd64));
- SetA64("0x001110<<100000000010xxxxxxxxxx", InstEmit.Rev64_V, typeof(OpCodeSimd64));
- SetA64("0x00111100>>>xxx100011xxxxxxxxxx", InstEmit.Rshrn_V, typeof(OpCodeSimdShImm64));
- SetA64("0x101110<<1xxxxx011000xxxxxxxxxx", InstEmit.Rsubhn_V, typeof(OpCodeSimdReg64));
- SetA64("0x001110<<1xxxxx011111xxxxxxxxxx", InstEmit.Saba_V, typeof(OpCodeSimdReg64));
- SetA64("0x001110<<1xxxxx010100xxxxxxxxxx", InstEmit.Sabal_V, typeof(OpCodeSimdReg64));
- SetA64("0x001110<<1xxxxx011101xxxxxxxxxx", InstEmit.Sabd_V, typeof(OpCodeSimdReg64));
- SetA64("0x001110<<1xxxxx011100xxxxxxxxxx", InstEmit.Sabdl_V, typeof(OpCodeSimdReg64));
- SetA64("0x001110<<100000011010xxxxxxxxxx", InstEmit.Sadalp_V, typeof(OpCodeSimd64));
- SetA64("0x001110<<1xxxxx000000xxxxxxxxxx", InstEmit.Saddl_V, typeof(OpCodeSimdReg64));
- SetA64("0x001110<<100000001010xxxxxxxxxx", InstEmit.Saddlp_V, typeof(OpCodeSimd64));
- SetA64("000011100x110000001110xxxxxxxxxx", InstEmit.Saddlv_V, typeof(OpCodeSimd64));
- SetA64("01001110<<110000001110xxxxxxxxxx", InstEmit.Saddlv_V, typeof(OpCodeSimd64));
- SetA64("0x001110<<1xxxxx000100xxxxxxxxxx", InstEmit.Saddw_V, typeof(OpCodeSimdReg64));
- SetA64("x00111100x100010000000xxxxxxxxxx", InstEmit.Scvtf_Gp, typeof(OpCodeSimdCvt64));
- SetA64(">00111100x000010>xxxxxxxxxxxxxxx", InstEmit.Scvtf_Gp_Fixed, typeof(OpCodeSimdCvt64));
- SetA64("010111100x100001110110xxxxxxxxxx", InstEmit.Scvtf_S, typeof(OpCodeSimd64));
- SetA64("0>0011100<100001110110xxxxxxxxxx", InstEmit.Scvtf_V, typeof(OpCodeSimd64));
- SetA64("0x001111001xxxxx111001xxxxxxxxxx", InstEmit.Scvtf_V_Fixed, typeof(OpCodeSimdShImm64));
- SetA64("0100111101xxxxxx111001xxxxxxxxxx", InstEmit.Scvtf_V_Fixed, typeof(OpCodeSimdShImm64));
- SetA64("01011110000xxxxx000000xxxxxxxxxx", InstEmit.Sha1c_V, typeof(OpCodeSimdReg64));
- SetA64("0101111000101000000010xxxxxxxxxx", InstEmit.Sha1h_V, typeof(OpCodeSimd64));
- SetA64("01011110000xxxxx001000xxxxxxxxxx", InstEmit.Sha1m_V, typeof(OpCodeSimdReg64));
- SetA64("01011110000xxxxx000100xxxxxxxxxx", InstEmit.Sha1p_V, typeof(OpCodeSimdReg64));
- SetA64("01011110000xxxxx001100xxxxxxxxxx", InstEmit.Sha1su0_V, typeof(OpCodeSimdReg64));
- SetA64("0101111000101000000110xxxxxxxxxx", InstEmit.Sha1su1_V, typeof(OpCodeSimd64));
- SetA64("01011110000xxxxx010000xxxxxxxxxx", InstEmit.Sha256h_V, typeof(OpCodeSimdReg64));
- SetA64("01011110000xxxxx010100xxxxxxxxxx", InstEmit.Sha256h2_V, typeof(OpCodeSimdReg64));
- SetA64("0101111000101000001010xxxxxxxxxx", InstEmit.Sha256su0_V, typeof(OpCodeSimd64));
- SetA64("01011110000xxxxx011000xxxxxxxxxx", InstEmit.Sha256su1_V, typeof(OpCodeSimdReg64));
- SetA64("0x001110<<1xxxxx000001xxxxxxxxxx", InstEmit.Shadd_V, typeof(OpCodeSimdReg64));
- SetA64("0101111101xxxxxx010101xxxxxxxxxx", InstEmit.Shl_S, typeof(OpCodeSimdShImm64));
- SetA64("0x00111100>>>xxx010101xxxxxxxxxx", InstEmit.Shl_V, typeof(OpCodeSimdShImm64));
- SetA64("0100111101xxxxxx010101xxxxxxxxxx", InstEmit.Shl_V, typeof(OpCodeSimdShImm64));
- SetA64("0x101110<<100001001110xxxxxxxxxx", InstEmit.Shll_V, typeof(OpCodeSimd64));
- SetA64("0x00111100>>>xxx100001xxxxxxxxxx", InstEmit.Shrn_V, typeof(OpCodeSimdShImm64));
- SetA64("0x001110<<1xxxxx001001xxxxxxxxxx", InstEmit.Shsub_V, typeof(OpCodeSimdReg64));
- SetA64("0x10111100>>>xxx010101xxxxxxxxxx", InstEmit.Sli_V, typeof(OpCodeSimdShImm64));
- SetA64("0110111101xxxxxx010101xxxxxxxxxx", InstEmit.Sli_V, typeof(OpCodeSimdShImm64));
- SetA64("0x001110<<1xxxxx011001xxxxxxxxxx", InstEmit.Smax_V, typeof(OpCodeSimdReg64));
- SetA64("0x001110<<1xxxxx101001xxxxxxxxxx", InstEmit.Smaxp_V, typeof(OpCodeSimdReg64));
- SetA64("000011100x110000101010xxxxxxxxxx", InstEmit.Smaxv_V, typeof(OpCodeSimd64));
- SetA64("01001110<<110000101010xxxxxxxxxx", InstEmit.Smaxv_V, typeof(OpCodeSimd64));
- SetA64("0x001110<<1xxxxx011011xxxxxxxxxx", InstEmit.Smin_V, typeof(OpCodeSimdReg64));
- SetA64("0x001110<<1xxxxx101011xxxxxxxxxx", InstEmit.Sminp_V, typeof(OpCodeSimdReg64));
- SetA64("000011100x110001101010xxxxxxxxxx", InstEmit.Sminv_V, typeof(OpCodeSimd64));
- SetA64("01001110<<110001101010xxxxxxxxxx", InstEmit.Sminv_V, typeof(OpCodeSimd64));
- SetA64("0x001110<<1xxxxx100000xxxxxxxxxx", InstEmit.Smlal_V, typeof(OpCodeSimdReg64));
- SetA64("0x001111xxxxxxxx0010x0xxxxxxxxxx", InstEmit.Smlal_Ve, typeof(OpCodeSimdRegElem64));
- SetA64("0x001110<<1xxxxx101000xxxxxxxxxx", InstEmit.Smlsl_V, typeof(OpCodeSimdReg64));
- SetA64("0x001111xxxxxxxx0110x0xxxxxxxxxx", InstEmit.Smlsl_Ve, typeof(OpCodeSimdRegElem64));
- SetA64("0x001110000xxxxx001011xxxxxxxxxx", InstEmit.Smov_S, typeof(OpCodeSimdIns64));
- SetA64("0x001110<<1xxxxx110000xxxxxxxxxx", InstEmit.Smull_V, typeof(OpCodeSimdReg64));
- SetA64("0x001111xxxxxxxx1010x0xxxxxxxxxx", InstEmit.Smull_Ve, typeof(OpCodeSimdRegElem64));
- SetA64("01011110xx100000011110xxxxxxxxxx", InstEmit.Sqabs_S, typeof(OpCodeSimd64));
- SetA64("0>001110<<100000011110xxxxxxxxxx", InstEmit.Sqabs_V, typeof(OpCodeSimd64));
- SetA64("01011110xx1xxxxx000011xxxxxxxxxx", InstEmit.Sqadd_S, typeof(OpCodeSimdReg64));
- SetA64("0>001110<<1xxxxx000011xxxxxxxxxx", InstEmit.Sqadd_V, typeof(OpCodeSimdReg64));
- SetA64("01011110011xxxxx101101xxxxxxxxxx", InstEmit.Sqdmulh_S, typeof(OpCodeSimdReg64));
- SetA64("01011110101xxxxx101101xxxxxxxxxx", InstEmit.Sqdmulh_S, typeof(OpCodeSimdReg64));
- SetA64("0x001110011xxxxx101101xxxxxxxxxx", InstEmit.Sqdmulh_V, typeof(OpCodeSimdReg64));
- SetA64("0x001110101xxxxx101101xxxxxxxxxx", InstEmit.Sqdmulh_V, typeof(OpCodeSimdReg64));
- SetA64("01111110xx100000011110xxxxxxxxxx", InstEmit.Sqneg_S, typeof(OpCodeSimd64));
- SetA64("0>101110<<100000011110xxxxxxxxxx", InstEmit.Sqneg_V, typeof(OpCodeSimd64));
- SetA64("01111110011xxxxx101101xxxxxxxxxx", InstEmit.Sqrdmulh_S, typeof(OpCodeSimdReg64));
- SetA64("01111110101xxxxx101101xxxxxxxxxx", InstEmit.Sqrdmulh_S, typeof(OpCodeSimdReg64));
- SetA64("0x101110011xxxxx101101xxxxxxxxxx", InstEmit.Sqrdmulh_V, typeof(OpCodeSimdReg64));
- SetA64("0x101110101xxxxx101101xxxxxxxxxx", InstEmit.Sqrdmulh_V, typeof(OpCodeSimdReg64));
- SetA64("0>001110<<1xxxxx010111xxxxxxxxxx", InstEmit.Sqrshl_V, typeof(OpCodeSimdReg64));
- SetA64("0101111100>>>xxx100111xxxxxxxxxx", InstEmit.Sqrshrn_S, typeof(OpCodeSimdShImm64));
- SetA64("0x00111100>>>xxx100111xxxxxxxxxx", InstEmit.Sqrshrn_V, typeof(OpCodeSimdShImm64));
- SetA64("0111111100>>>xxx100011xxxxxxxxxx", InstEmit.Sqrshrun_S, typeof(OpCodeSimdShImm64));
- SetA64("0x10111100>>>xxx100011xxxxxxxxxx", InstEmit.Sqrshrun_V, typeof(OpCodeSimdShImm64));
- SetA64("0>001110<<1xxxxx010011xxxxxxxxxx", InstEmit.Sqshl_V, typeof(OpCodeSimdReg64));
- SetA64("0101111100>>>xxx100101xxxxxxxxxx", InstEmit.Sqshrn_S, typeof(OpCodeSimdShImm64));
- SetA64("0x00111100>>>xxx100101xxxxxxxxxx", InstEmit.Sqshrn_V, typeof(OpCodeSimdShImm64));
- SetA64("0111111100>>>xxx100001xxxxxxxxxx", InstEmit.Sqshrun_S, typeof(OpCodeSimdShImm64));
- SetA64("0x10111100>>>xxx100001xxxxxxxxxx", InstEmit.Sqshrun_V, typeof(OpCodeSimdShImm64));
- SetA64("01011110xx1xxxxx001011xxxxxxxxxx", InstEmit.Sqsub_S, typeof(OpCodeSimdReg64));
- SetA64("0>001110<<1xxxxx001011xxxxxxxxxx", InstEmit.Sqsub_V, typeof(OpCodeSimdReg64));
- SetA64("01011110<<100001010010xxxxxxxxxx", InstEmit.Sqxtn_S, typeof(OpCodeSimd64));
- SetA64("0x001110<<100001010010xxxxxxxxxx", InstEmit.Sqxtn_V, typeof(OpCodeSimd64));
- SetA64("01111110<<100001001010xxxxxxxxxx", InstEmit.Sqxtun_S, typeof(OpCodeSimd64));
- SetA64("0x101110<<100001001010xxxxxxxxxx", InstEmit.Sqxtun_V, typeof(OpCodeSimd64));
- SetA64("0x001110<<1xxxxx000101xxxxxxxxxx", InstEmit.Srhadd_V, typeof(OpCodeSimdReg64));
- SetA64("0>001110<<1xxxxx010101xxxxxxxxxx", InstEmit.Srshl_V, typeof(OpCodeSimdReg64));
- SetA64("0101111101xxxxxx001001xxxxxxxxxx", InstEmit.Srshr_S, typeof(OpCodeSimdShImm64));
- SetA64("0x00111100>>>xxx001001xxxxxxxxxx", InstEmit.Srshr_V, typeof(OpCodeSimdShImm64));
- SetA64("0100111101xxxxxx001001xxxxxxxxxx", InstEmit.Srshr_V, typeof(OpCodeSimdShImm64));
- SetA64("0101111101xxxxxx001101xxxxxxxxxx", InstEmit.Srsra_S, typeof(OpCodeSimdShImm64));
- SetA64("0x00111100>>>xxx001101xxxxxxxxxx", InstEmit.Srsra_V, typeof(OpCodeSimdShImm64));
- SetA64("0100111101xxxxxx001101xxxxxxxxxx", InstEmit.Srsra_V, typeof(OpCodeSimdShImm64));
- SetA64("0>001110<<1xxxxx010001xxxxxxxxxx", InstEmit.Sshl_V, typeof(OpCodeSimdReg64));
- SetA64("0x00111100>>>xxx101001xxxxxxxxxx", InstEmit.Sshll_V, typeof(OpCodeSimdShImm64));
- SetA64("0101111101xxxxxx000001xxxxxxxxxx", InstEmit.Sshr_S, typeof(OpCodeSimdShImm64));
- SetA64("0x00111100>>>xxx000001xxxxxxxxxx", InstEmit.Sshr_V, typeof(OpCodeSimdShImm64));
- SetA64("0100111101xxxxxx000001xxxxxxxxxx", InstEmit.Sshr_V, typeof(OpCodeSimdShImm64));
- SetA64("0101111101xxxxxx000101xxxxxxxxxx", InstEmit.Ssra_S, typeof(OpCodeSimdShImm64));
- SetA64("0x00111100>>>xxx000101xxxxxxxxxx", InstEmit.Ssra_V, typeof(OpCodeSimdShImm64));
- SetA64("0100111101xxxxxx000101xxxxxxxxxx", InstEmit.Ssra_V, typeof(OpCodeSimdShImm64));
- SetA64("0x001110<<1xxxxx001000xxxxxxxxxx", InstEmit.Ssubl_V, typeof(OpCodeSimdReg64));
- SetA64("0x001110<<1xxxxx001100xxxxxxxxxx", InstEmit.Ssubw_V, typeof(OpCodeSimdReg64));
- SetA64("0x00110000000000xxxxxxxxxxxxxxxx", InstEmit.St__Vms, typeof(OpCodeSimdMemMs64));
- SetA64("0x001100100xxxxxxxxxxxxxxxxxxxxx", InstEmit.St__Vms, typeof(OpCodeSimdMemMs64));
- SetA64("0x00110100x00000xxxxxxxxxxxxxxxx", InstEmit.St__Vss, typeof(OpCodeSimdMemSs64));
- SetA64("0x00110110xxxxxxxxxxxxxxxxxxxxxx", InstEmit.St__Vss, typeof(OpCodeSimdMemSs64));
- SetA64("xx10110xx0xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Stp, typeof(OpCodeSimdMemPair64));
- SetA64("xx111100x00xxxxxxxxx00xxxxxxxxxx", InstEmit.Str, typeof(OpCodeSimdMemImm64));
- SetA64("xx111100x00xxxxxxxxx01xxxxxxxxxx", InstEmit.Str, typeof(OpCodeSimdMemImm64));
- SetA64("xx111100x00xxxxxxxxx11xxxxxxxxxx", InstEmit.Str, typeof(OpCodeSimdMemImm64));
- SetA64("xx111101x0xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Str, typeof(OpCodeSimdMemImm64));
- SetA64("xx111100x01xxxxxxxxx10xxxxxxxxxx", InstEmit.Str, typeof(OpCodeSimdMemReg64));
- SetA64("01111110111xxxxx100001xxxxxxxxxx", InstEmit.Sub_S, typeof(OpCodeSimdReg64));
- SetA64("0>101110<<1xxxxx100001xxxxxxxxxx", InstEmit.Sub_V, typeof(OpCodeSimdReg64));
- SetA64("0x001110<<1xxxxx011000xxxxxxxxxx", InstEmit.Subhn_V, typeof(OpCodeSimdReg64));
- SetA64("01011110xx100000001110xxxxxxxxxx", InstEmit.Suqadd_S, typeof(OpCodeSimd64));
- SetA64("0>001110<<100000001110xxxxxxxxxx", InstEmit.Suqadd_V, typeof(OpCodeSimd64));
- SetA64("0x001110000xxxxx0xx000xxxxxxxxxx", InstEmit.Tbl_V, typeof(OpCodeSimdTbl64));
- SetA64("0>001110<<0xxxxx001010xxxxxxxxxx", InstEmit.Trn1_V, typeof(OpCodeSimdReg64));
- SetA64("0>001110<<0xxxxx011010xxxxxxxxxx", InstEmit.Trn2_V, typeof(OpCodeSimdReg64));
- SetA64("0x101110<<1xxxxx011111xxxxxxxxxx", InstEmit.Uaba_V, typeof(OpCodeSimdReg64));
- SetA64("0x101110<<1xxxxx010100xxxxxxxxxx", InstEmit.Uabal_V, typeof(OpCodeSimdReg64));
- SetA64("0x101110<<1xxxxx011101xxxxxxxxxx", InstEmit.Uabd_V, typeof(OpCodeSimdReg64));
- SetA64("0x101110<<1xxxxx011100xxxxxxxxxx", InstEmit.Uabdl_V, typeof(OpCodeSimdReg64));
- SetA64("0x101110<<100000011010xxxxxxxxxx", InstEmit.Uadalp_V, typeof(OpCodeSimd64));
- SetA64("0x101110<<1xxxxx000000xxxxxxxxxx", InstEmit.Uaddl_V, typeof(OpCodeSimdReg64));
- SetA64("0x101110<<100000001010xxxxxxxxxx", InstEmit.Uaddlp_V, typeof(OpCodeSimd64));
- SetA64("001011100x110000001110xxxxxxxxxx", InstEmit.Uaddlv_V, typeof(OpCodeSimd64));
- SetA64("01101110<<110000001110xxxxxxxxxx", InstEmit.Uaddlv_V, typeof(OpCodeSimd64));
- SetA64("0x101110<<1xxxxx000100xxxxxxxxxx", InstEmit.Uaddw_V, typeof(OpCodeSimdReg64));
- SetA64("x00111100x100011000000xxxxxxxxxx", InstEmit.Ucvtf_Gp, typeof(OpCodeSimdCvt64));
- SetA64(">00111100x000011>xxxxxxxxxxxxxxx", InstEmit.Ucvtf_Gp_Fixed, typeof(OpCodeSimdCvt64));
- SetA64("011111100x100001110110xxxxxxxxxx", InstEmit.Ucvtf_S, typeof(OpCodeSimd64));
- SetA64("0>1011100<100001110110xxxxxxxxxx", InstEmit.Ucvtf_V, typeof(OpCodeSimd64));
- SetA64("0x101111001xxxxx111001xxxxxxxxxx", InstEmit.Ucvtf_V_Fixed, typeof(OpCodeSimdShImm64));
- SetA64("0110111101xxxxxx111001xxxxxxxxxx", InstEmit.Ucvtf_V_Fixed, typeof(OpCodeSimdShImm64));
- SetA64("0x101110<<1xxxxx000001xxxxxxxxxx", InstEmit.Uhadd_V, typeof(OpCodeSimdReg64));
- SetA64("0x101110<<1xxxxx001001xxxxxxxxxx", InstEmit.Uhsub_V, typeof(OpCodeSimdReg64));
- SetA64("0x101110<<1xxxxx011001xxxxxxxxxx", InstEmit.Umax_V, typeof(OpCodeSimdReg64));
- SetA64("0x101110<<1xxxxx101001xxxxxxxxxx", InstEmit.Umaxp_V, typeof(OpCodeSimdReg64));
- SetA64("001011100x110000101010xxxxxxxxxx", InstEmit.Umaxv_V, typeof(OpCodeSimd64));
- SetA64("01101110<<110000101010xxxxxxxxxx", InstEmit.Umaxv_V, typeof(OpCodeSimd64));
- SetA64("0x101110<<1xxxxx011011xxxxxxxxxx", InstEmit.Umin_V, typeof(OpCodeSimdReg64));
- SetA64("0x101110<<1xxxxx101011xxxxxxxxxx", InstEmit.Uminp_V, typeof(OpCodeSimdReg64));
- SetA64("001011100x110001101010xxxxxxxxxx", InstEmit.Uminv_V, typeof(OpCodeSimd64));
- SetA64("01101110<<110001101010xxxxxxxxxx", InstEmit.Uminv_V, typeof(OpCodeSimd64));
- SetA64("0x101110<<1xxxxx100000xxxxxxxxxx", InstEmit.Umlal_V, typeof(OpCodeSimdReg64));
- SetA64("0x101111xxxxxxxx0010x0xxxxxxxxxx", InstEmit.Umlal_Ve, typeof(OpCodeSimdRegElem64));
- SetA64("0x101110<<1xxxxx101000xxxxxxxxxx", InstEmit.Umlsl_V, typeof(OpCodeSimdReg64));
- SetA64("0x101111xxxxxxxx0110x0xxxxxxxxxx", InstEmit.Umlsl_Ve, typeof(OpCodeSimdRegElem64));
- SetA64("0x001110000xxxxx001111xxxxxxxxxx", InstEmit.Umov_S, typeof(OpCodeSimdIns64));
- SetA64("0x101110<<1xxxxx110000xxxxxxxxxx", InstEmit.Umull_V, typeof(OpCodeSimdReg64));
- SetA64("0x101111xxxxxxxx1010x0xxxxxxxxxx", InstEmit.Umull_Ve, typeof(OpCodeSimdRegElem64));
- SetA64("01111110xx1xxxxx000011xxxxxxxxxx", InstEmit.Uqadd_S, typeof(OpCodeSimdReg64));
- SetA64("0>101110<<1xxxxx000011xxxxxxxxxx", InstEmit.Uqadd_V, typeof(OpCodeSimdReg64));
- SetA64("0>101110<<1xxxxx010111xxxxxxxxxx", InstEmit.Uqrshl_V, typeof(OpCodeSimdReg64));
- SetA64("0111111100>>>xxx100111xxxxxxxxxx", InstEmit.Uqrshrn_S, typeof(OpCodeSimdShImm64));
- SetA64("0x10111100>>>xxx100111xxxxxxxxxx", InstEmit.Uqrshrn_V, typeof(OpCodeSimdShImm64));
- SetA64("0>101110<<1xxxxx010011xxxxxxxxxx", InstEmit.Uqshl_V, typeof(OpCodeSimdReg64));
- SetA64("0111111100>>>xxx100101xxxxxxxxxx", InstEmit.Uqshrn_S, typeof(OpCodeSimdShImm64));
- SetA64("0x10111100>>>xxx100101xxxxxxxxxx", InstEmit.Uqshrn_V, typeof(OpCodeSimdShImm64));
- SetA64("01111110xx1xxxxx001011xxxxxxxxxx", InstEmit.Uqsub_S, typeof(OpCodeSimdReg64));
- SetA64("0>101110<<1xxxxx001011xxxxxxxxxx", InstEmit.Uqsub_V, typeof(OpCodeSimdReg64));
- SetA64("01111110<<100001010010xxxxxxxxxx", InstEmit.Uqxtn_S, typeof(OpCodeSimd64));
- SetA64("0x101110<<100001010010xxxxxxxxxx", InstEmit.Uqxtn_V, typeof(OpCodeSimd64));
- SetA64("0x101110<<1xxxxx000101xxxxxxxxxx", InstEmit.Urhadd_V, typeof(OpCodeSimdReg64));
- SetA64("0>101110<<1xxxxx010101xxxxxxxxxx", InstEmit.Urshl_V, typeof(OpCodeSimdReg64));
- SetA64("0111111101xxxxxx001001xxxxxxxxxx", InstEmit.Urshr_S, typeof(OpCodeSimdShImm64));
- SetA64("0x10111100>>>xxx001001xxxxxxxxxx", InstEmit.Urshr_V, typeof(OpCodeSimdShImm64));
- SetA64("0110111101xxxxxx001001xxxxxxxxxx", InstEmit.Urshr_V, typeof(OpCodeSimdShImm64));
- SetA64("0111111101xxxxxx001101xxxxxxxxxx", InstEmit.Ursra_S, typeof(OpCodeSimdShImm64));
- SetA64("0x10111100>>>xxx001101xxxxxxxxxx", InstEmit.Ursra_V, typeof(OpCodeSimdShImm64));
- SetA64("0110111101xxxxxx001101xxxxxxxxxx", InstEmit.Ursra_V, typeof(OpCodeSimdShImm64));
- SetA64("0>101110<<1xxxxx010001xxxxxxxxxx", InstEmit.Ushl_V, typeof(OpCodeSimdReg64));
- SetA64("0x10111100>>>xxx101001xxxxxxxxxx", InstEmit.Ushll_V, typeof(OpCodeSimdShImm64));
- SetA64("0111111101xxxxxx000001xxxxxxxxxx", InstEmit.Ushr_S, typeof(OpCodeSimdShImm64));
- SetA64("0x10111100>>>xxx000001xxxxxxxxxx", InstEmit.Ushr_V, typeof(OpCodeSimdShImm64));
- SetA64("0110111101xxxxxx000001xxxxxxxxxx", InstEmit.Ushr_V, typeof(OpCodeSimdShImm64));
- SetA64("01111110xx100000001110xxxxxxxxxx", InstEmit.Usqadd_S, typeof(OpCodeSimd64));
- SetA64("0>101110<<100000001110xxxxxxxxxx", InstEmit.Usqadd_V, typeof(OpCodeSimd64));
- SetA64("0111111101xxxxxx000101xxxxxxxxxx", InstEmit.Usra_S, typeof(OpCodeSimdShImm64));
- SetA64("0x10111100>>>xxx000101xxxxxxxxxx", InstEmit.Usra_V, typeof(OpCodeSimdShImm64));
- SetA64("0110111101xxxxxx000101xxxxxxxxxx", InstEmit.Usra_V, typeof(OpCodeSimdShImm64));
- SetA64("0x101110<<1xxxxx001000xxxxxxxxxx", InstEmit.Usubl_V, typeof(OpCodeSimdReg64));
- SetA64("0x101110<<1xxxxx001100xxxxxxxxxx", InstEmit.Usubw_V, typeof(OpCodeSimdReg64));
- SetA64("0>001110<<0xxxxx000110xxxxxxxxxx", InstEmit.Uzp1_V, typeof(OpCodeSimdReg64));
- SetA64("0>001110<<0xxxxx010110xxxxxxxxxx", InstEmit.Uzp2_V, typeof(OpCodeSimdReg64));
- SetA64("0x001110<<100001001010xxxxxxxxxx", InstEmit.Xtn_V, typeof(OpCodeSimd64));
- SetA64("0>001110<<0xxxxx001110xxxxxxxxxx", InstEmit.Zip1_V, typeof(OpCodeSimdReg64));
- SetA64("0>001110<<0xxxxx011110xxxxxxxxxx", InstEmit.Zip2_V, typeof(OpCodeSimdReg64));
-#endregion
-
- FillFastLookupTable(_instA32FastLookup, _allInstA32);
- FillFastLookupTable(_instT32FastLookup, _allInstT32);
- FillFastLookupTable(_instA64FastLookup, _allInstA64);
- }
-
- private static void SetA32(string encoding, InstEmitter emitter, Type type)
- {
- Set(encoding, new Inst(emitter, type), ExecutionMode.Aarch32Arm);
- }
-
- private static void SetT32(string encoding, InstEmitter emitter, Type type)
- {
- if (encoding.Length == 16)
- {
- encoding = "xxxxxxxxxxxxxxxx" + encoding;
- }
-
- Set(encoding, new Inst(emitter, type), ExecutionMode.Aarch32Thumb);
- }
-
- private static void SetA64(string encoding, InstEmitter emitter, Type type)
- {
- Set(encoding, new Inst(emitter, type), ExecutionMode.Aarch64);
- }
-
- private static void Set(string encoding, Inst inst, ExecutionMode mode)
- {
- int bit = encoding.Length - 1;
- int value = 0;
- int xMask = 0;
- int xBits = 0;
-
- int[] xPos = new int[encoding.Length];
-
- int blacklisted = 0;
-
- for (int index = 0; index < encoding.Length; index++, bit--)
- {
- // Note: < and > are used on special encodings.
- // The < means that we should never have ALL bits with the '<' set.
- // So, when the encoding has <<, it means that 00, 01, and 10 are valid,
- // but not 11. <<< is 000, 001, ..., 110 but NOT 111, and so on...
- // For >, the invalid value is zero. So, for >> 01, 10 and 11 are valid,
- // but 00 isn't.
- char chr = encoding[index];
-
- if (chr == '1')
- {
- value |= 1 << bit;
- }
- else if (chr == 'x')
- {
- xMask |= 1 << bit;
- }
- else if (chr == '>')
- {
- xPos[xBits++] = bit;
- }
- else if (chr == '<')
- {
- xPos[xBits++] = bit;
-
- blacklisted |= 1 << bit;
- }
- else if (chr != '0')
- {
- throw new ArgumentException(nameof(encoding));
- }
- }
-
- xMask = ~xMask;
-
- if (xBits == 0)
- {
- InsertInst(xMask, value, inst, mode);
-
- return;
- }
-
- for (int index = 0; index < (1 << xBits); index++)
- {
- int mask = 0;
-
- for (int x = 0; x < xBits; x++)
- {
- mask |= ((index >> x) & 1) << xPos[x];
- }
-
- if (mask != blacklisted)
- {
- InsertInst(xMask, value | mask, inst, mode);
- }
- }
- }
-
- private static void InsertInst(int xMask, int value, Inst inst, ExecutionMode mode)
- {
- InstInfo info = new InstInfo(xMask, value, inst);
-
- switch (mode)
- {
- case ExecutionMode.Aarch32Arm: _allInstA32.Add(info); break;
- case ExecutionMode.Aarch32Thumb: _allInstT32.Add(info); break;
- case ExecutionMode.Aarch64: _allInstA64.Add(info); break;
- }
- }
-
- private static void FillFastLookupTable(InstInfo[][] table, List<InstInfo> allInsts)
- {
- List<InstInfo>[] tmp = new List<InstInfo>[FastLookupSize];
-
- for (int i = 0; i < FastLookupSize; i++)
- {
- tmp[i] = new List<InstInfo>();
- }
-
- foreach (InstInfo inst in allInsts)
- {
- int mask = ToFastLookupIndex(inst.Mask);
- int value = ToFastLookupIndex(inst.Value);
-
- for (int i = 0; i < FastLookupSize; i++)
- {
- if ((i & mask) == value)
- {
- tmp[i].Add(inst);
- }
- }
- }
-
- for (int i = 0; i < FastLookupSize; i++)
- {
- table[i] = tmp[i].ToArray();
- }
- }
-
- public static Inst GetInstA32(int opCode)
- {
- return GetInstFromList(_instA32FastLookup[ToFastLookupIndex(opCode)], opCode);
- }
-
- public static Inst GetInstT32(int opCode)
- {
- return GetInstFromList(_instT32FastLookup[ToFastLookupIndex(opCode)], opCode);
- }
-
- public static Inst GetInstA64(int opCode)
- {
- return GetInstFromList(_instA64FastLookup[ToFastLookupIndex(opCode)], opCode);
- }
-
- private static int ToFastLookupIndex(int value)
- {
- return ((value >> 10) & 0x00F) | ((value >> 18) & 0xFF0);
- }
-
- private static Inst GetInstFromList(IEnumerable<InstInfo> instList, int opCode)
- {
- foreach (InstInfo node in instList)
- {
- if ((opCode & node.Mask) == node.Value)
- {
- return node.Inst;
- }
- }
-
- return Inst.Undefined;
- }
- }
-}
diff --git a/ChocolArm64/Optimizations.cs b/ChocolArm64/Optimizations.cs
deleted file mode 100644
index 24828ebf..00000000
--- a/ChocolArm64/Optimizations.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System.Runtime.Intrinsics.X86;
-
-namespace ChocolArm64
-{
- public static class Optimizations
- {
- public static bool AssumeStrictAbiCompliance { get; set; } = true;
-
- public static bool FastFP { get; set; } = true;
-
- private const bool UseAllSseIfAvailable = true;
-
- public static bool UseSseIfAvailable { get; set; } = UseAllSseIfAvailable;
- public static bool UseSse2IfAvailable { get; set; } = UseAllSseIfAvailable;
- public static bool UseSse3IfAvailable { get; set; } = UseAllSseIfAvailable;
- public static bool UseSsse3IfAvailable { get; set; } = UseAllSseIfAvailable;
- public static bool UseSse41IfAvailable { get; set; } = UseAllSseIfAvailable;
- public static bool UseSse42IfAvailable { get; set; } = UseAllSseIfAvailable;
-
- internal static bool UseSse => UseSseIfAvailable && Sse.IsSupported;
- internal static bool UseSse2 => UseSse2IfAvailable && Sse2.IsSupported;
- internal static bool UseSse3 => UseSse3IfAvailable && Sse3.IsSupported;
- internal static bool UseSsse3 => UseSsse3IfAvailable && Ssse3.IsSupported;
- internal static bool UseSse41 => UseSse41IfAvailable && Sse41.IsSupported;
- internal static bool UseSse42 => UseSse42IfAvailable && Sse42.IsSupported;
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/State/Aarch32Mode.cs b/ChocolArm64/State/Aarch32Mode.cs
deleted file mode 100644
index bc4e4b64..00000000
--- a/ChocolArm64/State/Aarch32Mode.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace ChocolArm64.State
-{
- enum Aarch32Mode
- {
- User = 0b10000,
- Fiq = 0b10001,
- Irq = 0b10010,
- Supervisor = 0b10011,
- Monitor = 0b10110,
- Abort = 0b10111,
- Hypervisor = 0b11010,
- Undefined = 0b11011,
- System = 0b11111
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/State/CpuThreadState.cs b/ChocolArm64/State/CpuThreadState.cs
deleted file mode 100644
index e4baaefa..00000000
--- a/ChocolArm64/State/CpuThreadState.cs
+++ /dev/null
@@ -1,354 +0,0 @@
-using ChocolArm64.Translation;
-using System;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Runtime.Intrinsics;
-
-using static ChocolArm64.Instructions.VectorHelper;
-
-namespace ChocolArm64.State
-{
- public class CpuThreadState : ARMeilleure.State.IExecutionContext
- {
- private const int MinCountForCheck = 40000;
-
- internal const int ErgSizeLog2 = 4;
- internal const int DczSizeLog2 = 4;
-
- public ulong X0, X1, X2, X3, X4, X5, X6, X7,
- X8, X9, X10, X11, X12, X13, X14, X15,
- X16, X17, X18, X19, X20, X21, X22, X23,
- X24, X25, X26, X27, X28, X29, X30, X31;
-
- public Vector128<float> V0, V1, V2, V3, V4, V5, V6, V7,
- V8, V9, V10, V11, V12, V13, V14, V15,
- V16, V17, V18, V19, V20, V21, V22, V23,
- V24, V25, V26, V27, V28, V29, V30, V31;
-
- public bool IsAarch32 { get; set; }
-
- public bool Thumb;
- public bool BigEndian;
-
- public bool Overflow;
- public bool Carry;
- public bool Zero;
- public bool Negative;
-
- public int ElrHyp;
-
- public bool Running { get; set; }
-
- private bool _interrupted;
-
- private int _syncCount;
-
- public long TpidrEl0 { get; set; }
- public long Tpidr { get; set; }
-
- public int CFpcr { get; set; }
- public int CFpsr { get; set; }
-
- public ARMeilleure.State.FPCR Fpcr
- {
- get => (ARMeilleure.State.FPCR)CFpcr;
- set => CFpcr = (int)value;
- }
-
- public ARMeilleure.State.FPSR Fpsr
- {
- get => (ARMeilleure.State.FPSR)CFpsr;
- set => CFpsr = (int)value;
- }
-
- public int Psr
- {
- get
- {
- return (Negative ? (int)PState.NMask : 0) |
- (Zero ? (int)PState.ZMask : 0) |
- (Carry ? (int)PState.CMask : 0) |
- (Overflow ? (int)PState.VMask : 0);
- }
- }
-
- public uint CtrEl0 => 0x8444c004;
- public uint DczidEl0 => 0x00000004;
-
- public ulong CntfrqEl0 { get; set; }
- public ulong CntpctEl0
- {
- get
- {
- double ticks = _tickCounter.ElapsedTicks * _hostTickFreq;
-
- return (ulong)(ticks * CntfrqEl0);
- }
- }
-
- public event EventHandler<EventArgs> Interrupt;
- public event EventHandler<ARMeilleure.State.InstExceptionEventArgs> Break;
- public event EventHandler<ARMeilleure.State.InstExceptionEventArgs> SupervisorCall;
- public event EventHandler<ARMeilleure.State.InstUndefinedEventArgs> Undefined;
-
- private static Stopwatch _tickCounter;
-
- private static double _hostTickFreq;
-
- internal Translator CurrentTranslator;
-
- private ulong _exclusiveAddress;
-
- internal ulong ExclusiveValueLow { get; set; }
- internal ulong ExclusiveValueHigh { get; set; }
-
- public CpuThreadState()
- {
- ClearExclusiveAddress();
-
- Running = true;
- }
-
- static CpuThreadState()
- {
- _hostTickFreq = 1.0 / Stopwatch.Frequency;
-
- _tickCounter = new Stopwatch();
-
- _tickCounter.Start();
- }
-
- internal void SetExclusiveAddress(ulong address)
- {
- _exclusiveAddress = GetMaskedExclusiveAddress(address);
- }
-
- internal bool CheckExclusiveAddress(ulong address)
- {
- return GetMaskedExclusiveAddress(address) == _exclusiveAddress;
- }
-
- internal void ClearExclusiveAddress()
- {
- _exclusiveAddress = ulong.MaxValue;
- }
-
- private ulong GetMaskedExclusiveAddress(ulong address)
- {
- return address & ~((4UL << ErgSizeLog2) - 1);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal bool Synchronize()
- {
- // Firing a interrupt frequently is expensive, so we only
- // do it after a given number of instructions has executed.
- _syncCount++;
-
- if (_syncCount >= MinCountForCheck)
- {
- CheckInterrupt();
- }
-
- return Running;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- private void CheckInterrupt()
- {
- _syncCount = 0;
-
- if (_interrupted)
- {
- _interrupted = false;
-
- Interrupt?.Invoke(this, EventArgs.Empty);
- }
- }
-
- public ulong GetX(int index)
- {
- switch (index)
- {
- case 0: return X0;
- case 1: return X1;
- case 2: return X2;
- case 3: return X3;
- case 4: return X4;
- case 5: return X5;
- case 6: return X6;
- case 7: return X7;
- case 8: return X8;
- case 9: return X9;
- case 10: return X10;
- case 11: return X11;
- case 12: return X12;
- case 13: return X13;
- case 14: return X14;
- case 15: return X15;
- case 16: return X16;
- case 17: return X17;
- case 18: return X18;
- case 19: return X19;
- case 20: return X20;
- case 21: return X21;
- case 22: return X22;
- case 23: return X23;
- case 24: return X24;
- case 25: return X25;
- case 26: return X26;
- case 27: return X27;
- case 28: return X28;
- case 29: return X29;
- case 30: return X30;
- case 31: return X31;
-
- default: throw new ArgumentOutOfRangeException(nameof(index));
- }
- }
-
- public void SetX(int index, ulong value)
- {
- switch (index)
- {
- case 0: X0 = value; break;
- case 1: X1 = value; break;
- case 2: X2 = value; break;
- case 3: X3 = value; break;
- case 4: X4 = value; break;
- case 5: X5 = value; break;
- case 6: X6 = value; break;
- case 7: X7 = value; break;
- case 8: X8 = value; break;
- case 9: X9 = value; break;
- case 10: X10 = value; break;
- case 11: X11 = value; break;
- case 12: X12 = value; break;
- case 13: X13 = value; break;
- case 14: X14 = value; break;
- case 15: X15 = value; break;
- case 16: X16 = value; break;
- case 17: X17 = value; break;
- case 18: X18 = value; break;
- case 19: X19 = value; break;
- case 20: X20 = value; break;
- case 21: X21 = value; break;
- case 22: X22 = value; break;
- case 23: X23 = value; break;
- case 24: X24 = value; break;
- case 25: X25 = value; break;
- case 26: X26 = value; break;
- case 27: X27 = value; break;
- case 28: X28 = value; break;
- case 29: X29 = value; break;
- case 30: X30 = value; break;
- case 31: X31 = value; break;
-
- default: throw new ArgumentOutOfRangeException(nameof(index));
- }
- }
-
- public ARMeilleure.State.V128 GetV(int index)
- {
- switch (index)
- {
- case 0: return new ARMeilleure.State.V128(VectorExtractIntZx(V0, 0, 3), VectorExtractIntZx(V0, 1, 3));
- case 1: return new ARMeilleure.State.V128(VectorExtractIntZx(V1, 0, 3), VectorExtractIntZx(V1, 1, 3));
- case 2: return new ARMeilleure.State.V128(VectorExtractIntZx(V2, 0, 3), VectorExtractIntZx(V2, 1, 3));
- case 3: return new ARMeilleure.State.V128(VectorExtractIntZx(V3, 0, 3), VectorExtractIntZx(V3, 1, 3));
- case 4: return new ARMeilleure.State.V128(VectorExtractIntZx(V4, 0, 3), VectorExtractIntZx(V4, 1, 3));
- case 5: return new ARMeilleure.State.V128(VectorExtractIntZx(V5, 0, 3), VectorExtractIntZx(V5, 1, 3));
- case 6: return new ARMeilleure.State.V128(VectorExtractIntZx(V6, 0, 3), VectorExtractIntZx(V6, 1, 3));
- case 7: return new ARMeilleure.State.V128(VectorExtractIntZx(V7, 0, 3), VectorExtractIntZx(V7, 1, 3));
- case 8: return new ARMeilleure.State.V128(VectorExtractIntZx(V8, 0, 3), VectorExtractIntZx(V8, 1, 3));
- case 9: return new ARMeilleure.State.V128(VectorExtractIntZx(V9, 0, 3), VectorExtractIntZx(V9, 1, 3));
- case 10: return new ARMeilleure.State.V128(VectorExtractIntZx(V10, 0, 3), VectorExtractIntZx(V10, 1, 3));
- case 11: return new ARMeilleure.State.V128(VectorExtractIntZx(V11, 0, 3), VectorExtractIntZx(V11, 1, 3));
- case 12: return new ARMeilleure.State.V128(VectorExtractIntZx(V12, 0, 3), VectorExtractIntZx(V12, 1, 3));
- case 13: return new ARMeilleure.State.V128(VectorExtractIntZx(V13, 0, 3), VectorExtractIntZx(V13, 1, 3));
- case 14: return new ARMeilleure.State.V128(VectorExtractIntZx(V14, 0, 3), VectorExtractIntZx(V14, 1, 3));
- case 15: return new ARMeilleure.State.V128(VectorExtractIntZx(V15, 0, 3), VectorExtractIntZx(V15, 1, 3));
- case 16: return new ARMeilleure.State.V128(VectorExtractIntZx(V16, 0, 3), VectorExtractIntZx(V16, 1, 3));
- case 17: return new ARMeilleure.State.V128(VectorExtractIntZx(V17, 0, 3), VectorExtractIntZx(V17, 1, 3));
- case 18: return new ARMeilleure.State.V128(VectorExtractIntZx(V18, 0, 3), VectorExtractIntZx(V18, 1, 3));
- case 19: return new ARMeilleure.State.V128(VectorExtractIntZx(V19, 0, 3), VectorExtractIntZx(V19, 1, 3));
- case 20: return new ARMeilleure.State.V128(VectorExtractIntZx(V20, 0, 3), VectorExtractIntZx(V20, 1, 3));
- case 21: return new ARMeilleure.State.V128(VectorExtractIntZx(V21, 0, 3), VectorExtractIntZx(V21, 1, 3));
- case 22: return new ARMeilleure.State.V128(VectorExtractIntZx(V22, 0, 3), VectorExtractIntZx(V22, 1, 3));
- case 23: return new ARMeilleure.State.V128(VectorExtractIntZx(V23, 0, 3), VectorExtractIntZx(V23, 1, 3));
- case 24: return new ARMeilleure.State.V128(VectorExtractIntZx(V24, 0, 3), VectorExtractIntZx(V24, 1, 3));
- case 25: return new ARMeilleure.State.V128(VectorExtractIntZx(V25, 0, 3), VectorExtractIntZx(V25, 1, 3));
- case 26: return new ARMeilleure.State.V128(VectorExtractIntZx(V26, 0, 3), VectorExtractIntZx(V26, 1, 3));
- case 27: return new ARMeilleure.State.V128(VectorExtractIntZx(V27, 0, 3), VectorExtractIntZx(V27, 1, 3));
- case 28: return new ARMeilleure.State.V128(VectorExtractIntZx(V28, 0, 3), VectorExtractIntZx(V28, 1, 3));
- case 29: return new ARMeilleure.State.V128(VectorExtractIntZx(V29, 0, 3), VectorExtractIntZx(V29, 1, 3));
- case 30: return new ARMeilleure.State.V128(VectorExtractIntZx(V30, 0, 3), VectorExtractIntZx(V30, 1, 3));
- case 31: return new ARMeilleure.State.V128(VectorExtractIntZx(V31, 0, 3), VectorExtractIntZx(V31, 1, 3));
-
- default: throw new ArgumentOutOfRangeException(nameof(index));
- }
- }
-
- public bool GetPstateFlag(ARMeilleure.State.PState flag)
- {
- switch (flag)
- {
- case ARMeilleure.State.PState.NFlag: return Negative;
- case ARMeilleure.State.PState.ZFlag: return Zero;
- case ARMeilleure.State.PState.CFlag: return Carry;
- case ARMeilleure.State.PState.VFlag: return Overflow;
-
- default: throw new ArgumentOutOfRangeException(nameof(flag));
- }
- }
-
- public void RequestInterrupt()
- {
- _interrupted = true;
- }
-
- internal void OnBreak(long position, int imm)
- {
- Break?.Invoke(this, new ARMeilleure.State.InstExceptionEventArgs((ulong)position, imm));
- }
-
- internal void OnSvcCall(long position, int imm)
- {
- SupervisorCall?.Invoke(this, new ARMeilleure.State.InstExceptionEventArgs((ulong)position, imm));
- }
-
- internal void OnUndefined(long position, int rawOpCode)
- {
- Undefined?.Invoke(this, new ARMeilleure.State.InstUndefinedEventArgs((ulong)position, rawOpCode));
- }
-
- internal ExecutionMode GetExecutionMode()
- {
- if (!IsAarch32)
- {
- return ExecutionMode.Aarch64;
- }
- else
- {
- return Thumb ? ExecutionMode.Aarch32Thumb : ExecutionMode.Aarch32Arm;
- }
- }
-
- internal bool GetFpcrFlag(Fpcr flag)
- {
- return (CFpcr & (1 << (int)flag)) != 0;
- }
-
- internal void SetFpsrFlag(Fpsr flag)
- {
- CFpsr |= 1 << (int)flag;
- }
-
- internal RoundMode FPRoundingMode()
- {
- return (RoundMode)((CFpcr >> (int)State.Fpcr.RMode) & 3);
- }
-
- public void Dispose() { }
- }
-}
diff --git a/ChocolArm64/State/ExecutionMode.cs b/ChocolArm64/State/ExecutionMode.cs
deleted file mode 100644
index b735fd5f..00000000
--- a/ChocolArm64/State/ExecutionMode.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace ChocolArm64.State
-{
- enum ExecutionMode
- {
- Aarch64,
- Aarch32Arm,
- Aarch32Thumb
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/State/FpExc.cs b/ChocolArm64/State/FpExc.cs
deleted file mode 100644
index 5cb7a402..00000000
--- a/ChocolArm64/State/FpExc.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace ChocolArm64.State
-{
- enum FpExc
- {
- InvalidOp = 0,
- DivideByZero = 1,
- Overflow = 2,
- Underflow = 3,
- Inexact = 4,
- InputDenorm = 7
- }
-}
diff --git a/ChocolArm64/State/FpType.cs b/ChocolArm64/State/FpType.cs
deleted file mode 100644
index fc279106..00000000
--- a/ChocolArm64/State/FpType.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace ChocolArm64.State
-{
- enum FpType
- {
- Nonzero,
- Zero,
- Infinity,
- QNaN,
- SNaN
- }
-}
diff --git a/ChocolArm64/State/Fpcr.cs b/ChocolArm64/State/Fpcr.cs
deleted file mode 100644
index 908faee5..00000000
--- a/ChocolArm64/State/Fpcr.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace ChocolArm64.State
-{
- enum Fpcr
- {
- Ufe = 11,
- RMode = 22,
- Fz = 24,
- Dn = 25,
- Ahp = 26
- }
-}
diff --git a/ChocolArm64/State/Fpsr.cs b/ChocolArm64/State/Fpsr.cs
deleted file mode 100644
index ba551eef..00000000
--- a/ChocolArm64/State/Fpsr.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace ChocolArm64.State
-{
- enum Fpsr
- {
- Ufc = 3,
- Qc = 27
- }
-}
diff --git a/ChocolArm64/State/PState.cs b/ChocolArm64/State/PState.cs
deleted file mode 100644
index 053a5357..00000000
--- a/ChocolArm64/State/PState.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System;
-
-namespace ChocolArm64.State
-{
- [Flags]
- enum PState
- {
- TBit = 5,
- EBit = 9,
-
- VBit = 28,
- CBit = 29,
- ZBit = 30,
- NBit = 31,
-
- TMask = 1 << TBit,
- EMask = 1 << EBit,
-
- VMask = 1 << VBit,
- CMask = 1 << CBit,
- ZMask = 1 << ZBit,
- NMask = 1 << NBit
- }
-}
diff --git a/ChocolArm64/State/Register.cs b/ChocolArm64/State/Register.cs
deleted file mode 100644
index a7a2ead0..00000000
--- a/ChocolArm64/State/Register.cs
+++ /dev/null
@@ -1,148 +0,0 @@
-using System;
-using System.Reflection;
-
-namespace ChocolArm64.State
-{
- struct Register : IEquatable<Register>
- {
- public int Index;
-
- public RegisterType Type;
-
- public Register(int index, RegisterType type)
- {
- Index = index;
- Type = type;
- }
-
- public override int GetHashCode()
- {
- return (ushort)Index | ((ushort)Type << 16);
- }
-
- public override bool Equals(object obj)
- {
- return obj is Register reg && Equals(reg);
- }
-
- public bool Equals(Register other)
- {
- return Index == other.Index && Type == other.Type;
- }
-
- public FieldInfo GetField()
- {
- switch (Type)
- {
- case RegisterType.Flag: return GetFieldFlag();
- case RegisterType.Int: return GetFieldInt();
- case RegisterType.Vector: return GetFieldVector();
- }
-
- throw new InvalidOperationException();
- }
-
- private FieldInfo GetFieldFlag()
- {
- switch ((PState)Index)
- {
- case PState.TBit: return GetField(nameof(CpuThreadState.Thumb));
- case PState.EBit: return GetField(nameof(CpuThreadState.BigEndian));
-
- case PState.VBit: return GetField(nameof(CpuThreadState.Overflow));
- case PState.CBit: return GetField(nameof(CpuThreadState.Carry));
- case PState.ZBit: return GetField(nameof(CpuThreadState.Zero));
- case PState.NBit: return GetField(nameof(CpuThreadState.Negative));
- }
-
- throw new InvalidOperationException();
- }
-
- private FieldInfo GetFieldInt()
- {
- switch (Index)
- {
- case 0: return GetField(nameof(CpuThreadState.X0));
- case 1: return GetField(nameof(CpuThreadState.X1));
- case 2: return GetField(nameof(CpuThreadState.X2));
- case 3: return GetField(nameof(CpuThreadState.X3));
- case 4: return GetField(nameof(CpuThreadState.X4));
- case 5: return GetField(nameof(CpuThreadState.X5));
- case 6: return GetField(nameof(CpuThreadState.X6));
- case 7: return GetField(nameof(CpuThreadState.X7));
- case 8: return GetField(nameof(CpuThreadState.X8));
- case 9: return GetField(nameof(CpuThreadState.X9));
- case 10: return GetField(nameof(CpuThreadState.X10));
- case 11: return GetField(nameof(CpuThreadState.X11));
- case 12: return GetField(nameof(CpuThreadState.X12));
- case 13: return GetField(nameof(CpuThreadState.X13));
- case 14: return GetField(nameof(CpuThreadState.X14));
- case 15: return GetField(nameof(CpuThreadState.X15));
- case 16: return GetField(nameof(CpuThreadState.X16));
- case 17: return GetField(nameof(CpuThreadState.X17));
- case 18: return GetField(nameof(CpuThreadState.X18));
- case 19: return GetField(nameof(CpuThreadState.X19));
- case 20: return GetField(nameof(CpuThreadState.X20));
- case 21: return GetField(nameof(CpuThreadState.X21));
- case 22: return GetField(nameof(CpuThreadState.X22));
- case 23: return GetField(nameof(CpuThreadState.X23));
- case 24: return GetField(nameof(CpuThreadState.X24));
- case 25: return GetField(nameof(CpuThreadState.X25));
- case 26: return GetField(nameof(CpuThreadState.X26));
- case 27: return GetField(nameof(CpuThreadState.X27));
- case 28: return GetField(nameof(CpuThreadState.X28));
- case 29: return GetField(nameof(CpuThreadState.X29));
- case 30: return GetField(nameof(CpuThreadState.X30));
- case 31: return GetField(nameof(CpuThreadState.X31));
- }
-
- throw new InvalidOperationException();
- }
-
- private FieldInfo GetFieldVector()
- {
- switch (Index)
- {
- case 0: return GetField(nameof(CpuThreadState.V0));
- case 1: return GetField(nameof(CpuThreadState.V1));
- case 2: return GetField(nameof(CpuThreadState.V2));
- case 3: return GetField(nameof(CpuThreadState.V3));
- case 4: return GetField(nameof(CpuThreadState.V4));
- case 5: return GetField(nameof(CpuThreadState.V5));
- case 6: return GetField(nameof(CpuThreadState.V6));
- case 7: return GetField(nameof(CpuThreadState.V7));
- case 8: return GetField(nameof(CpuThreadState.V8));
- case 9: return GetField(nameof(CpuThreadState.V9));
- case 10: return GetField(nameof(CpuThreadState.V10));
- case 11: return GetField(nameof(CpuThreadState.V11));
- case 12: return GetField(nameof(CpuThreadState.V12));
- case 13: return GetField(nameof(CpuThreadState.V13));
- case 14: return GetField(nameof(CpuThreadState.V14));
- case 15: return GetField(nameof(CpuThreadState.V15));
- case 16: return GetField(nameof(CpuThreadState.V16));
- case 17: return GetField(nameof(CpuThreadState.V17));
- case 18: return GetField(nameof(CpuThreadState.V18));
- case 19: return GetField(nameof(CpuThreadState.V19));
- case 20: return GetField(nameof(CpuThreadState.V20));
- case 21: return GetField(nameof(CpuThreadState.V21));
- case 22: return GetField(nameof(CpuThreadState.V22));
- case 23: return GetField(nameof(CpuThreadState.V23));
- case 24: return GetField(nameof(CpuThreadState.V24));
- case 25: return GetField(nameof(CpuThreadState.V25));
- case 26: return GetField(nameof(CpuThreadState.V26));
- case 27: return GetField(nameof(CpuThreadState.V27));
- case 28: return GetField(nameof(CpuThreadState.V28));
- case 29: return GetField(nameof(CpuThreadState.V29));
- case 30: return GetField(nameof(CpuThreadState.V30));
- case 31: return GetField(nameof(CpuThreadState.V31));
- }
-
- throw new InvalidOperationException();
- }
-
- private FieldInfo GetField(string name)
- {
- return typeof(CpuThreadState).GetField(name);
- }
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/State/RegisterAlias.cs b/ChocolArm64/State/RegisterAlias.cs
deleted file mode 100644
index 8c2b95d7..00000000
--- a/ChocolArm64/State/RegisterAlias.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-namespace ChocolArm64.State
-{
- static class RegisterAlias
- {
- public const int R8Usr = 8;
- public const int R9Usr = 9;
- public const int R10Usr = 10;
- public const int R11Usr = 11;
- public const int R12Usr = 12;
- public const int SpUsr = 13;
- public const int LrUsr = 14;
-
- public const int SpHyp = 15;
-
- public const int LrIrq = 16;
- public const int SpIrq = 17;
-
- public const int LrSvc = 18;
- public const int SpSvc = 19;
-
- public const int LrAbt = 20;
- public const int SpAbt = 21;
-
- public const int LrUnd = 22;
- public const int SpUnd = 23;
-
- public const int R8Fiq = 24;
- public const int R9Fiq = 25;
- public const int R10Fiq = 26;
- public const int R11Fiq = 27;
- public const int R12Fiq = 28;
- public const int SpFiq = 29;
- public const int LrFiq = 30;
-
- public const int Aarch32Lr = 14;
- public const int Aarch32Pc = 15;
-
- public const int Lr = 30;
- public const int Zr = 31;
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/State/RegisterConsts.cs b/ChocolArm64/State/RegisterConsts.cs
deleted file mode 100644
index 8c34789c..00000000
--- a/ChocolArm64/State/RegisterConsts.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace ChocolArm64.State
-{
- static class RegisterConsts
- {
- public const int RegsCount = 32;
- public const int RegsMask = RegsCount - 1;
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/State/RegisterSize.cs b/ChocolArm64/State/RegisterSize.cs
deleted file mode 100644
index 7cc99599..00000000
--- a/ChocolArm64/State/RegisterSize.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace ChocolArm64.State
-{
- enum RegisterSize
- {
- Int32,
- Int64,
- Simd64,
- Simd128
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/State/RegisterType.cs b/ChocolArm64/State/RegisterType.cs
deleted file mode 100644
index 4476d044..00000000
--- a/ChocolArm64/State/RegisterType.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace ChocolArm64.State
-{
- enum RegisterType
- {
- Flag,
- Int,
- Vector
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/State/RoundMode.cs b/ChocolArm64/State/RoundMode.cs
deleted file mode 100644
index b687cc8e..00000000
--- a/ChocolArm64/State/RoundMode.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace ChocolArm64.State
-{
- enum RoundMode
- {
- ToNearest = 0,
- TowardsPlusInfinity = 1,
- TowardsMinusInfinity = 2,
- TowardsZero = 3
- }
-}
diff --git a/ChocolArm64/Translation/CallType.cs b/ChocolArm64/Translation/CallType.cs
deleted file mode 100644
index 937ede76..00000000
--- a/ChocolArm64/Translation/CallType.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace ChocolArm64.Translation
-{
- enum CallType
- {
- Call,
- VirtualCall,
- VirtualJump
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/Translation/ILEmitterCtx.cs b/ChocolArm64/Translation/ILEmitterCtx.cs
deleted file mode 100644
index 0deb29b2..00000000
--- a/ChocolArm64/Translation/ILEmitterCtx.cs
+++ /dev/null
@@ -1,709 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.Instructions;
-using ChocolArm64.IntermediateRepresentation;
-using ChocolArm64.Memory;
-using ChocolArm64.State;
-using System;
-using System.Collections.Generic;
-using System.Reflection;
-using System.Reflection.Emit;
-
-namespace ChocolArm64.Translation
-{
- class ILEmitterCtx
- {
- public MemoryManager Memory { get; }
-
- private TranslatorCache _cache;
- private TranslatorQueue _queue;
-
- private Block _currBlock;
-
- public Block CurrBlock
- {
- get
- {
- return _currBlock;
- }
- set
- {
- _currBlock = value;
-
- ResetBlockState();
- }
- }
-
- public OpCode64 CurrOp { get; set; }
-
- public TranslationTier Tier { get; }
-
- public Aarch32Mode Mode { get; } = Aarch32Mode.User; //TODO
-
- public bool HasIndirectJump { get; set; }
-
- public bool HasSlowCall { get; set; }
-
- private Dictionary<long, ILLabel> _labels;
-
- private Dictionary<ILLabel, BasicBlock> _irLabels;
-
- private List<BasicBlock> _irBlocks;
-
- private BasicBlock _irBlock;
-
- private bool _needsNewBlock;
-
- private OpCode64 _optOpLastCompare;
- private OpCode64 _optOpLastFlagSet;
-
- // This is the index of the temporary register, used to store temporary
- // values needed by some functions, since IL doesn't have a swap instruction.
- // You can use any value here as long it doesn't conflict with the indices
- // for the other registers. Any value >= 64 or < 0 will do.
- private const int ReservedLocalsCount = 64;
-
- private const int RorTmpIndex = ReservedLocalsCount + 0;
- private const int CmpOptTmp1Index = ReservedLocalsCount + 1;
- private const int CmpOptTmp2Index = ReservedLocalsCount + 2;
- private const int IntGpTmp1Index = ReservedLocalsCount + 3;
- private const int IntGpTmp2Index = ReservedLocalsCount + 4;
- private const int UserIntTempStart = ReservedLocalsCount + 5;
-
- // Vectors are part of another "set" of locals.
- private const int VecGpTmp1Index = ReservedLocalsCount + 0;
- private const int VecGpTmp2Index = ReservedLocalsCount + 1;
- private const int VecGpTmp3Index = ReservedLocalsCount + 2;
- private const int UserVecTempStart = ReservedLocalsCount + 3;
-
- private static int _userIntTempCount;
- private static int _userVecTempCount;
-
- public ILEmitterCtx(
- MemoryManager memory,
- TranslatorCache cache,
- TranslatorQueue queue,
- TranslationTier tier)
- {
- Memory = memory ?? throw new ArgumentNullException(nameof(memory));
- _cache = cache ?? throw new ArgumentNullException(nameof(cache));
- _queue = queue ?? throw new ArgumentNullException(nameof(queue));
-
- Tier = tier;
-
- _labels = new Dictionary<long, ILLabel>();
-
- _irLabels = new Dictionary<ILLabel, BasicBlock>();
-
- _irBlocks = new List<BasicBlock>();
-
- NewNextBlock();
-
- EmitSynchronization();
-
- EmitLoadContext();
- }
-
- public static int GetIntTempIndex()
- {
- return UserIntTempStart + _userIntTempCount++;
- }
-
- public static int GetVecTempIndex()
- {
- return UserVecTempStart + _userVecTempCount++;
- }
-
- public BasicBlock[] GetBlocks()
- {
- return _irBlocks.ToArray();
- }
-
- public void EmitSynchronization()
- {
- EmitLdarg(TranslatedSub.StateArgIdx);
-
- EmitPrivateCall(typeof(CpuThreadState), nameof(CpuThreadState.Synchronize));
-
- EmitLdc_I4(0);
-
- ILLabel lblContinue = new ILLabel();
-
- Emit(OpCodes.Bne_Un_S, lblContinue);
-
- EmitLdc_I8(0);
-
- Emit(OpCodes.Ret);
-
- MarkLabel(lblContinue);
- }
-
- public void ResetBlockStateForPredicatedOp()
- {
- // Check if this is a predicated instruction that modifies flags,
- // in this case the value of the flags is unknown as we don't know
- // in advance if the instruction is going to be executed or not.
- // So, we reset the block state to prevent an invalid optimization.
- if (CurrOp == _optOpLastFlagSet)
- {
- ResetBlockState();
- }
- }
-
- private void ResetBlockState()
- {
- _optOpLastFlagSet = null;
- _optOpLastCompare = null;
- }
-
- public void TranslateAhead(long position, ExecutionMode mode = ExecutionMode.Aarch64)
- {
- if (_cache.TryGetSubroutine(position, out TranslatedSub sub) && sub.Tier != TranslationTier.Tier0)
- {
- return;
- }
-
- _queue.Enqueue(position, mode, TranslationTier.Tier1, isComplete: true);
- }
-
- public bool TryOptEmitSubroutineCall()
- {
- // Calls should always have a next block, unless
- // we're translating a single basic block.
- if (_currBlock.Next == null)
- {
- return false;
- }
-
- if (!(CurrOp is IOpCodeBImm op))
- {
- return false;
- }
-
- if (!_cache.TryGetSubroutine(op.Imm, out TranslatedSub sub) || sub.Tier != TranslationTier.Tier0)
- {
- return false;
- }
-
- EmitStoreContext();
-
- for (int index = 0; index < TranslatedSub.FixedArgTypes.Length; index++)
- {
- EmitLdarg(index);
- }
-
- EmitCall(sub.Method);
-
- return true;
- }
-
- public void TryOptMarkCondWithoutCmp()
- {
- _optOpLastCompare = CurrOp;
-
- InstEmitAluHelper.EmitAluLoadOpers(this);
-
- Stloc(CmpOptTmp2Index, RegisterType.Int);
- Stloc(CmpOptTmp1Index, RegisterType.Int);
- }
-
- private Dictionary<Condition, OpCode> _branchOps = new Dictionary<Condition, OpCode>()
- {
- { Condition.Eq, OpCodes.Beq },
- { Condition.Ne, OpCodes.Bne_Un },
- { Condition.GeUn, OpCodes.Bge_Un },
- { Condition.LtUn, OpCodes.Blt_Un },
- { Condition.GtUn, OpCodes.Bgt_Un },
- { Condition.LeUn, OpCodes.Ble_Un },
- { Condition.Ge, OpCodes.Bge },
- { Condition.Lt, OpCodes.Blt },
- { Condition.Gt, OpCodes.Bgt },
- { Condition.Le, OpCodes.Ble }
- };
-
- public void EmitCondBranch(ILLabel target, Condition cond)
- {
- if (_optOpLastCompare != null &&
- _optOpLastCompare == _optOpLastFlagSet && _branchOps.ContainsKey(cond))
- {
- if (_optOpLastCompare.Emitter == InstEmit.Subs)
- {
- Ldloc(CmpOptTmp1Index, RegisterType.Int, _optOpLastCompare.RegisterSize);
- Ldloc(CmpOptTmp2Index, RegisterType.Int, _optOpLastCompare.RegisterSize);
-
- Emit(_branchOps[cond], target);
-
- return;
- }
- else if (_optOpLastCompare.Emitter == InstEmit.Adds && cond != Condition.GeUn
- && cond != Condition.LtUn
- && cond != Condition.GtUn
- && cond != Condition.LeUn)
- {
- // There are several limitations that needs to be taken into account for CMN comparisons:
- // - The unsigned comparisons are not valid, as they depend on the
- // carry flag value, and they will have different values for addition and
- // subtraction. For addition, it's carry, and for subtraction, it's borrow.
- // So, we need to make sure we're not doing a unsigned compare for the CMN case.
- // - We can only do the optimization for the immediate variants,
- // because when the second operand value is exactly INT_MIN, we can't
- // negate the value as theres no positive counterpart.
- // Such invalid values can't be encoded on the immediate encodings.
- if (_optOpLastCompare is IOpCodeAluImm64 op)
- {
- Ldloc(CmpOptTmp1Index, RegisterType.Int, _optOpLastCompare.RegisterSize);
-
- if (_optOpLastCompare.RegisterSize == RegisterSize.Int32)
- {
- EmitLdc_I4((int)-op.Imm);
- }
- else
- {
- EmitLdc_I8(-op.Imm);
- }
-
- Emit(_branchOps[cond], target);
-
- return;
- }
- }
- }
-
- OpCode ilOp;
-
- int intCond = (int)cond;
-
- if (intCond < 14)
- {
- int condTrue = intCond >> 1;
-
- switch (condTrue)
- {
- case 0: EmitLdflg((int)PState.ZBit); break;
- case 1: EmitLdflg((int)PState.CBit); break;
- case 2: EmitLdflg((int)PState.NBit); break;
- case 3: EmitLdflg((int)PState.VBit); break;
-
- case 4:
- EmitLdflg((int)PState.CBit);
- EmitLdflg((int)PState.ZBit);
-
- Emit(OpCodes.Not);
- Emit(OpCodes.And);
- break;
-
- case 5:
- case 6:
- EmitLdflg((int)PState.NBit);
- EmitLdflg((int)PState.VBit);
-
- Emit(OpCodes.Ceq);
-
- if (condTrue == 6)
- {
- EmitLdflg((int)PState.ZBit);
-
- Emit(OpCodes.Not);
- Emit(OpCodes.And);
- }
- break;
- }
-
- ilOp = (intCond & 1) != 0 ? OpCodes.Brfalse : OpCodes.Brtrue;
- }
- else
- {
- ilOp = OpCodes.Br;
- }
-
- Emit(ilOp, target);
- }
-
- public void EmitCast(IntType intType)
- {
- switch (intType)
- {
- case IntType.UInt8: Emit(OpCodes.Conv_U1); break;
- case IntType.UInt16: Emit(OpCodes.Conv_U2); break;
- case IntType.UInt32: Emit(OpCodes.Conv_U4); break;
- case IntType.UInt64: Emit(OpCodes.Conv_U8); break;
- case IntType.Int8: Emit(OpCodes.Conv_I1); break;
- case IntType.Int16: Emit(OpCodes.Conv_I2); break;
- case IntType.Int32: Emit(OpCodes.Conv_I4); break;
- case IntType.Int64: Emit(OpCodes.Conv_I8); break;
- }
-
- bool sz64 = CurrOp.RegisterSize != RegisterSize.Int32;
-
- if (sz64 == (intType == IntType.UInt64 || intType == IntType.Int64))
- {
- return;
- }
-
- if (sz64)
- {
- Emit(intType >= IntType.Int8 ? OpCodes.Conv_I8 : OpCodes.Conv_U8);
- }
- else
- {
- Emit(OpCodes.Conv_U4);
- }
- }
-
- public void EmitLsl(int amount) => EmitILShift(amount, OpCodes.Shl);
- public void EmitLsr(int amount) => EmitILShift(amount, OpCodes.Shr_Un);
- public void EmitAsr(int amount) => EmitILShift(amount, OpCodes.Shr);
-
- private void EmitILShift(int amount, OpCode ilOp)
- {
- if (amount > 0)
- {
- EmitLdc_I4(amount);
-
- Emit(ilOp);
- }
- }
-
- public void EmitRor(int amount)
- {
- if (amount > 0)
- {
- Stloc(RorTmpIndex, RegisterType.Int);
- Ldloc(RorTmpIndex, RegisterType.Int);
-
- EmitLdc_I4(amount);
-
- Emit(OpCodes.Shr_Un);
-
- Ldloc(RorTmpIndex, RegisterType.Int);
-
- EmitLdc_I4(CurrOp.GetBitsCount() - amount);
-
- Emit(OpCodes.Shl);
- Emit(OpCodes.Or);
- }
- }
-
- public ILLabel GetLabel(long position)
- {
- if (!_labels.TryGetValue(position, out ILLabel output))
- {
- output = new ILLabel();
-
- _labels.Add(position, output);
- }
-
- return output;
- }
-
- public void MarkLabel(ILLabel label)
- {
- if (_irLabels.TryGetValue(label, out BasicBlock nextBlock))
- {
- nextBlock.Index = _irBlocks.Count;
-
- _irBlocks.Add(nextBlock);
-
- NextBlock(nextBlock);
- }
- else
- {
- NewNextBlock();
-
- _irLabels.Add(label, _irBlock);
- }
-
- AddOperation(Operation.MarkLabel(label));
- }
-
- public void Emit(OpCode ilOp)
- {
- AddOperation(Operation.IL(ilOp));
-
- if (ilOp == OpCodes.Ret)
- {
- NextBlock(null);
-
- _needsNewBlock = true;
- }
- }
-
- public void Emit(OpCode ilOp, ILLabel label)
- {
- AddOperation(Operation.ILBranch(ilOp, label));
-
- _needsNewBlock = true;
-
- if (!_irLabels.TryGetValue(label, out BasicBlock branchBlock))
- {
- branchBlock = new BasicBlock();
-
- _irLabels.Add(label, branchBlock);
- }
-
- _irBlock.Branch = branchBlock;
- }
-
- public void EmitLdfld(FieldInfo info)
- {
- AddOperation(Operation.LoadField(info));
- }
-
- public void EmitLdarg(int index)
- {
- AddOperation(Operation.LoadArgument(index));
- }
-
- public void EmitLdintzr(int index)
- {
- if (index != RegisterAlias.Zr)
- {
- EmitLdint(index);
- }
- else
- {
- EmitLdc_I(0);
- }
- }
-
- public void EmitStintzr(int index)
- {
- if (index != RegisterAlias.Zr)
- {
- EmitStint(index);
- }
- else
- {
- Emit(OpCodes.Pop);
- }
- }
-
- public void EmitLoadContext()
- {
- _needsNewBlock = true;
-
- AddOperation(Operation.LoadContext());
- }
-
- public void EmitStoreContext()
- {
- AddOperation(Operation.StoreContext());
- }
-
- public void EmitLdtmp() => EmitLdint(IntGpTmp1Index);
- public void EmitSttmp() => EmitStint(IntGpTmp1Index);
-
- public void EmitLdtmp2() => EmitLdint(IntGpTmp2Index);
- public void EmitSttmp2() => EmitStint(IntGpTmp2Index);
-
- public void EmitLdvectmp() => EmitLdvec(VecGpTmp1Index);
- public void EmitStvectmp() => EmitStvec(VecGpTmp1Index);
-
- public void EmitLdvectmp2() => EmitLdvec(VecGpTmp2Index);
- public void EmitStvectmp2() => EmitStvec(VecGpTmp2Index);
-
- public void EmitLdvectmp3() => EmitLdvec(VecGpTmp3Index);
- public void EmitStvectmp3() => EmitStvec(VecGpTmp3Index);
-
- public void EmitLdint(int index) => Ldloc(index, RegisterType.Int);
- public void EmitStint(int index) => Stloc(index, RegisterType.Int);
-
- public void EmitLdvec(int index) => Ldloc(index, RegisterType.Vector);
- public void EmitStvec(int index) => Stloc(index, RegisterType.Vector);
-
- public void EmitLdflg(int index) => Ldloc(index, RegisterType.Flag);
- public void EmitStflg(int index)
- {
- // Set this only if any of the NZCV flag bits were modified.
- // This is used to ensure that when emiting a direct IL branch
- // instruction for compare + branch sequences, we're not expecting
- // to use comparison values from an old instruction, when in fact
- // the flags were already overwritten by another instruction further along.
- if (index >= (int)PState.VBit)
- {
- _optOpLastFlagSet = CurrOp;
- }
-
- Stloc(index, RegisterType.Flag);
- }
-
- private void Ldloc(int index, RegisterType type)
- {
- AddOperation(Operation.LoadLocal(index, type, CurrOp.RegisterSize));
- }
-
- private void Ldloc(int index, RegisterType type, RegisterSize size)
- {
- AddOperation(Operation.LoadLocal(index, type, size));
- }
-
- private void Stloc(int index, RegisterType type)
- {
- AddOperation(Operation.StoreLocal(index, type, CurrOp.RegisterSize));
- }
-
- public void EmitCallPropGet(Type objType, string propName)
- {
- EmitCall(objType, $"get_{propName}");
- }
-
- public void EmitCallPropSet(Type objType, string propName)
- {
- EmitCall(objType, $"set_{propName}");
- }
-
- public void EmitCall(Type objType, string mthdName)
- {
- if (objType == null)
- {
- throw new ArgumentNullException(nameof(objType));
- }
-
- if (mthdName == null)
- {
- throw new ArgumentNullException(nameof(mthdName));
- }
-
- EmitCall(objType.GetMethod(mthdName));
- }
-
- public void EmitCallPrivatePropGet(Type objType, string propName)
- {
- EmitPrivateCall(objType, $"get_{propName}");
- }
-
- public void EmitCallPrivatePropSet(Type objType, string propName)
- {
- EmitPrivateCall(objType, $"set_{propName}");
- }
-
- public void EmitPrivateCall(Type objType, string mthdName)
- {
- if (objType == null)
- {
- throw new ArgumentNullException(nameof(objType));
- }
-
- if (mthdName == null)
- {
- throw new ArgumentNullException(nameof(mthdName));
- }
-
- EmitCall(objType.GetMethod(mthdName, BindingFlags.Instance | BindingFlags.NonPublic));
- }
-
- public void EmitCall(MethodInfo mthdInfo, bool isVirtual = false)
- {
- if (mthdInfo == null)
- {
- throw new ArgumentNullException(nameof(mthdInfo));
- }
-
- if (isVirtual)
- {
- AddOperation(Operation.CallVirtual(mthdInfo));
- }
- else
- {
- AddOperation(Operation.Call(mthdInfo));
- }
- }
-
- public void EmitLdc_I(long value)
- {
- if (CurrOp.RegisterSize == RegisterSize.Int32)
- {
- EmitLdc_I4((int)value);
- }
- else
- {
- EmitLdc_I8(value);
- }
- }
-
- public void EmitLdc_I4(int value)
- {
- AddOperation(Operation.LoadConstant(value));
- }
-
- public void EmitLdc_I8(long value)
- {
- AddOperation(Operation.LoadConstant(value));
- }
-
- public void EmitLdc_R4(float value)
- {
- AddOperation(Operation.LoadConstant(value));
- }
-
- public void EmitLdc_R8(double value)
- {
- AddOperation(Operation.LoadConstant(value));
- }
-
- public void EmitZnFlagCheck()
- {
- EmitZnCheck(OpCodes.Ceq, (int)PState.ZBit);
- EmitZnCheck(OpCodes.Clt, (int)PState.NBit);
- }
-
- private void EmitZnCheck(OpCode ilCmpOp, int flag)
- {
- Emit(OpCodes.Dup);
- Emit(OpCodes.Ldc_I4_0);
-
- if (CurrOp.RegisterSize != RegisterSize.Int32)
- {
- Emit(OpCodes.Conv_I8);
- }
-
- Emit(ilCmpOp);
-
- EmitStflg(flag);
- }
-
- private void AddOperation(Operation operation)
- {
- if (_needsNewBlock)
- {
- NewNextBlock();
- }
-
- _irBlock.Add(operation);
- }
-
- private void NewNextBlock()
- {
- BasicBlock block = new BasicBlock(_irBlocks.Count);
-
- _irBlocks.Add(block);
-
- NextBlock(block);
- }
-
- private void NextBlock(BasicBlock nextBlock)
- {
- if (_irBlock != null && !EndsWithUnconditional(_irBlock))
- {
- _irBlock.Next = nextBlock;
- }
-
- _irBlock = nextBlock;
-
- _needsNewBlock = false;
- }
-
- private static bool EndsWithUnconditional(BasicBlock block)
- {
- Operation lastOp = block.GetLastOp();
-
- if (lastOp == null || lastOp.Type != OperationType.ILBranch)
- {
- return false;
- }
-
- OpCode opCode = lastOp.GetArg<OpCode>(0);
-
- return opCode == OpCodes.Br || opCode == OpCodes.Br_S;
- }
- }
-}
diff --git a/ChocolArm64/Translation/ILGeneratorEx.cs b/ChocolArm64/Translation/ILGeneratorEx.cs
deleted file mode 100644
index 6b1512d2..00000000
--- a/ChocolArm64/Translation/ILGeneratorEx.cs
+++ /dev/null
@@ -1,121 +0,0 @@
-using System;
-
-namespace ChocolArm64
-{
- using System.Reflection.Emit;
-
- static class ILGeneratorEx
- {
- public static void EmitLdc_I4(this ILGenerator generator, int value)
- {
- switch (value)
- {
- case 0: generator.Emit(OpCodes.Ldc_I4_0); break;
- case 1: generator.Emit(OpCodes.Ldc_I4_1); break;
- case 2: generator.Emit(OpCodes.Ldc_I4_2); break;
- case 3: generator.Emit(OpCodes.Ldc_I4_3); break;
- case 4: generator.Emit(OpCodes.Ldc_I4_4); break;
- case 5: generator.Emit(OpCodes.Ldc_I4_5); break;
- case 6: generator.Emit(OpCodes.Ldc_I4_6); break;
- case 7: generator.Emit(OpCodes.Ldc_I4_7); break;
- case 8: generator.Emit(OpCodes.Ldc_I4_8); break;
- case -1: generator.Emit(OpCodes.Ldc_I4_M1); break;
- default: generator.Emit(OpCodes.Ldc_I4, value); break;
- }
- }
-
- public static void EmitLdarg(this ILGenerator generator, int index)
- {
- switch (index)
- {
- case 0: generator.Emit(OpCodes.Ldarg_0); break;
- case 1: generator.Emit(OpCodes.Ldarg_1); break;
- case 2: generator.Emit(OpCodes.Ldarg_2); break;
- case 3: generator.Emit(OpCodes.Ldarg_3); break;
-
- default:
- if ((uint)index <= byte.MaxValue)
- {
- generator.Emit(OpCodes.Ldarg_S, (byte)index);
- }
- else if ((uint)index < ushort.MaxValue)
- {
- generator.Emit(OpCodes.Ldarg, (short)index);
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- break;
- }
- }
-
- public static void EmitStarg(this ILGenerator generator, int index)
- {
- if ((uint)index <= byte.MaxValue)
- {
- generator.Emit(OpCodes.Starg_S, (byte)index);
- }
- else if ((uint)index < ushort.MaxValue)
- {
- generator.Emit(OpCodes.Starg, (short)index);
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- }
-
- public static void EmitLdloc(this ILGenerator generator, int index)
- {
- switch (index)
- {
- case 0: generator.Emit(OpCodes.Ldloc_0); break;
- case 1: generator.Emit(OpCodes.Ldloc_1); break;
- case 2: generator.Emit(OpCodes.Ldloc_2); break;
- case 3: generator.Emit(OpCodes.Ldloc_3); break;
-
- default:
- if ((uint)index <= byte.MaxValue)
- {
- generator.Emit(OpCodes.Ldloc_S, (byte)index);
- }
- else if ((uint)index < ushort.MaxValue)
- {
- generator.Emit(OpCodes.Ldloc, (short)index);
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- break;
- }
- }
-
- public static void EmitStloc(this ILGenerator generator, int index)
- {
- switch (index)
- {
- case 0: generator.Emit(OpCodes.Stloc_0); break;
- case 1: generator.Emit(OpCodes.Stloc_1); break;
- case 2: generator.Emit(OpCodes.Stloc_2); break;
- case 3: generator.Emit(OpCodes.Stloc_3); break;
-
- default:
- if ((uint)index <= byte.MaxValue)
- {
- generator.Emit(OpCodes.Stloc_S, (byte)index);
- }
- else if ((uint)index < ushort.MaxValue)
- {
- generator.Emit(OpCodes.Stloc, (short)index);
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- break;
- }
- }
- }
-}
diff --git a/ChocolArm64/Translation/RegisterUsage.cs b/ChocolArm64/Translation/RegisterUsage.cs
deleted file mode 100644
index f88fa0cd..00000000
--- a/ChocolArm64/Translation/RegisterUsage.cs
+++ /dev/null
@@ -1,176 +0,0 @@
-using ChocolArm64.IntermediateRepresentation;
-using ChocolArm64.State;
-using System.Collections.Generic;
-
-namespace ChocolArm64.Translation
-{
- class RegisterUsage
- {
- private const long CallerSavedIntRegistersMask = 0x7fL << 9;
- private const long PStateNzcvFlagsMask = 0xfL << 60;
-
- private const long CallerSavedVecRegistersMask = 0xffffL << 16;
-
- private RegisterMask[] _inputs;
- private RegisterMask[] _outputs;
-
- public RegisterUsage(BasicBlock entryBlock, int blocksCount)
- {
- _inputs = new RegisterMask[blocksCount];
- _outputs = new RegisterMask[blocksCount];
-
- HashSet<BasicBlock> visited = new HashSet<BasicBlock>();
-
- Stack<BasicBlock> blockStack = new Stack<BasicBlock>();
-
- List<BasicBlock> postOrderBlocks = new List<BasicBlock>(blocksCount);
-
- visited.Add(entryBlock);
-
- blockStack.Push(entryBlock);
-
- while (blockStack.TryPop(out BasicBlock block))
- {
- if (block.Next != null && visited.Add(block.Next))
- {
- blockStack.Push(block);
- blockStack.Push(block.Next);
- }
- else if (block.Branch != null && visited.Add(block.Branch))
- {
- blockStack.Push(block);
- blockStack.Push(block.Branch);
- }
- else
- {
- postOrderBlocks.Add(block);
- }
- }
-
- RegisterMask[] cmnOutputMasks = new RegisterMask[blocksCount];
-
- bool modified;
-
- bool firstPass = true;
-
- do
- {
- modified = false;
-
- for (int blkIndex = postOrderBlocks.Count - 1; blkIndex >= 0; blkIndex--)
- {
- BasicBlock block = postOrderBlocks[blkIndex];
-
- if (block.Predecessors.Count != 0 && !block.HasStateLoad)
- {
- BasicBlock predecessor = block.Predecessors[0];
-
- RegisterMask cmnOutputs = predecessor.RegOutputs | cmnOutputMasks[predecessor.Index];
-
- RegisterMask outputs = _outputs[predecessor.Index];
-
- for (int pIndex = 1; pIndex < block.Predecessors.Count; pIndex++)
- {
- predecessor = block.Predecessors[pIndex];
-
- cmnOutputs &= predecessor.RegOutputs | cmnOutputMasks[predecessor.Index];
-
- outputs |= _outputs[predecessor.Index];
- }
-
- _inputs[block.Index] |= outputs & ~cmnOutputs;
-
- if (!firstPass)
- {
- cmnOutputs &= cmnOutputMasks[block.Index];
- }
-
- if (Exchange(cmnOutputMasks, block.Index, cmnOutputs))
- {
- modified = true;
- }
-
- outputs |= block.RegOutputs;
-
- if (Exchange(_outputs, block.Index, _outputs[block.Index] | outputs))
- {
- modified = true;
- }
- }
- else if (Exchange(_outputs, block.Index, block.RegOutputs))
- {
- modified = true;
- }
- }
-
- firstPass = false;
- }
- while (modified);
-
- do
- {
- modified = false;
-
- for (int blkIndex = 0; blkIndex < postOrderBlocks.Count; blkIndex++)
- {
- BasicBlock block = postOrderBlocks[blkIndex];
-
- RegisterMask inputs = block.RegInputs;
-
- if (block.Next != null)
- {
- inputs |= _inputs[block.Next.Index];
- }
-
- if (block.Branch != null)
- {
- inputs |= _inputs[block.Branch.Index];
- }
-
- inputs &= ~cmnOutputMasks[block.Index];
-
- if (Exchange(_inputs, block.Index, _inputs[block.Index] | inputs))
- {
- modified = true;
- }
- }
- }
- while (modified);
- }
-
- private static bool Exchange(RegisterMask[] masks, int blkIndex, RegisterMask value)
- {
- RegisterMask oldValue = masks[blkIndex];
-
- masks[blkIndex] = value;
-
- return oldValue != value;
- }
-
- public RegisterMask GetInputs(BasicBlock entryBlock) => _inputs[entryBlock.Index];
-
- public RegisterMask GetOutputs(BasicBlock block) => _outputs[block.Index];
-
- public static long ClearCallerSavedIntRegs(long mask, ExecutionMode mode)
- {
- // TODO: ARM32 support.
- if (mode == ExecutionMode.Aarch64)
- {
- mask &= ~(CallerSavedIntRegistersMask | PStateNzcvFlagsMask);
- }
-
- return mask;
- }
-
- public static long ClearCallerSavedVecRegs(long mask, ExecutionMode mode)
- {
- // TODO: ARM32 support.
- if (mode == ExecutionMode.Aarch64)
- {
- mask &= ~CallerSavedVecRegistersMask;
- }
-
- return mask;
- }
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/Translation/TranslatedSub.cs b/ChocolArm64/Translation/TranslatedSub.cs
deleted file mode 100644
index cf42e202..00000000
--- a/ChocolArm64/Translation/TranslatedSub.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-using ChocolArm64.Memory;
-using ChocolArm64.State;
-using System;
-using System.Reflection;
-using System.Reflection.Emit;
-
-namespace ChocolArm64.Translation
-{
- delegate long ArmSubroutine(CpuThreadState state, MemoryManager memory);
-
- class TranslatedSub
- {
- // This is the minimum amount of calls needed for the method
- // to be retranslated with higher quality code. It's only worth
- // doing that for hot code.
- private const int MinCallCountForOpt = 30;
-
- public ArmSubroutine Delegate { get; private set; }
-
- public static int StateArgIdx { get; }
- public static int MemoryArgIdx { get; }
-
- public static Type[] FixedArgTypes { get; }
-
- public DynamicMethod Method { get; }
-
- public TranslationTier Tier { get; }
-
- private bool _rejit;
-
- private int _callCount;
-
- public TranslatedSub(DynamicMethod method, TranslationTier tier, bool rejit)
- {
- Method = method ?? throw new ArgumentNullException(nameof(method));
- Tier = tier;
- _rejit = rejit;
- }
-
- static TranslatedSub()
- {
- MethodInfo mthdInfo = typeof(ArmSubroutine).GetMethod("Invoke");
-
- ParameterInfo[] Params = mthdInfo.GetParameters();
-
- FixedArgTypes = new Type[Params.Length];
-
- for (int index = 0; index < Params.Length; index++)
- {
- Type argType = Params[index].ParameterType;
-
- FixedArgTypes[index] = argType;
-
- if (argType == typeof(CpuThreadState))
- {
- StateArgIdx = index;
- }
- else if (argType == typeof(MemoryManager))
- {
- MemoryArgIdx = index;
- }
- }
- }
-
- public void PrepareMethod()
- {
- Delegate = (ArmSubroutine)Method.CreateDelegate(typeof(ArmSubroutine));
- }
-
- public long Execute(CpuThreadState threadState, MemoryManager memory)
- {
- return Delegate(threadState, memory);
- }
-
- public bool Rejit()
- {
- if (!_rejit)
- {
- return false;
- }
-
- if (_callCount++ < MinCallCountForOpt)
- {
- return false;
- }
-
- // Only return true once, so that it is added to the queue only once.
- _rejit = false;
-
- return true;
- }
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/Translation/TranslatedSubBuilder.cs b/ChocolArm64/Translation/TranslatedSubBuilder.cs
deleted file mode 100644
index eb69d9ee..00000000
--- a/ChocolArm64/Translation/TranslatedSubBuilder.cs
+++ /dev/null
@@ -1,274 +0,0 @@
-using ChocolArm64.IntermediateRepresentation;
-using ChocolArm64.State;
-using System;
-using System.Collections.Generic;
-using System.Reflection;
-using System.Reflection.Emit;
-using System.Runtime.Intrinsics;
-
-using static ChocolArm64.State.RegisterConsts;
-
-namespace ChocolArm64.Translation
-{
- class TranslatedSubBuilder
- {
- private ExecutionMode _mode;
-
- private bool _isComplete;
-
- private Dictionary<Register, int> _locals;
-
- private RegisterUsage _regUsage;
-
- public TranslatedSubBuilder(ExecutionMode mode, bool isComplete = false)
- {
- _mode = mode;
- _isComplete = isComplete;
- }
-
- public TranslatedSub Build(BasicBlock[] blocks, string name, TranslationTier tier, bool rejit = true)
- {
- _regUsage = new RegisterUsage(blocks[0], blocks.Length);
-
- DynamicMethod method = new DynamicMethod(name, typeof(long), TranslatedSub.FixedArgTypes);
-
- TranslatedSub subroutine = new TranslatedSub(method, tier, rejit);
-
- _locals = new Dictionary<Register, int>();
-
- Dictionary<ILLabel, Label> labels = new Dictionary<ILLabel, Label>();
-
- ILGenerator generator = method.GetILGenerator();
-
- Label GetLabel(ILLabel label)
- {
- if (!labels.TryGetValue(label, out Label ilLabel))
- {
- ilLabel = generator.DefineLabel();
-
- labels.Add(label, ilLabel);
- }
-
- return ilLabel;
- }
-
- foreach (BasicBlock block in blocks)
- {
- for (int index = 0; index < block.Count; index++)
- {
- Operation operation = block.GetOperation(index);
-
- switch (operation.Type)
- {
- case OperationType.Call:
- generator.Emit(OpCodes.Call, operation.GetArg<MethodInfo>(0));
- break;
-
- case OperationType.CallVirtual:
- generator.Emit(OpCodes.Callvirt, operation.GetArg<MethodInfo>(0));
- break;
-
- case OperationType.IL:
- generator.Emit(operation.GetArg<OpCode>(0));
- break;
-
- case OperationType.ILBranch:
- generator.Emit(operation.GetArg<OpCode>(0), GetLabel(operation.GetArg<ILLabel>(1)));
- break;
-
- case OperationType.LoadArgument:
- generator.EmitLdarg(operation.GetArg<int>(0));
- break;
-
- case OperationType.LoadConstant:
- EmitLoadConstant(generator, operation.GetArg(0));
- break;
-
- case OperationType.LoadContext:
- EmitLoadContext(generator, operation.Parent);
- break;
-
- case OperationType.LoadField:
- generator.Emit(OpCodes.Ldfld, operation.GetArg<FieldInfo>(0));
- break;
-
- case OperationType.LoadLocal:
- EmitLoadLocal(
- generator,
- operation.GetArg<int>(0),
- operation.GetArg<RegisterType>(1),
- operation.GetArg<RegisterSize>(2));
- break;
-
- case OperationType.MarkLabel:
- generator.MarkLabel(GetLabel(operation.GetArg<ILLabel>(0)));
- break;
-
- case OperationType.StoreContext:
- EmitStoreContext(generator, operation.Parent);
- break;
-
- case OperationType.StoreLocal:
- EmitStoreLocal(
- generator,
- operation.GetArg<int>(0),
- operation.GetArg<RegisterType>(1),
- operation.GetArg<RegisterSize>(2));
- break;
- }
- }
- }
-
- subroutine.PrepareMethod();
-
- return subroutine;
- }
-
- private static void EmitLoadConstant(ILGenerator generator, object value)
- {
- switch (value)
- {
- case int valI4: generator.EmitLdc_I4(valI4); break;
- case long valI8: generator.Emit(OpCodes.Ldc_I8, valI8); break;
- case float valR4: generator.Emit(OpCodes.Ldc_R4, valR4); break;
- case double valR8: generator.Emit(OpCodes.Ldc_R8, valR8); break;
- }
- }
-
- private void EmitLoadContext(ILGenerator generator, BasicBlock block)
- {
- RegisterMask inputs = _regUsage.GetInputs(block);
-
- long intInputs = inputs.IntMask;
- long vecInputs = inputs.VecMask;
-
- if (Optimizations.AssumeStrictAbiCompliance && _isComplete)
- {
- intInputs = RegisterUsage.ClearCallerSavedIntRegs(intInputs, _mode);
- vecInputs = RegisterUsage.ClearCallerSavedVecRegs(vecInputs, _mode);
- }
-
- LoadLocals(generator, intInputs, RegisterType.Int);
- LoadLocals(generator, vecInputs, RegisterType.Vector);
- }
-
- private void LoadLocals(ILGenerator generator, long inputs, RegisterType baseType)
- {
- for (int bit = 0; bit < 64; bit++)
- {
- long mask = 1L << bit;
-
- if ((inputs & mask) != 0)
- {
- Register reg = GetRegFromBit(bit, baseType);
-
- generator.EmitLdarg(TranslatedSub.StateArgIdx);
- generator.Emit(OpCodes.Ldfld, reg.GetField());
-
- generator.EmitStloc(GetLocalIndex(generator, reg));
- }
- }
- }
-
- private void EmitStoreContext(ILGenerator generator, BasicBlock block)
- {
- RegisterMask outputs = _regUsage.GetOutputs(block);
-
- long intOutputs = outputs.IntMask;
- long vecOutputs = outputs.VecMask;
-
- if (Optimizations.AssumeStrictAbiCompliance && _isComplete)
- {
- intOutputs = RegisterUsage.ClearCallerSavedIntRegs(intOutputs, _mode);
- vecOutputs = RegisterUsage.ClearCallerSavedVecRegs(vecOutputs, _mode);
- }
-
- StoreLocals(generator, intOutputs, RegisterType.Int);
- StoreLocals(generator, vecOutputs, RegisterType.Vector);
- }
-
- private void StoreLocals(ILGenerator generator, long outputs, RegisterType baseType)
- {
- for (int bit = 0; bit < 64; bit++)
- {
- long mask = 1L << bit;
-
- if ((outputs & mask) != 0)
- {
- Register reg = GetRegFromBit(bit, baseType);
-
- generator.EmitLdarg(TranslatedSub.StateArgIdx);
- generator.EmitLdloc(GetLocalIndex(generator, reg));
-
- generator.Emit(OpCodes.Stfld, reg.GetField());
- }
- }
- }
-
- private void EmitLoadLocal(ILGenerator generator, int index, RegisterType type, RegisterSize size)
- {
- Register reg = new Register(index, type);
-
- generator.EmitLdloc(GetLocalIndex(generator, reg));
-
- if (type == RegisterType.Int && size == RegisterSize.Int32)
- {
- generator.Emit(OpCodes.Conv_U4);
- }
- }
-
- private void EmitStoreLocal(ILGenerator generator, int index, RegisterType type, RegisterSize size)
- {
- Register reg = new Register(index, type);
-
- if (type == RegisterType.Int && size == RegisterSize.Int32)
- {
- generator.Emit(OpCodes.Conv_U8);
- }
-
- generator.EmitStloc(GetLocalIndex(generator, reg));
- }
-
- private int GetLocalIndex(ILGenerator generator, Register reg)
- {
- if (!_locals.TryGetValue(reg, out int index))
- {
- generator.DeclareLocal(GetFieldType(reg.Type));
-
- index = _locals.Count;
-
- _locals.Add(reg, index);
- }
-
- return index;
- }
-
- private static Type GetFieldType(RegisterType regType)
- {
- switch (regType)
- {
- case RegisterType.Flag: return typeof(bool);
- case RegisterType.Int: return typeof(ulong);
- case RegisterType.Vector: return typeof(Vector128<float>);
- }
-
- throw new ArgumentException(nameof(regType));
- }
-
- private static Register GetRegFromBit(int bit, RegisterType baseType)
- {
- if (bit < RegsCount)
- {
- return new Register(bit, baseType);
- }
- else if (baseType == RegisterType.Int)
- {
- return new Register(bit & RegsMask, RegisterType.Flag);
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(bit));
- }
- }
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/Translation/TranslationTier.cs b/ChocolArm64/Translation/TranslationTier.cs
deleted file mode 100644
index 13afd9c5..00000000
--- a/ChocolArm64/Translation/TranslationTier.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace ChocolArm64.Translation
-{
- enum TranslationTier
- {
- Tier0,
- Tier1,
- Tier2,
-
- Count
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/Translation/Translator.cs b/ChocolArm64/Translation/Translator.cs
deleted file mode 100644
index ab8f474a..00000000
--- a/ChocolArm64/Translation/Translator.cs
+++ /dev/null
@@ -1,252 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.Events;
-using ChocolArm64.IntermediateRepresentation;
-using ChocolArm64.Memory;
-using ChocolArm64.State;
-using System;
-using System.Reflection.Emit;
-using System.Threading;
-
-namespace ChocolArm64.Translation
-{
- public class Translator : ARMeilleure.Translation.ITranslator
- {
- private MemoryManager _memory;
-
- private CpuThreadState _dummyThreadState;
-
- private TranslatorCache _cache;
- private TranslatorQueue _queue;
-
- private Thread _backgroundTranslator;
-
- public event EventHandler<CpuTraceEventArgs> CpuTrace;
-
- public bool EnableCpuTrace { get; set; }
-
- private volatile int _threadCount;
-
- public Translator(MemoryManager memory)
- {
- _memory = memory;
-
- _dummyThreadState = new CpuThreadState();
-
- _dummyThreadState.Running = false;
-
- _cache = new TranslatorCache();
- _queue = new TranslatorQueue();
- }
-
- public void Execute(ARMeilleure.State.IExecutionContext ctx, ulong address)
- {
- CpuThreadState state = (CpuThreadState)ctx;
-
- long position = (long)address;
-
- if (Interlocked.Increment(ref _threadCount) == 1)
- {
- _backgroundTranslator = new Thread(TranslateQueuedSubs);
- _backgroundTranslator.Start();
- }
-
- state.CurrentTranslator = this;
-
- do
- {
- if (EnableCpuTrace)
- {
- CpuTrace?.Invoke(this, new CpuTraceEventArgs(position));
- }
-
- if (!_cache.TryGetSubroutine(position, out TranslatedSub sub))
- {
- sub = TranslateLowCq(position, state.GetExecutionMode());
- }
-
- position = sub.Execute(state, _memory);
- }
- while (position != 0 && state.Running);
-
- state.CurrentTranslator = null;
-
- if (Interlocked.Decrement(ref _threadCount) == 0)
- {
- _queue.ForceSignal();
- }
- }
-
- internal ArmSubroutine GetOrTranslateSubroutine(CpuThreadState state, long position, CallType cs)
- {
- if (!_cache.TryGetSubroutine(position, out TranslatedSub sub))
- {
- sub = TranslateLowCq(position, state.GetExecutionMode());
- }
-
- if (sub.Rejit())
- {
- bool isComplete = cs == CallType.Call ||
- cs == CallType.VirtualCall;
-
- _queue.Enqueue(position, state.GetExecutionMode(), TranslationTier.Tier1, isComplete);
- }
-
- return sub.Delegate;
- }
-
- private void TranslateQueuedSubs()
- {
- while (_threadCount != 0)
- {
- if (_queue.TryDequeue(out TranslatorQueueItem item))
- {
- bool isCached = _cache.TryGetSubroutine(item.Position, out TranslatedSub sub);
-
- if (isCached && item.Tier <= sub.Tier)
- {
- continue;
- }
-
- if (item.Tier == TranslationTier.Tier0)
- {
- TranslateLowCq(item.Position, item.Mode);
- }
- else
- {
- TranslateHighCq(item.Position, item.Mode, item.IsComplete);
- }
- }
- else
- {
- _queue.WaitForItems();
- }
- }
- }
-
- private TranslatedSub TranslateLowCq(long position, ExecutionMode mode)
- {
- Block[] blocks = Decoder.DecodeBasicBlock(_memory, (ulong)position, mode);
-
- ILEmitterCtx context = new ILEmitterCtx(_memory, _cache, _queue, TranslationTier.Tier0);
-
- BasicBlock[] bbs = EmitAndGetBlocks(context, blocks);
-
- TranslatedSubBuilder builder = new TranslatedSubBuilder(mode);
-
- string name = GetSubroutineName(position);
-
- TranslatedSub subroutine = builder.Build(bbs, name, TranslationTier.Tier0);
-
- return _cache.GetOrAdd(position, subroutine, GetOpsCount(bbs));
- }
-
- private TranslatedSub TranslateHighCq(long position, ExecutionMode mode, bool isComplete)
- {
- Block[] blocks = Decoder.DecodeSubroutine(_memory, (ulong)position, mode);
-
- ILEmitterCtx context = new ILEmitterCtx(_memory, _cache, _queue, TranslationTier.Tier1);
-
- if (blocks[0].Address != (ulong)position)
- {
- context.Emit(OpCodes.Br, context.GetLabel(position));
- }
-
- BasicBlock[] bbs = EmitAndGetBlocks(context, blocks);
-
- isComplete &= !context.HasIndirectJump;
-
- TranslatedSubBuilder builder = new TranslatedSubBuilder(mode, isComplete);
-
- string name = GetSubroutineName(position);
-
- TranslatedSub subroutine = builder.Build(bbs, name, TranslationTier.Tier1, context.HasSlowCall);
-
- ForceAheadOfTimeCompilation(subroutine);
-
- _cache.AddOrUpdate(position, subroutine, GetOpsCount(bbs));
-
- return subroutine;
- }
-
- private static BasicBlock[] EmitAndGetBlocks(ILEmitterCtx context, Block[] blocks)
- {
- for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++)
- {
- Block block = blocks[blkIndex];
-
- context.CurrBlock = block;
-
- context.MarkLabel(context.GetLabel((long)block.Address));
-
- for (int opcIndex = 0; opcIndex < block.OpCodes.Count; opcIndex++)
- {
- OpCode64 opCode = block.OpCodes[opcIndex];
-
- context.CurrOp = opCode;
-
- bool isLastOp = opcIndex == block.OpCodes.Count - 1;
-
- if (isLastOp && block.Branch != null && block.Branch.Address <= block.Address)
- {
- context.EmitSynchronization();
- }
-
- ILLabel lblPredicateSkip = null;
-
- if (opCode is OpCode32 op && op.Cond < Condition.Al)
- {
- lblPredicateSkip = new ILLabel();
-
- context.EmitCondBranch(lblPredicateSkip, op.Cond.Invert());
- }
-
- opCode.Emitter(context);
-
- if (lblPredicateSkip != null)
- {
- context.MarkLabel(lblPredicateSkip);
-
- context.ResetBlockStateForPredicatedOp();
-
- // If this is the last op on the block, and there's no "next" block
- // after this one, then we have to return right now, with the address
- // of the next instruction to be executed (in the case that the condition
- // is false, and the branch was not taken, as all basic blocks should end
- // with some kind of branch).
- if (isLastOp && block.Next == null)
- {
- context.EmitStoreContext();
- context.EmitLdc_I8(opCode.Position + opCode.OpCodeSizeInBytes);
-
- context.Emit(OpCodes.Ret);
- }
- }
- }
- }
-
- return context.GetBlocks();
- }
-
- private static string GetSubroutineName(long position)
- {
- return $"Sub{position:x16}";
- }
-
- private static int GetOpsCount(BasicBlock[] blocks)
- {
- int opCount = 0;
-
- foreach (BasicBlock block in blocks)
- {
- opCount += block.Count;
- }
-
- return opCount;
- }
-
- private void ForceAheadOfTimeCompilation(TranslatedSub subroutine)
- {
- subroutine.Execute(_dummyThreadState, null);
- }
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/Translation/TranslatorCache.cs b/ChocolArm64/Translation/TranslatorCache.cs
deleted file mode 100644
index cf6510ad..00000000
--- a/ChocolArm64/Translation/TranslatorCache.cs
+++ /dev/null
@@ -1,196 +0,0 @@
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Threading;
-
-namespace ChocolArm64.Translation
-{
- class TranslatorCache
- {
- // Maximum size of the cache, the unit used is completely arbitrary.
- private const int MaxTotalSize = 0x800000;
-
- // Minimum time required in milliseconds for a method to be eligible for deletion.
- private const int MinTimeDelta = 2 * 60000;
-
- // Minimum number of calls required to update the timestamp.
- private const int MinCallCountForUpdate = 250;
-
- private class CacheBucket
- {
- public TranslatedSub Subroutine { get; private set; }
-
- public LinkedListNode<long> Node { get; private set; }
-
- public int CallCount { get; set; }
-
- public int Size { get; private set; }
-
- public long Timestamp { get; private set; }
-
- public CacheBucket(TranslatedSub subroutine, LinkedListNode<long> node, int size)
- {
- Subroutine = subroutine;
- Size = size;
-
- UpdateNode(node);
- }
-
- public void UpdateNode(LinkedListNode<long> node)
- {
- Node = node;
-
- Timestamp = GetTimestamp();
- }
- }
-
- private ConcurrentDictionary<long, CacheBucket> _cache;
-
- private LinkedList<long> _sortedCache;
-
- private int _totalSize;
-
- public TranslatorCache()
- {
- _cache = new ConcurrentDictionary<long, CacheBucket>();
-
- _sortedCache = new LinkedList<long>();
- }
-
- public TranslatedSub GetOrAdd(long position, TranslatedSub subroutine, int size)
- {
- ClearCacheIfNeeded();
-
- lock (_sortedCache)
- {
- LinkedListNode<long> node = _sortedCache.AddLast(position);
-
- CacheBucket bucket = new CacheBucket(subroutine, node, size);
-
- bucket = _cache.GetOrAdd(position, bucket);
-
- if (bucket.Node == node)
- {
- _totalSize += size;
- }
- else
- {
- _sortedCache.Remove(node);
- }
-
- return bucket.Subroutine;
- }
- }
-
- public void AddOrUpdate(long position, TranslatedSub subroutine, int size)
- {
- ClearCacheIfNeeded();
-
- lock (_sortedCache)
- {
- _totalSize += size;
-
- LinkedListNode<long> node = _sortedCache.AddLast(position);
-
- CacheBucket newBucket = new CacheBucket(subroutine, node, size);
-
- _cache.AddOrUpdate(position, newBucket, (key, bucket) =>
- {
- _totalSize -= bucket.Size;
-
- _sortedCache.Remove(bucket.Node);
-
- return newBucket;
- });
- }
- }
-
- public bool HasSubroutine(long position)
- {
- return _cache.ContainsKey(position);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public bool TryGetSubroutine(long position, out TranslatedSub subroutine)
- {
- if (_cache.TryGetValue(position, out CacheBucket bucket))
- {
- if (bucket.CallCount++ > MinCallCountForUpdate)
- {
- if (Monitor.TryEnter(_sortedCache))
- {
- try
- {
- // The bucket value on the dictionary may have changed between the
- // time we get the value from the dictionary, and we acquire the
- // lock. So we need to ensure we are working with the latest value,
- // we can do that by getting the value again, inside the lock.
- if (_cache.TryGetValue(position, out CacheBucket latestBucket))
- {
- latestBucket.CallCount = 0;
-
- _sortedCache.Remove(latestBucket.Node);
-
- latestBucket.UpdateNode(_sortedCache.AddLast(position));
- }
- }
- finally
- {
- Monitor.Exit(_sortedCache);
- }
- }
- }
-
- subroutine = bucket.Subroutine;
-
- return true;
- }
-
- subroutine = default(TranslatedSub);
-
- return false;
- }
-
- private void ClearCacheIfNeeded()
- {
- long timestamp = GetTimestamp();
-
- while (_totalSize > MaxTotalSize)
- {
- lock (_sortedCache)
- {
- LinkedListNode<long> node = _sortedCache.First;
-
- if (node == null)
- {
- break;
- }
-
- CacheBucket bucket = _cache[node.Value];
-
- long timeDelta = timestamp - bucket.Timestamp;
-
- if (timeDelta <= MinTimeDelta)
- {
- break;
- }
-
- if (_cache.TryRemove(node.Value, out bucket))
- {
- _totalSize -= bucket.Size;
-
- _sortedCache.Remove(bucket.Node);
- }
- }
- }
- }
-
- private static long GetTimestamp()
- {
- long timestamp = Stopwatch.GetTimestamp();
-
- return timestamp / (Stopwatch.Frequency / 1000);
- }
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/Translation/TranslatorQueue.cs b/ChocolArm64/Translation/TranslatorQueue.cs
deleted file mode 100644
index 0f1d8474..00000000
--- a/ChocolArm64/Translation/TranslatorQueue.cs
+++ /dev/null
@@ -1,77 +0,0 @@
-using ChocolArm64.State;
-using System.Collections.Concurrent;
-using System.Threading;
-
-namespace ChocolArm64.Translation
-{
- class TranslatorQueue
- {
- private ConcurrentStack<TranslatorQueueItem>[] _translationQueue;
-
- private ManualResetEvent _queueDataReceivedEvent;
-
- private bool _signaled;
-
- public TranslatorQueue()
- {
- _translationQueue = new ConcurrentStack<TranslatorQueueItem>[(int)TranslationTier.Count];
-
- for (int prio = 0; prio < _translationQueue.Length; prio++)
- {
- _translationQueue[prio] = new ConcurrentStack<TranslatorQueueItem>();
- }
-
- _queueDataReceivedEvent = new ManualResetEvent(false);
- }
-
- public void Enqueue(long position, ExecutionMode mode, TranslationTier tier, bool isComplete)
- {
- TranslatorQueueItem item = new TranslatorQueueItem(position, mode, tier, isComplete);
-
- ConcurrentStack<TranslatorQueueItem> queue = _translationQueue[(int)tier];
-
- queue.Push(item);
-
- _queueDataReceivedEvent.Set();
- }
-
- public bool TryDequeue(out TranslatorQueueItem item)
- {
- for (int prio = 0; prio < _translationQueue.Length; prio++)
- {
- if (_translationQueue[prio].TryPop(out item))
- {
- return true;
- }
- }
-
- item = default(TranslatorQueueItem);
-
- return false;
- }
-
- public void WaitForItems()
- {
- _queueDataReceivedEvent.WaitOne();
-
- lock (_queueDataReceivedEvent)
- {
- if (!_signaled)
- {
- _queueDataReceivedEvent.Reset();
- }
- }
- }
-
- public void ForceSignal()
- {
- lock (_queueDataReceivedEvent)
- {
- _signaled = true;
-
- _queueDataReceivedEvent.Set();
- _queueDataReceivedEvent.Close();
- }
- }
- }
-} \ No newline at end of file
diff --git a/ChocolArm64/Translation/TranslatorQueueItem.cs b/ChocolArm64/Translation/TranslatorQueueItem.cs
deleted file mode 100644
index dde2706d..00000000
--- a/ChocolArm64/Translation/TranslatorQueueItem.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using ChocolArm64.State;
-
-namespace ChocolArm64.Translation
-{
- struct TranslatorQueueItem
- {
- public long Position { get; }
-
- public ExecutionMode Mode { get; }
-
- public TranslationTier Tier { get; }
-
- public bool IsComplete { get; }
-
- public TranslatorQueueItem(
- long position,
- ExecutionMode mode,
- TranslationTier tier,
- bool isComplete = false)
- {
- Position = position;
- Mode = mode;
- Tier = tier;
- IsComplete = isComplete;
- }
- }
-} \ No newline at end of file