Start adding support for SIMD & FP types, along with some of the related ARM instructions
This commit is contained in:
parent
1d3e1d929e
commit
f056709136
52 changed files with 10972 additions and 466 deletions
|
@ -2,15 +2,21 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
{
|
||||
struct AllocationResult
|
||||
{
|
||||
public int UsedRegisters { get; }
|
||||
public int SpillRegionSize { get; }
|
||||
public int MaxCallArgs { get; }
|
||||
public int IntUsedRegisters { get; }
|
||||
public int VecUsedRegisters { get; }
|
||||
public int SpillRegionSize { get; }
|
||||
public int MaxCallArgs { get; }
|
||||
|
||||
public AllocationResult(int usedRegisters, int spillRegionSize, int maxCallArgs)
|
||||
public AllocationResult(
|
||||
int intUsedRegisters,
|
||||
int vecUsedRegisters,
|
||||
int spillRegionSize,
|
||||
int maxCallArgs)
|
||||
{
|
||||
UsedRegisters = usedRegisters;
|
||||
SpillRegionSize = spillRegionSize;
|
||||
MaxCallArgs = maxCallArgs;
|
||||
IntUsedRegisters = intUsedRegisters;
|
||||
VecUsedRegisters = vecUsedRegisters;
|
||||
SpillRegionSize = spillRegionSize;
|
||||
MaxCallArgs = maxCallArgs;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
using ARMeilleure.CodeGen.X86;
|
||||
using ARMeilleure.Common;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.State;
|
||||
using ARMeilleure.Translation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -40,7 +39,8 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
public BitMap Active { get; }
|
||||
public BitMap Inactive { get; }
|
||||
|
||||
public int UsedRegisters { get; set; }
|
||||
public int IntUsedRegisters { get; set; }
|
||||
public int VecUsedRegisters { get; set; }
|
||||
|
||||
public AllocationContext(RegisterMasks masks, int intervalsCount)
|
||||
{
|
||||
|
@ -102,7 +102,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
}
|
||||
}
|
||||
|
||||
for (int index = RegistersCount; index < _intervals.Count; index++)
|
||||
for (int index = RegistersCount * 2; index < _intervals.Count; index++)
|
||||
{
|
||||
if (!_intervals[index].IsSpilled)
|
||||
{
|
||||
|
@ -113,7 +113,11 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
InsertSplitCopies();
|
||||
InsertSplitCopiesAtEdges(cfg);
|
||||
|
||||
return new AllocationResult(context.UsedRegisters, context.StackAlloc.TotalSize, maxCallArgs);
|
||||
return new AllocationResult(
|
||||
context.IntUsedRegisters,
|
||||
context.VecUsedRegisters,
|
||||
context.StackAlloc.TotalSize,
|
||||
maxCallArgs);
|
||||
}
|
||||
|
||||
private void AllocateInterval(AllocationContext context, LiveInterval current, int cIndex)
|
||||
|
@ -148,23 +152,6 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
}
|
||||
}
|
||||
|
||||
int availableRegs = context.Masks.IntAvailableRegisters;
|
||||
|
||||
foreach (int iIndex in context.Active)
|
||||
{
|
||||
availableRegs &= ~(1 << GetInterval(iIndex).Register.Index);
|
||||
}
|
||||
|
||||
foreach (int iIndex in context.Inactive)
|
||||
{
|
||||
LiveInterval interval = GetInterval(iIndex);
|
||||
|
||||
if (interval.Overlaps(current))
|
||||
{
|
||||
availableRegs &= ~(1 << interval.Register.Index);
|
||||
}
|
||||
}
|
||||
|
||||
if (!TryAllocateRegWithoutSpill(context, current, cIndex))
|
||||
{
|
||||
AllocateRegWithSpill(context, current, cIndex);
|
||||
|
@ -173,11 +160,15 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
|
||||
private bool TryAllocateRegWithoutSpill(AllocationContext context, LiveInterval current, int cIndex)
|
||||
{
|
||||
RegisterType regType = current.Local.Type.ToRegisterType();
|
||||
|
||||
int availableRegisters = context.Masks.GetAvailableRegisters(regType);
|
||||
|
||||
int[] freePositions = new int[RegistersCount];
|
||||
|
||||
for (int index = 0; index < RegistersCount; index++)
|
||||
{
|
||||
if ((context.Masks.IntAvailableRegisters & (1 << index)) != 0)
|
||||
if ((availableRegisters & (1 << index)) != 0)
|
||||
{
|
||||
freePositions[index] = int.MaxValue;
|
||||
}
|
||||
|
@ -187,14 +178,17 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
{
|
||||
LiveInterval interval = GetInterval(iIndex);
|
||||
|
||||
freePositions[interval.Register.Index] = 0;
|
||||
if (interval.Register.Type == regType)
|
||||
{
|
||||
freePositions[interval.Register.Index] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (int iIndex in context.Inactive)
|
||||
{
|
||||
LiveInterval interval = GetInterval(iIndex);
|
||||
|
||||
if (interval.Overlaps(current))
|
||||
if (interval.Register.Type == regType && interval.Overlaps(current))
|
||||
{
|
||||
int nextOverlap = interval.NextOverlap(current);
|
||||
|
||||
|
@ -233,9 +227,16 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
}
|
||||
}
|
||||
|
||||
current.Register = new Register(selectedReg, RegisterType.Integer);
|
||||
current.Register = new Register(selectedReg, regType);
|
||||
|
||||
context.UsedRegisters |= 1 << selectedReg;
|
||||
if (regType == RegisterType.Integer)
|
||||
{
|
||||
context.IntUsedRegisters |= 1 << selectedReg;
|
||||
}
|
||||
else /* if (regType == RegisterType.Vector) */
|
||||
{
|
||||
context.VecUsedRegisters |= 1 << selectedReg;
|
||||
}
|
||||
|
||||
context.Active.Set(cIndex);
|
||||
|
||||
|
@ -244,13 +245,17 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
|
||||
private void AllocateRegWithSpill(AllocationContext context, LiveInterval current, int cIndex)
|
||||
{
|
||||
RegisterType regType = current.Local.Type.ToRegisterType();
|
||||
|
||||
int availableRegisters = context.Masks.GetAvailableRegisters(regType);
|
||||
|
||||
int[] usePositions = new int[RegistersCount];
|
||||
|
||||
int[] blockedPositions = new int[RegistersCount];
|
||||
|
||||
for (int index = 0; index < RegistersCount; index++)
|
||||
{
|
||||
if ((context.Masks.IntAvailableRegisters & (1 << index)) != 0)
|
||||
if ((availableRegisters & (1 << index)) != 0)
|
||||
{
|
||||
usePositions[index] = int.MaxValue;
|
||||
|
||||
|
@ -274,7 +279,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
{
|
||||
LiveInterval interval = GetInterval(iIndex);
|
||||
|
||||
if (!interval.IsFixed)
|
||||
if (!interval.IsFixed && interval.Register.Type == regType)
|
||||
{
|
||||
int nextUse = interval.NextUseAfter(current.Start);
|
||||
|
||||
|
@ -289,7 +294,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
{
|
||||
LiveInterval interval = GetInterval(iIndex);
|
||||
|
||||
if (!interval.IsFixed && interval.Overlaps(current))
|
||||
if (!interval.IsFixed && interval.Register.Type == regType && interval.Overlaps(current))
|
||||
{
|
||||
int nextUse = interval.NextUseAfter(current.Start);
|
||||
|
||||
|
@ -304,7 +309,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
{
|
||||
LiveInterval interval = GetInterval(iIndex);
|
||||
|
||||
if (interval.IsFixed)
|
||||
if (interval.IsFixed && interval.Register.Type == regType)
|
||||
{
|
||||
SetBlockedPosition(interval.Register.Index, 0);
|
||||
}
|
||||
|
@ -314,7 +319,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
{
|
||||
LiveInterval interval = GetInterval(iIndex);
|
||||
|
||||
if (interval.IsFixed && interval.Overlaps(current))
|
||||
if (interval.IsFixed && interval.Register.Type == regType && interval.Overlaps(current))
|
||||
{
|
||||
SetBlockedPosition(interval.Register.Index, interval.NextOverlap(current));
|
||||
}
|
||||
|
@ -344,7 +349,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
{
|
||||
//Spill made the register available for the entire current lifetime,
|
||||
//so we only need to split the intervals using the selected register.
|
||||
current.Register = new Register(selectedReg, RegisterType.Integer);
|
||||
current.Register = new Register(selectedReg, regType);
|
||||
|
||||
SplitAndSpillOverlappingIntervals(context, current);
|
||||
|
||||
|
@ -355,7 +360,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
//There are conflicts even after spill due to the use of fixed registers
|
||||
//that can't be spilled, so we need to also split current at the point of
|
||||
//the first fixed register use.
|
||||
current.Register = new Register(selectedReg, RegisterType.Integer);
|
||||
current.Register = new Register(selectedReg, regType);
|
||||
|
||||
LiveInterval splitChild = current.Split(GetSplitPosition(blockedPositions[selectedReg]));
|
||||
|
||||
|
@ -745,7 +750,10 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
throw new ArgumentException("Spilled intervals are not allowed.");
|
||||
}
|
||||
|
||||
return new Operand(interval.Register.Index, RegisterType.Integer, interval.Local.Type);
|
||||
return new Operand(
|
||||
interval.Register.Index,
|
||||
interval.Register.Type,
|
||||
interval.Local.Type);
|
||||
}
|
||||
|
||||
private static int GetSplitPosition(int position)
|
||||
|
@ -771,9 +779,8 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
|
||||
for (int index = 0; index < RegistersCount; index++)
|
||||
{
|
||||
LiveInterval interval = new LiveInterval(new Register(index, RegisterType.Integer));
|
||||
|
||||
_intervals.Add(interval);
|
||||
_intervals.Add(new LiveInterval(new Register(index, RegisterType.Integer)));
|
||||
_intervals.Add(new LiveInterval(new Register(index, RegisterType.Vector)));
|
||||
}
|
||||
|
||||
HashSet<Operand> visited = new HashSet<Operand>();
|
||||
|
@ -812,7 +819,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
|
||||
_blockRanges = new LiveRange[cfg.Blocks.Count];
|
||||
|
||||
int mapSize = _intervals.Count + RegistersCount;
|
||||
int mapSize = _intervals.Count;
|
||||
|
||||
BitMap[] blkLiveGen = new BitMap[cfg.Blocks.Count];
|
||||
BitMap[] blkLiveKill = new BitMap[cfg.Blocks.Count];
|
||||
|
@ -940,18 +947,8 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
|
||||
if (node is Operation operation && operation.Inst == Instruction.Call)
|
||||
{
|
||||
int callerSavedRegs = regMasks.IntCallerSavedRegisters;
|
||||
|
||||
while (callerSavedRegs != 0)
|
||||
{
|
||||
int callerSavedReg = BitUtils.LowestBitSet(callerSavedRegs);
|
||||
|
||||
LiveInterval interval = _intervals[callerSavedReg];
|
||||
|
||||
interval.AddRange(operationPos, operationPos + 1);
|
||||
|
||||
callerSavedRegs &= ~(1 << callerSavedReg);
|
||||
}
|
||||
AddIntervalCallerSavedReg(regMasks.IntCallerSavedRegisters, operationPos, RegisterType.Integer);
|
||||
AddIntervalCallerSavedReg(regMasks.VecCallerSavedRegisters, operationPos, RegisterType.Vector);
|
||||
|
||||
if (maxCallArgs < operation.SourcesCount - 1)
|
||||
{
|
||||
|
@ -962,6 +959,24 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
}
|
||||
}
|
||||
|
||||
private void AddIntervalCallerSavedReg(int mask, int operationPos, RegisterType regType)
|
||||
{
|
||||
while (mask != 0)
|
||||
{
|
||||
int regIndex = BitUtils.LowestBitSet(mask);
|
||||
|
||||
Debug.Assert(regIndex < RegistersCount, "Invalid register index.");
|
||||
|
||||
Register callerSavedReg = new Register(regIndex, regType);
|
||||
|
||||
LiveInterval interval = _intervals[GetRegisterId(callerSavedReg)];
|
||||
|
||||
interval.AddRange(operationPos, operationPos + 1);
|
||||
|
||||
mask &= ~(1 << regIndex);
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetOperandId(Operand operand)
|
||||
{
|
||||
if (operand.Kind == OperandKind.LocalVariable)
|
||||
|
@ -970,7 +985,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
}
|
||||
else if (operand.Kind == OperandKind.Register)
|
||||
{
|
||||
return operand.GetRegister().Index;
|
||||
return GetRegisterId(operand.GetRegister());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -978,6 +993,11 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
}
|
||||
}
|
||||
|
||||
private static int GetRegisterId(Register register)
|
||||
{
|
||||
return (register.Index << 1) | (register.Type == RegisterType.Vector ? 1 : 0);
|
||||
}
|
||||
|
||||
private void CoalesceCopies(BasicBlock[] blocks)
|
||||
{
|
||||
foreach (BasicBlock block in blocks)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.State;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
|
|
@ -1,19 +1,47 @@
|
|||
using ARMeilleure.IntermediateRepresentation;
|
||||
using System;
|
||||
|
||||
namespace ARMeilleure.CodeGen.RegisterAllocators
|
||||
{
|
||||
struct RegisterMasks
|
||||
{
|
||||
public int IntAvailableRegisters { get; }
|
||||
public int VecAvailableRegisters { get; }
|
||||
public int IntCallerSavedRegisters { get; }
|
||||
public int VecCallerSavedRegisters { get; }
|
||||
public int IntCalleeSavedRegisters { get; }
|
||||
public int VecCalleeSavedRegisters { get; }
|
||||
|
||||
public RegisterMasks(
|
||||
int intAvailableRegisters,
|
||||
int vecAvailableRegisters,
|
||||
int intCallerSavedRegisters,
|
||||
int intCalleeSavedRegisters)
|
||||
int vecCallerSavedRegisters,
|
||||
int intCalleeSavedRegisters,
|
||||
int vecCalleeSavedRegisters)
|
||||
{
|
||||
IntAvailableRegisters = intAvailableRegisters;
|
||||
VecAvailableRegisters = vecAvailableRegisters;
|
||||
IntCallerSavedRegisters = intCallerSavedRegisters;
|
||||
VecCallerSavedRegisters = vecCallerSavedRegisters;
|
||||
IntCalleeSavedRegisters = intCalleeSavedRegisters;
|
||||
VecCalleeSavedRegisters = vecCalleeSavedRegisters;
|
||||
}
|
||||
|
||||
public int GetAvailableRegisters(RegisterType type)
|
||||
{
|
||||
if (type == RegisterType.Integer)
|
||||
{
|
||||
return IntAvailableRegisters;
|
||||
}
|
||||
else if (type == RegisterType.Vector)
|
||||
{
|
||||
return VecAvailableRegisters;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException($"Invalid register type \"{type}\".");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -4,9 +4,11 @@ namespace ARMeilleure.CodeGen.X86
|
|||
{
|
||||
static class CallingConvention
|
||||
{
|
||||
private const int RegistersMask = 0xffff;
|
||||
|
||||
public static int GetIntAvailableRegisters()
|
||||
{
|
||||
int mask = 0xffff;
|
||||
int mask = RegistersMask;
|
||||
|
||||
mask &= ~(1 << (int)X86Register.Rbp);
|
||||
mask &= ~(1 << (int)X86Register.Rsp);
|
||||
|
@ -14,6 +16,11 @@ namespace ARMeilleure.CodeGen.X86
|
|||
return mask;
|
||||
}
|
||||
|
||||
public static int GetVecAvailableRegisters()
|
||||
{
|
||||
return RegistersMask;
|
||||
}
|
||||
|
||||
public static int GetIntCallerSavedRegisters()
|
||||
{
|
||||
return (1 << (int)X86Register.Rax) |
|
||||
|
@ -25,6 +32,16 @@ namespace ARMeilleure.CodeGen.X86
|
|||
(1 << (int)X86Register.R11);
|
||||
}
|
||||
|
||||
public static int GetVecCallerSavedRegisters()
|
||||
{
|
||||
return (1 << (int)X86Register.Xmm0) |
|
||||
(1 << (int)X86Register.Xmm1) |
|
||||
(1 << (int)X86Register.Xmm2) |
|
||||
(1 << (int)X86Register.Xmm3) |
|
||||
(1 << (int)X86Register.Xmm4) |
|
||||
(1 << (int)X86Register.Xmm5);
|
||||
}
|
||||
|
||||
public static int GetIntCalleeSavedRegisters()
|
||||
{
|
||||
return (1 << (int)X86Register.Rbx) |
|
||||
|
@ -38,7 +55,12 @@ namespace ARMeilleure.CodeGen.X86
|
|||
(1 << (int)X86Register.R15);
|
||||
}
|
||||
|
||||
public static int GetIntArgumentsOnRegsCount()
|
||||
public static int GetVecCalleeSavedRegisters()
|
||||
{
|
||||
return GetVecCallerSavedRegisters() ^ RegistersMask;
|
||||
}
|
||||
|
||||
public static int GetArgumentsOnRegsCount()
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
@ -56,9 +78,27 @@ namespace ARMeilleure.CodeGen.X86
|
|||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
|
||||
public static X86Register GetVecArgumentRegister(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return X86Register.Xmm0;
|
||||
case 1: return X86Register.Xmm1;
|
||||
case 2: return X86Register.Xmm2;
|
||||
case 3: return X86Register.Xmm3;
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
|
||||
public static X86Register GetIntReturnRegister()
|
||||
{
|
||||
return X86Register.Rax;
|
||||
}
|
||||
|
||||
public static X86Register GetVecReturnRegister()
|
||||
{
|
||||
return X86Register.Xmm0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -87,7 +87,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||
{
|
||||
//We need to add 8 bytes to the total size, as the call to this
|
||||
//function already pushed 8 bytes (the return address).
|
||||
int mask = CallingConvention.GetIntCalleeSavedRegisters() & allocResult.UsedRegisters;
|
||||
int mask = CallingConvention.GetIntCalleeSavedRegisters() & allocResult.IntUsedRegisters;
|
||||
|
||||
mask |= 1 << (int)X86Register.Rbp;
|
||||
|
||||
|
@ -97,7 +97,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||
|
||||
//The ABI mandates that the space for at least 4 arguments
|
||||
//is reserved on the stack (this is called shadow space).
|
||||
if (argsCount < 4)
|
||||
if (argsCount < 4 && argsCount != 0)
|
||||
{
|
||||
argsCount = 4;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
7
ARMeilleure/CodeGen/X86/HardwareCapabilities.cs
Normal file
7
ARMeilleure/CodeGen/X86/HardwareCapabilities.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
static class HardwareCapabilities
|
||||
{
|
||||
public const bool SupportsVexEncoding = true;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
using ARMeilleure.CodeGen.Optimizations;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.Memory;
|
||||
using ARMeilleure.State;
|
||||
using ARMeilleure.Translation;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
@ -118,51 +117,93 @@ namespace ARMeilleure.CodeGen.X86
|
|||
|
||||
private static void AddConstantCopy(LinkedListNode<Node> node, Operation operation)
|
||||
{
|
||||
if (operation.SourcesCount == 0)
|
||||
if (operation.SourcesCount == 0 || HasFixedConst(operation.Inst))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Instruction inst = operation.Inst;
|
||||
|
||||
Operand dest = operation.Dest;
|
||||
Operand src1 = operation.GetSource(0);
|
||||
Operand src2;
|
||||
|
||||
if (src1.Kind == OperandKind.Constant && !HasConstSrc1(inst))
|
||||
if (src1.Type.IsInteger())
|
||||
{
|
||||
if (IsComutative(inst))
|
||||
//Handle integer types.
|
||||
//Most ALU instructions accepts a 32-bits immediate on the second operand.
|
||||
//We need to ensure the following:
|
||||
//- If the constant is on operand 1, we need to move it.
|
||||
//-- But first, we try to swap operand 1 and 2 if the instruction is comutative.
|
||||
//-- Doing so may allow us to encode the constant as operand 2 and avoid a copy.
|
||||
//- If the constant is on operand 2, we check if the instruction supports it,
|
||||
//if not, we also add a copy. 64-bits constants are usually not supported.
|
||||
bool isVecCopy = inst == Instruction.Copy && !dest.Type.IsInteger();
|
||||
|
||||
if (src1.Kind == OperandKind.Constant && (!HasConstSrc1(inst) || isVecCopy))
|
||||
{
|
||||
src2 = operation.GetSource(1);
|
||||
if (IsComutative(inst))
|
||||
{
|
||||
src2 = operation.GetSource(1);
|
||||
|
||||
Operand temp = src1;
|
||||
Operand temp = src1;
|
||||
|
||||
src1 = src2;
|
||||
src2 = temp;
|
||||
src1 = src2;
|
||||
src2 = temp;
|
||||
|
||||
operation.SetSource(0, src1);
|
||||
operation.SetSource(1, src2);
|
||||
}
|
||||
|
||||
if (src1.Kind == OperandKind.Constant)
|
||||
{
|
||||
src1 = AddCopy(node, src1);
|
||||
|
||||
operation.SetSource(0, src1);
|
||||
}
|
||||
}
|
||||
|
||||
if (operation.SourcesCount < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
src2 = operation.GetSource(1);
|
||||
|
||||
if (src2.Kind == OperandKind.Constant && (!HasConstSrc2(inst) || IsLongConst(src2)))
|
||||
{
|
||||
src2 = AddCopy(node, src2);
|
||||
|
||||
operation.SetSource(0, src1);
|
||||
operation.SetSource(1, src2);
|
||||
}
|
||||
|
||||
if (src1.Kind == OperandKind.Constant)
|
||||
}
|
||||
else
|
||||
{
|
||||
//Handle non-integer types (FP32, FP64 and V128).
|
||||
//For instructions without an immediate operand, we do the following:
|
||||
//- Insert a copy with the constant value (as integer) to a GPR.
|
||||
//- Insert a copy from the GPR to a XMM register.
|
||||
//- Replace the constant use with the XMM register.
|
||||
if (src1.Kind == OperandKind.Constant && src1.Type.IsInteger())
|
||||
{
|
||||
src1 = AddCopy(node, src1);
|
||||
src1 = AddXmmCopy(node, src1);
|
||||
|
||||
operation.SetSource(0, src1);
|
||||
}
|
||||
}
|
||||
|
||||
if (operation.SourcesCount < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (operation.SourcesCount < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
src2 = operation.GetSource(1);
|
||||
src2 = operation.GetSource(1);
|
||||
|
||||
if (src2.Kind == OperandKind.Constant && (!HasConstSrc2(inst) || IsLongConst(src2)))
|
||||
{
|
||||
src2 = AddCopy(node, src2);
|
||||
if (src2.Kind == OperandKind.Constant && src2.Type.IsInteger())
|
||||
{
|
||||
src2 = AddXmmCopy(node, src2);
|
||||
|
||||
operation.SetSource(1, src2);
|
||||
operation.SetSource(1, src2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -248,7 +289,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||
{
|
||||
int argsCount = operation.SourcesCount;
|
||||
|
||||
int maxArgs = CallingConvention.GetIntArgumentsOnRegsCount();
|
||||
int maxArgs = CallingConvention.GetArgumentsOnRegsCount();
|
||||
|
||||
if (argsCount > maxArgs + 1)
|
||||
{
|
||||
|
@ -259,7 +300,18 @@ namespace ARMeilleure.CodeGen.X86
|
|||
{
|
||||
Operand source = operation.GetSource(index);
|
||||
|
||||
Operand argReg = Gpr(CallingConvention.GetIntArgumentRegister(index - 1), source.Type);
|
||||
RegisterType regType = source.Type.ToRegisterType();
|
||||
|
||||
Operand argReg;
|
||||
|
||||
if (regType == RegisterType.Integer)
|
||||
{
|
||||
argReg = Gpr(CallingConvention.GetIntArgumentRegister(index - 1), source.Type);
|
||||
}
|
||||
else /* if (regType == RegisterType.Vector) */
|
||||
{
|
||||
argReg = Xmm(CallingConvention.GetVecArgumentRegister(index - 1), source.Type);
|
||||
}
|
||||
|
||||
Operation srcCopyOp = new Operation(Instruction.Copy, argReg, source);
|
||||
|
||||
|
@ -285,7 +337,18 @@ namespace ARMeilleure.CodeGen.X86
|
|||
|
||||
if (dest != null)
|
||||
{
|
||||
Operand retReg = Gpr(CallingConvention.GetIntReturnRegister(), dest.Type);
|
||||
RegisterType regType = dest.Type.ToRegisterType();
|
||||
|
||||
Operand retReg;
|
||||
|
||||
if (regType == RegisterType.Integer)
|
||||
{
|
||||
retReg = Gpr(CallingConvention.GetIntReturnRegister(), dest.Type);
|
||||
}
|
||||
else /* if (regType == RegisterType.Vector) */
|
||||
{
|
||||
retReg = Xmm(CallingConvention.GetVecReturnRegister(), dest.Type);
|
||||
}
|
||||
|
||||
Operation destCopyOp = new Operation(Instruction.Copy, dest, retReg);
|
||||
|
||||
|
@ -312,7 +375,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||
//a three operand form where the second source is a immediate value.
|
||||
bool threeOperandForm = inst == Instruction.Multiply && operation.GetSource(1).Kind == OperandKind.Constant;
|
||||
|
||||
if (IsSameOperandDestSrc1(inst) && src1.Kind == OperandKind.LocalVariable && !threeOperandForm)
|
||||
if (IsSameOperandDestSrc1(operation) && src1.Kind == OperandKind.LocalVariable && !threeOperandForm)
|
||||
{
|
||||
Operation copyOp = new Operation(Instruction.Copy, dest, src1);
|
||||
|
||||
|
@ -332,6 +395,17 @@ namespace ARMeilleure.CodeGen.X86
|
|||
}
|
||||
}
|
||||
|
||||
private static Operand AddXmmCopy(LinkedListNode<Node> node, Operand source)
|
||||
{
|
||||
Operand temp = Local(source.Type);
|
||||
|
||||
Operation copyOp = new Operation(Instruction.Copy, temp, AddCopy(node, GetIntConst(source)));
|
||||
|
||||
node.List.AddBefore(node, copyOp);
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
private static Operand AddCopy(LinkedListNode<Node> node, Operand source)
|
||||
{
|
||||
Operand temp = Local(source.Type);
|
||||
|
@ -343,6 +417,20 @@ namespace ARMeilleure.CodeGen.X86
|
|||
return temp;
|
||||
}
|
||||
|
||||
private static Operand GetIntConst(Operand value)
|
||||
{
|
||||
if (value.Type == OperandType.FP32)
|
||||
{
|
||||
return Const(value.AsInt32());
|
||||
}
|
||||
else if (value.Type == OperandType.FP64)
|
||||
{
|
||||
return Const(value.AsInt64());
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private static bool IsLongConst(Operand operand)
|
||||
{
|
||||
long value = operand.Type == OperandType.I32 ? operand.AsInt32()
|
||||
|
@ -405,9 +493,14 @@ namespace ARMeilleure.CodeGen.X86
|
|||
return Register((int)register, RegisterType.Integer, type);
|
||||
}
|
||||
|
||||
private static bool IsSameOperandDestSrc1(Instruction inst)
|
||||
private static Operand Xmm(X86Register register, OperandType type)
|
||||
{
|
||||
switch (inst)
|
||||
return Register((int)register, RegisterType.Vector, type);
|
||||
}
|
||||
|
||||
private static bool IsSameOperandDestSrc1(Operation operation)
|
||||
{
|
||||
switch (operation.Inst)
|
||||
{
|
||||
case Instruction.Add:
|
||||
case Instruction.BitwiseAnd:
|
||||
|
@ -423,6 +516,23 @@ namespace ARMeilleure.CodeGen.X86
|
|||
case Instruction.ShiftRightUI:
|
||||
case Instruction.Subtract:
|
||||
return true;
|
||||
|
||||
case Instruction.VectorInsert:
|
||||
case Instruction.VectorInsert16:
|
||||
case Instruction.VectorInsert8:
|
||||
return !HardwareCapabilities.SupportsVexEncoding;
|
||||
}
|
||||
|
||||
return IsVexSameOperandDestSrc1(operation);
|
||||
}
|
||||
|
||||
private static bool IsVexSameOperandDestSrc1(Operation operation)
|
||||
{
|
||||
if (IsIntrinsic(operation.Inst))
|
||||
{
|
||||
bool isUnary = operation.SourcesCount < 2;
|
||||
|
||||
return !HardwareCapabilities.SupportsVexEncoding && !isUnary;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -464,6 +574,9 @@ namespace ARMeilleure.CodeGen.X86
|
|||
case Instruction.ShiftRightSI:
|
||||
case Instruction.ShiftRightUI:
|
||||
case Instruction.Subtract:
|
||||
case Instruction.VectorExtract:
|
||||
case Instruction.VectorExtract16:
|
||||
case Instruction.VectorExtract8:
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -486,5 +599,29 @@ namespace ARMeilleure.CodeGen.X86
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool HasFixedConst(Instruction inst)
|
||||
{
|
||||
switch (inst)
|
||||
{
|
||||
case Instruction.LoadFromContext:
|
||||
case Instruction.StoreToContext:
|
||||
case Instruction.VectorExtract:
|
||||
case Instruction.VectorExtract16:
|
||||
case Instruction.VectorExtract8:
|
||||
case Instruction.VectorInsert:
|
||||
case Instruction.VectorInsert16:
|
||||
case Instruction.VectorInsert8:
|
||||
return true;
|
||||
}
|
||||
|
||||
return IsIntrinsic(inst);
|
||||
}
|
||||
|
||||
private static bool IsIntrinsic(Instruction inst)
|
||||
{
|
||||
return inst > Instruction.X86Intrinsic_Start &&
|
||||
inst < Instruction.X86Intrinsic_End;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,38 +3,152 @@ namespace ARMeilleure.CodeGen.X86
|
|||
enum X86Instruction
|
||||
{
|
||||
Add,
|
||||
Addpd,
|
||||
Addps,
|
||||
Addsd,
|
||||
Addss,
|
||||
And,
|
||||
Andnpd,
|
||||
Andnps,
|
||||
Bsr,
|
||||
Bswap,
|
||||
Call,
|
||||
Cmovcc,
|
||||
Cmp,
|
||||
Div,
|
||||
Divpd,
|
||||
Divps,
|
||||
Divsd,
|
||||
Divss,
|
||||
Haddpd,
|
||||
Haddps,
|
||||
Idiv,
|
||||
Imul,
|
||||
Imul128,
|
||||
Insertps,
|
||||
Maxpd,
|
||||
Maxps,
|
||||
Maxsd,
|
||||
Maxss,
|
||||
Minpd,
|
||||
Minps,
|
||||
Minsd,
|
||||
Minss,
|
||||
Mov,
|
||||
Mov16,
|
||||
Mov8,
|
||||
Movd,
|
||||
Movdqu,
|
||||
Movhlps,
|
||||
Movlhps,
|
||||
Movq,
|
||||
Movsd,
|
||||
Movss,
|
||||
Movsx16,
|
||||
Movsx32,
|
||||
Movsx8,
|
||||
Movzx16,
|
||||
Movzx8,
|
||||
Mul128,
|
||||
Mulpd,
|
||||
Mulps,
|
||||
Mulsd,
|
||||
Mulss,
|
||||
Neg,
|
||||
Not,
|
||||
Or,
|
||||
Paddb,
|
||||
Paddd,
|
||||
Paddq,
|
||||
Paddw,
|
||||
Pand,
|
||||
Pandn,
|
||||
Pavgb,
|
||||
Pavgw,
|
||||
Pblendvb,
|
||||
Pcmpeqb,
|
||||
Pcmpeqd,
|
||||
Pcmpeqq,
|
||||
Pcmpeqw,
|
||||
Pcmpgtb,
|
||||
Pcmpgtd,
|
||||
Pcmpgtq,
|
||||
Pcmpgtw,
|
||||
Pextrb,
|
||||
Pextrd,
|
||||
Pextrw,
|
||||
Pinsrb,
|
||||
Pinsrd,
|
||||
Pinsrw,
|
||||
Pmaxsb,
|
||||
Pmaxsd,
|
||||
Pmaxsw,
|
||||
Pmaxub,
|
||||
Pmaxud,
|
||||
Pmaxuw,
|
||||
Pminsb,
|
||||
Pminsd,
|
||||
Pminsw,
|
||||
Pminub,
|
||||
Pminud,
|
||||
Pminuw,
|
||||
Pmovsxbw,
|
||||
Pmovsxdq,
|
||||
Pmovsxwd,
|
||||
Pmovzxbw,
|
||||
Pmovzxdq,
|
||||
Pmovzxwd,
|
||||
Pmulld,
|
||||
Pmullw,
|
||||
Pop,
|
||||
Popcnt,
|
||||
Por,
|
||||
Pshufd,
|
||||
Psllw,
|
||||
Psrad,
|
||||
Psraw,
|
||||
Psrld,
|
||||
Psrlq,
|
||||
Psrldq,
|
||||
Psrlw,
|
||||
Psubb,
|
||||
Psubd,
|
||||
Psubq,
|
||||
Psubw,
|
||||
Push,
|
||||
Pxor,
|
||||
Rcpps,
|
||||
Rcpss,
|
||||
Ror,
|
||||
Roundpd,
|
||||
Roundps,
|
||||
Roundsd,
|
||||
Roundss,
|
||||
Rsqrtps,
|
||||
Rsqrtss,
|
||||
Sar,
|
||||
Setcc,
|
||||
Shl,
|
||||
Shr,
|
||||
Shufpd,
|
||||
Shufps,
|
||||
Sqrtpd,
|
||||
Sqrtps,
|
||||
Sqrtsd,
|
||||
Sqrtss,
|
||||
Sub,
|
||||
Subpd,
|
||||
Subps,
|
||||
Subsd,
|
||||
Subss,
|
||||
Test,
|
||||
Unpckhpd,
|
||||
Unpckhps,
|
||||
Unpcklpd,
|
||||
Unpcklps,
|
||||
Xor,
|
||||
Xorpd,
|
||||
Xorps,
|
||||
|
||||
Count
|
||||
}
|
||||
|
|
|
@ -17,6 +17,23 @@ namespace ARMeilleure.CodeGen.X86
|
|||
R12 = 12,
|
||||
R13 = 13,
|
||||
R14 = 14,
|
||||
R15 = 15
|
||||
R15 = 15,
|
||||
|
||||
Xmm0 = 0,
|
||||
Xmm1 = 1,
|
||||
Xmm2 = 2,
|
||||
Xmm3 = 3,
|
||||
Xmm4 = 4,
|
||||
Xmm5 = 5,
|
||||
Xmm6 = 6,
|
||||
Xmm7 = 7,
|
||||
Xmm8 = 8,
|
||||
Xmm9 = 9,
|
||||
Xmm10 = 10,
|
||||
Xmm11 = 11,
|
||||
Xmm12 = 12,
|
||||
Xmm13 = 13,
|
||||
Xmm14 = 14,
|
||||
Xmm15 = 15
|
||||
}
|
||||
}
|
|
@ -24,6 +24,9 @@ namespace ARMeilleure.Decoders
|
|||
RegisterSize = RegisterSize.Int64;
|
||||
}
|
||||
|
||||
public int GetPairsCount() => GetBitsCount() / 16;
|
||||
public int GetBytesCount() => GetBitsCount() / 8;
|
||||
|
||||
public int GetBitsCount()
|
||||
{
|
||||
switch (RegisterSize)
|
||||
|
|
|
@ -2,9 +2,9 @@ namespace ARMeilleure.Decoders
|
|||
{
|
||||
class OpCodeSimdFmov : OpCode, IOpCodeSimd
|
||||
{
|
||||
public int Rd { get; private set; }
|
||||
public long Imm { get; private set; }
|
||||
public int Size { get; private set; }
|
||||
public int Rd { get; private set; }
|
||||
public long Immediate { get; private set; }
|
||||
public int Size { get; private set; }
|
||||
|
||||
public OpCodeSimdFmov(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
|
@ -25,7 +25,7 @@ namespace ARMeilleure.Decoders
|
|||
Rd = (opCode >> 0) & 0x1f;
|
||||
imm = (opCode >> 13) & 0xff;
|
||||
|
||||
Imm = DecoderHelper.DecodeImm8Float(imm, type);
|
||||
Immediate = DecoderHelper.DecodeImm8Float(imm, type);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,9 +2,9 @@ namespace ARMeilleure.Decoders
|
|||
{
|
||||
class OpCodeSimdImm : OpCode, IOpCodeSimd
|
||||
{
|
||||
public int Rd { get; private set; }
|
||||
public long Imm { get; private set; }
|
||||
public int Size { get; private set; }
|
||||
public int Rd { get; private set; }
|
||||
public long Immediate { get; private set; }
|
||||
public int Size { get; private set; }
|
||||
|
||||
public OpCodeSimdImm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
|
@ -76,7 +76,7 @@ namespace ARMeilleure.Decoders
|
|||
Size = 0;
|
||||
}
|
||||
|
||||
Imm = imm;
|
||||
Immediate = imm;
|
||||
|
||||
RegisterSize = ((opCode >> 30) & 1) != 0
|
||||
? RegisterSize.Simd128
|
||||
|
|
|
@ -190,27 +190,27 @@ namespace ARMeilleure.Decoders
|
|||
SetA64("10011011110xxxxx0xxxxxxxxxxxxxxx", InstName.Umulh, InstEmit.Umulh, typeof(OpCodeMul));
|
||||
|
||||
//FP & SIMD
|
||||
SetA64("0101111011100000101110xxxxxxxxxx", InstName.Abs_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>001110<<100000101110xxxxxxxxxx", InstName.Abs_V, null, typeof(OpCodeSimd));
|
||||
SetA64("01011110111xxxxx100001xxxxxxxxxx", InstName.Add_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>001110<<1xxxxx100001xxxxxxxxxx", InstName.Add_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx010000xxxxxxxxxx", InstName.Addhn_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0101111011110001101110xxxxxxxxxx", InstName.Addp_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>001110<<1xxxxx101111xxxxxxxxxx", InstName.Addp_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("000011100x110001101110xxxxxxxxxx", InstName.Addv_V, null, typeof(OpCodeSimd));
|
||||
SetA64("01001110<<110001101110xxxxxxxxxx", InstName.Addv_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0100111000101000010110xxxxxxxxxx", InstName.Aesd_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0100111000101000010010xxxxxxxxxx", InstName.Aese_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0100111000101000011110xxxxxxxxxx", InstName.Aesimc_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0100111000101000011010xxxxxxxxxx", InstName.Aesmc_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0101111011100000101110xxxxxxxxxx", InstName.Abs_S, InstEmit.Abs_S, typeof(OpCodeSimd));
|
||||
SetA64("0>001110<<100000101110xxxxxxxxxx", InstName.Abs_V, InstEmit.Abs_V, typeof(OpCodeSimd));
|
||||
SetA64("01011110111xxxxx100001xxxxxxxxxx", InstName.Add_S, InstEmit.Add_S, typeof(OpCodeSimdReg));
|
||||
SetA64("0>001110<<1xxxxx100001xxxxxxxxxx", InstName.Add_V, InstEmit.Add_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx010000xxxxxxxxxx", InstName.Addhn_V, InstEmit.Addhn_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0101111011110001101110xxxxxxxxxx", InstName.Addp_S, InstEmit.Addp_S, typeof(OpCodeSimd));
|
||||
SetA64("0>001110<<1xxxxx101111xxxxxxxxxx", InstName.Addp_V, InstEmit.Addp_V, typeof(OpCodeSimdReg));
|
||||
SetA64("000011100x110001101110xxxxxxxxxx", InstName.Addv_V, InstEmit.Addv_V, typeof(OpCodeSimd));
|
||||
SetA64("01001110<<110001101110xxxxxxxxxx", InstName.Addv_V, InstEmit.Addv_V, typeof(OpCodeSimd));
|
||||
SetA64("0100111000101000010110xxxxxxxxxx", InstName.Aesd_V, InstEmit.Aesd_V, typeof(OpCodeSimd));
|
||||
SetA64("0100111000101000010010xxxxxxxxxx", InstName.Aese_V, InstEmit.Aese_V, typeof(OpCodeSimd));
|
||||
SetA64("0100111000101000011110xxxxxxxxxx", InstName.Aesimc_V, InstEmit.Aesimc_V, typeof(OpCodeSimd));
|
||||
SetA64("0100111000101000011010xxxxxxxxxx", InstName.Aesmc_V, InstEmit.Aesmc_V, typeof(OpCodeSimd));
|
||||
SetA64("0x001110001xxxxx000111xxxxxxxxxx", InstName.And_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110011xxxxx000111xxxxxxxxxx", InstName.Bic_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x10111100000xxx<<x101xxxxxxxxxx", InstName.Bic_Vi, null, typeof(OpCodeSimdImm));
|
||||
SetA64("0x101110111xxxxx000111xxxxxxxxxx", InstName.Bif_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110101xxxxx000111xxxxxxxxxx", InstName.Bit_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110011xxxxx000111xxxxxxxxxx", InstName.Bsl_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<100000010010xxxxxxxxxx", InstName.Cls_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0x101110<<100000010010xxxxxxxxxx", InstName.Clz_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0x001110<<100000010010xxxxxxxxxx", InstName.Cls_V, InstEmit.Cls_V, typeof(OpCodeSimd));
|
||||
SetA64("0x101110<<100000010010xxxxxxxxxx", InstName.Clz_V, InstEmit.Clz_V, typeof(OpCodeSimd));
|
||||
SetA64("01111110111xxxxx100011xxxxxxxxxx", InstName.Cmeq_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0101111011100000100110xxxxxxxxxx", InstName.Cmeq_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>101110<<1xxxxx100011xxxxxxxxxx", InstName.Cmeq_V, null, typeof(OpCodeSimdReg));
|
||||
|
@ -233,20 +233,20 @@ namespace ARMeilleure.Decoders
|
|||
SetA64("0>001110<<100000101010xxxxxxxxxx", InstName.Cmlt_V, null, typeof(OpCodeSimd));
|
||||
SetA64("01011110111xxxxx100011xxxxxxxxxx", InstName.Cmtst_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>001110<<1xxxxx100011xxxxxxxxxx", InstName.Cmtst_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x00111000100000010110xxxxxxxxxx", InstName.Cnt_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0x00111000100000010110xxxxxxxxxx", InstName.Cnt_V, InstEmit.Cnt_V, typeof(OpCodeSimd));
|
||||
SetA64("0>001110000x<>>>000011xxxxxxxxxx", InstName.Dup_Gp, null, typeof(OpCodeSimdIns));
|
||||
SetA64("01011110000xxxxx000001xxxxxxxxxx", InstName.Dup_S, null, typeof(OpCodeSimdIns));
|
||||
SetA64("0>001110000x<>>>000001xxxxxxxxxx", InstName.Dup_V, null, typeof(OpCodeSimdIns));
|
||||
SetA64("0x101110001xxxxx000111xxxxxxxxxx", InstName.Eor_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>101110000xxxxx0<xxx0xxxxxxxxxx", InstName.Ext_V, null, typeof(OpCodeSimdExt));
|
||||
SetA64("011111101x1xxxxx110101xxxxxxxxxx", InstName.Fabd_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>1011101<1xxxxx110101xxxxxxxxxx", InstName.Fabd_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("000111100x100000110000xxxxxxxxxx", InstName.Fabs_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>0011101<100000111110xxxxxxxxxx", InstName.Fabs_V, null, typeof(OpCodeSimd));
|
||||
SetA64("000111100x1xxxxx001010xxxxxxxxxx", InstName.Fadd_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011100<1xxxxx110101xxxxxxxxxx", InstName.Fadd_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("011111100x110000110110xxxxxxxxxx", InstName.Faddp_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>1011100<1xxxxx110101xxxxxxxxxx", InstName.Faddp_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("011111101x1xxxxx110101xxxxxxxxxx", InstName.Fabd_S, InstEmit.Fabd_S, typeof(OpCodeSimdReg));
|
||||
SetA64("0>1011101<1xxxxx110101xxxxxxxxxx", InstName.Fabd_V, InstEmit.Fabd_V, typeof(OpCodeSimdReg));
|
||||
SetA64("000111100x100000110000xxxxxxxxxx", InstName.Fabs_S, InstEmit.Fabs_S, typeof(OpCodeSimd));
|
||||
SetA64("0>0011101<100000111110xxxxxxxxxx", InstName.Fabs_V, InstEmit.Fabs_V, typeof(OpCodeSimd));
|
||||
SetA64("000111100x1xxxxx001010xxxxxxxxxx", InstName.Fadd_S, InstEmit.Fadd_S, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011100<1xxxxx110101xxxxxxxxxx", InstName.Fadd_V, InstEmit.Fadd_V, typeof(OpCodeSimdReg));
|
||||
SetA64("011111100x110000110110xxxxxxxxxx", InstName.Faddp_S, InstEmit.Faddp_S, typeof(OpCodeSimd));
|
||||
SetA64("0>1011100<1xxxxx110101xxxxxxxxxx", InstName.Faddp_V, InstEmit.Faddp_V, typeof(OpCodeSimdReg));
|
||||
SetA64("000111100x1xxxxxxxxx01xxxxx0xxxx", InstName.Fccmp_S, null, typeof(OpCodeSimdFcond));
|
||||
SetA64("000111100x1xxxxxxxxx01xxxxx1xxxx", InstName.Fccmpe_S, null, typeof(OpCodeSimdFcond));
|
||||
SetA64("010111100x1xxxxx111001xxxxxxxxxx", InstName.Fcmeq_S, null, typeof(OpCodeSimdReg));
|
||||
|
@ -293,73 +293,73 @@ namespace ARMeilleure.Decoders
|
|||
SetA64("0>1011101<100001101110xxxxxxxxxx", InstName.Fcvtzu_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0x101111001xxxxx111111xxxxxxxxxx", InstName.Fcvtzu_V_Fixed, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0110111101xxxxxx111111xxxxxxxxxx", InstName.Fcvtzu_V_Fixed, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("000111100x1xxxxx000110xxxxxxxxxx", InstName.Fdiv_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>1011100<1xxxxx111111xxxxxxxxxx", InstName.Fdiv_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("000111110x0xxxxx0xxxxxxxxxxxxxxx", InstName.Fmadd_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("000111100x1xxxxx010010xxxxxxxxxx", InstName.Fmax_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011100<1xxxxx111101xxxxxxxxxx", InstName.Fmax_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("000111100x1xxxxx011010xxxxxxxxxx", InstName.Fmaxnm_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011100<1xxxxx110001xxxxxxxxxx", InstName.Fmaxnm_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>1011100<1xxxxx111101xxxxxxxxxx", InstName.Fmaxp_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("000111100x1xxxxx010110xxxxxxxxxx", InstName.Fmin_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011101<1xxxxx111101xxxxxxxxxx", InstName.Fmin_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("000111100x1xxxxx011110xxxxxxxxxx", InstName.Fminnm_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011101<1xxxxx110001xxxxxxxxxx", InstName.Fminnm_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>1011101<1xxxxx111101xxxxxxxxxx", InstName.Fminp_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("010111111xxxxxxx0001x0xxxxxxxxxx", InstName.Fmla_Se, null, typeof(OpCodeSimdRegElemF));
|
||||
SetA64("0>0011100<1xxxxx110011xxxxxxxxxx", InstName.Fmla_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011111<xxxxxx0001x0xxxxxxxxxx", InstName.Fmla_Ve, null, typeof(OpCodeSimdRegElemF));
|
||||
SetA64("010111111xxxxxxx0101x0xxxxxxxxxx", InstName.Fmls_Se, null, typeof(OpCodeSimdRegElemF));
|
||||
SetA64("0>0011101<1xxxxx110011xxxxxxxxxx", InstName.Fmls_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011111<xxxxxx0101x0xxxxxxxxxx", InstName.Fmls_Ve, null, typeof(OpCodeSimdRegElemF));
|
||||
SetA64("000111100x1xxxxx000110xxxxxxxxxx", InstName.Fdiv_S, InstEmit.Fdiv_S, typeof(OpCodeSimdReg));
|
||||
SetA64("0>1011100<1xxxxx111111xxxxxxxxxx", InstName.Fdiv_V, InstEmit.Fdiv_V, typeof(OpCodeSimdReg));
|
||||
SetA64("000111110x0xxxxx0xxxxxxxxxxxxxxx", InstName.Fmadd_S, InstEmit.Fmadd_S, typeof(OpCodeSimdReg));
|
||||
SetA64("000111100x1xxxxx010010xxxxxxxxxx", InstName.Fmax_S, InstEmit.Fmax_S, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011100<1xxxxx111101xxxxxxxxxx", InstName.Fmax_V, InstEmit.Fmax_V, typeof(OpCodeSimdReg));
|
||||
SetA64("000111100x1xxxxx011010xxxxxxxxxx", InstName.Fmaxnm_S, InstEmit.Fmaxnm_S, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011100<1xxxxx110001xxxxxxxxxx", InstName.Fmaxnm_V, InstEmit.Fmaxnm_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0>1011100<1xxxxx111101xxxxxxxxxx", InstName.Fmaxp_V, InstEmit.Fmaxp_V, typeof(OpCodeSimdReg));
|
||||
SetA64("000111100x1xxxxx010110xxxxxxxxxx", InstName.Fmin_S, InstEmit.Fmin_S, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011101<1xxxxx111101xxxxxxxxxx", InstName.Fmin_V, InstEmit.Fmin_V, typeof(OpCodeSimdReg));
|
||||
SetA64("000111100x1xxxxx011110xxxxxxxxxx", InstName.Fminnm_S, InstEmit.Fminnm_S, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011101<1xxxxx110001xxxxxxxxxx", InstName.Fminnm_V, InstEmit.Fminnm_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0>1011101<1xxxxx111101xxxxxxxxxx", InstName.Fminp_V, InstEmit.Fminp_V, typeof(OpCodeSimdReg));
|
||||
SetA64("010111111xxxxxxx0001x0xxxxxxxxxx", InstName.Fmla_Se, InstEmit.Fmla_Se, typeof(OpCodeSimdRegElemF));
|
||||
SetA64("0>0011100<1xxxxx110011xxxxxxxxxx", InstName.Fmla_V, InstEmit.Fmla_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011111<xxxxxx0001x0xxxxxxxxxx", InstName.Fmla_Ve, InstEmit.Fmla_Ve, typeof(OpCodeSimdRegElemF));
|
||||
SetA64("010111111xxxxxxx0101x0xxxxxxxxxx", InstName.Fmls_Se, InstEmit.Fmls_Se, typeof(OpCodeSimdRegElemF));
|
||||
SetA64("0>0011101<1xxxxx110011xxxxxxxxxx", InstName.Fmls_V, InstEmit.Fmls_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011111<xxxxxx0101x0xxxxxxxxxx", InstName.Fmls_Ve, InstEmit.Fmls_Ve, typeof(OpCodeSimdRegElemF));
|
||||
SetA64("000111100x100000010000xxxxxxxxxx", InstName.Fmov_S, null, typeof(OpCodeSimd));
|
||||
SetA64("00011110xx1xxxxxxxx100xxxxxxxxxx", InstName.Fmov_Si, null, typeof(OpCodeSimdFmov));
|
||||
SetA64("00011110xx1xxxxxxxx100xxxxxxxxxx", InstName.Fmov_Si, InstEmit.Fmov_Si, typeof(OpCodeSimdFmov));
|
||||
SetA64("0xx0111100000xxx111101xxxxxxxxxx", InstName.Fmov_V, null, typeof(OpCodeSimdImm));
|
||||
SetA64("x00111100x100110000000xxxxxxxxxx", InstName.Fmov_Ftoi, null, typeof(OpCodeSimdCvt));
|
||||
SetA64("x00111100x100111000000xxxxxxxxxx", InstName.Fmov_Itof, null, typeof(OpCodeSimdCvt));
|
||||
SetA64("1001111010101110000000xxxxxxxxxx", InstName.Fmov_Ftoi1, null, typeof(OpCodeSimdCvt));
|
||||
SetA64("1001111010101111000000xxxxxxxxxx", InstName.Fmov_Itof1, null, typeof(OpCodeSimdCvt));
|
||||
SetA64("000111110x0xxxxx1xxxxxxxxxxxxxxx", InstName.Fmsub_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("000111100x1xxxxx000010xxxxxxxxxx", InstName.Fmul_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("010111111xxxxxxx1001x0xxxxxxxxxx", InstName.Fmul_Se, null, typeof(OpCodeSimdRegElemF));
|
||||
SetA64("0>1011100<1xxxxx110111xxxxxxxxxx", InstName.Fmul_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011111<xxxxxx1001x0xxxxxxxxxx", InstName.Fmul_Ve, null, typeof(OpCodeSimdRegElemF));
|
||||
SetA64("010111100x1xxxxx110111xxxxxxxxxx", InstName.Fmulx_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("011111111xxxxxxx1001x0xxxxxxxxxx", InstName.Fmulx_Se, null, typeof(OpCodeSimdRegElemF));
|
||||
SetA64("0>0011100<1xxxxx110111xxxxxxxxxx", InstName.Fmulx_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>1011111<xxxxxx1001x0xxxxxxxxxx", InstName.Fmulx_Ve, null, typeof(OpCodeSimdRegElemF));
|
||||
SetA64("000111100x100001010000xxxxxxxxxx", InstName.Fneg_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>1011101<100000111110xxxxxxxxxx", InstName.Fneg_V, null, typeof(OpCodeSimd));
|
||||
SetA64("000111110x1xxxxx0xxxxxxxxxxxxxxx", InstName.Fnmadd_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("000111110x1xxxxx1xxxxxxxxxxxxxxx", InstName.Fnmsub_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("000111100x1xxxxx100010xxxxxxxxxx", InstName.Fnmul_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("010111101x100001110110xxxxxxxxxx", InstName.Frecpe_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>0011101<100001110110xxxxxxxxxx", InstName.Frecpe_V, null, typeof(OpCodeSimd));
|
||||
SetA64("010111100x1xxxxx111111xxxxxxxxxx", InstName.Frecps_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011100<1xxxxx111111xxxxxxxxxx", InstName.Frecps_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("010111101x100001111110xxxxxxxxxx", InstName.Frecpx_S, null, typeof(OpCodeSimd));
|
||||
SetA64("000111100x100110010000xxxxxxxxxx", InstName.Frinta_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>1011100<100001100010xxxxxxxxxx", InstName.Frinta_V, null, typeof(OpCodeSimd));
|
||||
SetA64("000111100x100111110000xxxxxxxxxx", InstName.Frinti_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>1011101<100001100110xxxxxxxxxx", InstName.Frinti_V, null, typeof(OpCodeSimd));
|
||||
SetA64("000111100x100101010000xxxxxxxxxx", InstName.Frintm_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>0011100<100001100110xxxxxxxxxx", InstName.Frintm_V, null, typeof(OpCodeSimd));
|
||||
SetA64("000111100x100100010000xxxxxxxxxx", InstName.Frintn_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>0011100<100001100010xxxxxxxxxx", InstName.Frintn_V, null, typeof(OpCodeSimd));
|
||||
SetA64("000111100x100100110000xxxxxxxxxx", InstName.Frintp_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>0011101<100001100010xxxxxxxxxx", InstName.Frintp_V, null, typeof(OpCodeSimd));
|
||||
SetA64("000111100x100111010000xxxxxxxxxx", InstName.Frintx_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>1011100<100001100110xxxxxxxxxx", InstName.Frintx_V, null, typeof(OpCodeSimd));
|
||||
SetA64("000111100x100101110000xxxxxxxxxx", InstName.Frintz_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>0011101<100001100110xxxxxxxxxx", InstName.Frintz_V, null, typeof(OpCodeSimd));
|
||||
SetA64("011111101x100001110110xxxxxxxxxx", InstName.Frsqrte_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>1011101<100001110110xxxxxxxxxx", InstName.Frsqrte_V, null, typeof(OpCodeSimd));
|
||||
SetA64("010111101x1xxxxx111111xxxxxxxxxx", InstName.Frsqrts_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011101<1xxxxx111111xxxxxxxxxx", InstName.Frsqrts_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("000111100x100001110000xxxxxxxxxx", InstName.Fsqrt_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>1011101<100001111110xxxxxxxxxx", InstName.Fsqrt_V, null, typeof(OpCodeSimd));
|
||||
SetA64("000111100x1xxxxx001110xxxxxxxxxx", InstName.Fsub_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011101<1xxxxx110101xxxxxxxxxx", InstName.Fsub_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("000111110x0xxxxx1xxxxxxxxxxxxxxx", InstName.Fmsub_S, InstEmit.Fmsub_S, typeof(OpCodeSimdReg));
|
||||
SetA64("000111100x1xxxxx000010xxxxxxxxxx", InstName.Fmul_S, InstEmit.Fmul_S, typeof(OpCodeSimdReg));
|
||||
SetA64("010111111xxxxxxx1001x0xxxxxxxxxx", InstName.Fmul_Se, InstEmit.Fmul_Se, typeof(OpCodeSimdRegElemF));
|
||||
SetA64("0>1011100<1xxxxx110111xxxxxxxxxx", InstName.Fmul_V, InstEmit.Fmul_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011111<xxxxxx1001x0xxxxxxxxxx", InstName.Fmul_Ve, InstEmit.Fmul_Ve, typeof(OpCodeSimdRegElemF));
|
||||
SetA64("010111100x1xxxxx110111xxxxxxxxxx", InstName.Fmulx_S, InstEmit.Fmulx_S, typeof(OpCodeSimdReg));
|
||||
SetA64("011111111xxxxxxx1001x0xxxxxxxxxx", InstName.Fmulx_Se, InstEmit.Fmulx_Se, typeof(OpCodeSimdRegElemF));
|
||||
SetA64("0>0011100<1xxxxx110111xxxxxxxxxx", InstName.Fmulx_V, InstEmit.Fmulx_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0>1011111<xxxxxx1001x0xxxxxxxxxx", InstName.Fmulx_Ve, InstEmit.Fmulx_Ve, typeof(OpCodeSimdRegElemF));
|
||||
SetA64("000111100x100001010000xxxxxxxxxx", InstName.Fneg_S, InstEmit.Fneg_S, typeof(OpCodeSimd));
|
||||
SetA64("0>1011101<100000111110xxxxxxxxxx", InstName.Fneg_V, InstEmit.Fneg_V, typeof(OpCodeSimd));
|
||||
SetA64("000111110x1xxxxx0xxxxxxxxxxxxxxx", InstName.Fnmadd_S, InstEmit.Fnmadd_S, typeof(OpCodeSimdReg));
|
||||
SetA64("000111110x1xxxxx1xxxxxxxxxxxxxxx", InstName.Fnmsub_S, InstEmit.Fnmsub_S, typeof(OpCodeSimdReg));
|
||||
SetA64("000111100x1xxxxx100010xxxxxxxxxx", InstName.Fnmul_S, InstEmit.Fnmul_S, typeof(OpCodeSimdReg));
|
||||
SetA64("010111101x100001110110xxxxxxxxxx", InstName.Frecpe_S, InstEmit.Frecpe_S, typeof(OpCodeSimd));
|
||||
SetA64("0>0011101<100001110110xxxxxxxxxx", InstName.Frecpe_V, InstEmit.Frecpe_V, typeof(OpCodeSimd));
|
||||
SetA64("010111100x1xxxxx111111xxxxxxxxxx", InstName.Frecps_S, InstEmit.Frecps_S, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011100<1xxxxx111111xxxxxxxxxx", InstName.Frecps_V, InstEmit.Frecps_V, typeof(OpCodeSimdReg));
|
||||
SetA64("010111101x100001111110xxxxxxxxxx", InstName.Frecpx_S, InstEmit.Frecpx_S, typeof(OpCodeSimd));
|
||||
SetA64("000111100x100110010000xxxxxxxxxx", InstName.Frinta_S, InstEmit.Frinta_S, typeof(OpCodeSimd));
|
||||
SetA64("0>1011100<100001100010xxxxxxxxxx", InstName.Frinta_V, InstEmit.Frinta_V, typeof(OpCodeSimd));
|
||||
SetA64("000111100x100111110000xxxxxxxxxx", InstName.Frinti_S, InstEmit.Frinti_S, typeof(OpCodeSimd));
|
||||
SetA64("0>1011101<100001100110xxxxxxxxxx", InstName.Frinti_V, InstEmit.Frinti_V, typeof(OpCodeSimd));
|
||||
SetA64("000111100x100101010000xxxxxxxxxx", InstName.Frintm_S, InstEmit.Frintm_S, typeof(OpCodeSimd));
|
||||
SetA64("0>0011100<100001100110xxxxxxxxxx", InstName.Frintm_V, InstEmit.Frintm_V, typeof(OpCodeSimd));
|
||||
SetA64("000111100x100100010000xxxxxxxxxx", InstName.Frintn_S, InstEmit.Frintn_S, typeof(OpCodeSimd));
|
||||
SetA64("0>0011100<100001100010xxxxxxxxxx", InstName.Frintn_V, InstEmit.Frintn_V, typeof(OpCodeSimd));
|
||||
SetA64("000111100x100100110000xxxxxxxxxx", InstName.Frintp_S, InstEmit.Frintp_S, typeof(OpCodeSimd));
|
||||
SetA64("0>0011101<100001100010xxxxxxxxxx", InstName.Frintp_V, InstEmit.Frintp_V, typeof(OpCodeSimd));
|
||||
SetA64("000111100x100111010000xxxxxxxxxx", InstName.Frintx_S, InstEmit.Frintx_S, typeof(OpCodeSimd));
|
||||
SetA64("0>1011100<100001100110xxxxxxxxxx", InstName.Frintx_V, InstEmit.Frintx_V, typeof(OpCodeSimd));
|
||||
SetA64("000111100x100101110000xxxxxxxxxx", InstName.Frintz_S, InstEmit.Frintz_S, typeof(OpCodeSimd));
|
||||
SetA64("0>0011101<100001100110xxxxxxxxxx", InstName.Frintz_V, InstEmit.Frintz_V, typeof(OpCodeSimd));
|
||||
SetA64("011111101x100001110110xxxxxxxxxx", InstName.Frsqrte_S, InstEmit.Frsqrte_S, typeof(OpCodeSimd));
|
||||
SetA64("0>1011101<100001110110xxxxxxxxxx", InstName.Frsqrte_V, InstEmit.Frsqrte_V, typeof(OpCodeSimd));
|
||||
SetA64("010111101x1xxxxx111111xxxxxxxxxx", InstName.Frsqrts_S, InstEmit.Frsqrts_S, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011101<1xxxxx111111xxxxxxxxxx", InstName.Frsqrts_V, InstEmit.Frsqrts_V, typeof(OpCodeSimdReg));
|
||||
SetA64("000111100x100001110000xxxxxxxxxx", InstName.Fsqrt_S, InstEmit.Fsqrt_S, typeof(OpCodeSimd));
|
||||
SetA64("0>1011101<100001111110xxxxxxxxxx", InstName.Fsqrt_V, InstEmit.Fsqrt_V, typeof(OpCodeSimd));
|
||||
SetA64("000111100x1xxxxx001110xxxxxxxxxx", InstName.Fsub_S, InstEmit.Fsub_S, typeof(OpCodeSimdReg));
|
||||
SetA64("0>0011101<1xxxxx110101xxxxxxxxxx", InstName.Fsub_V, InstEmit.Fsub_V, typeof(OpCodeSimdReg));
|
||||
SetA64("01001110000xxxxx000111xxxxxxxxxx", InstName.Ins_Gp, null, typeof(OpCodeSimdIns));
|
||||
SetA64("01101110000xxxxx0xxxx1xxxxxxxxxx", InstName.Ins_V, null, typeof(OpCodeSimdIns));
|
||||
SetA64("0x00110001000000xxxxxxxxxxxxxxxx", InstName.Ld__Vms, null, typeof(OpCodeSimdMemMs));
|
||||
|
@ -373,40 +373,40 @@ namespace ARMeilleure.Decoders
|
|||
SetA64("xx111101x1xxxxxxxxxxxxxxxxxxxxxx", InstName.Ldr, null, typeof(OpCodeSimdMemImm));
|
||||
SetA64("xx111100x11xxxxxxxxx10xxxxxxxxxx", InstName.Ldr, null, typeof(OpCodeSimdMemReg));
|
||||
SetA64("xx011100xxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ldr_Literal, null, typeof(OpCodeSimdMemLit));
|
||||
SetA64("0x001110<<1xxxxx100101xxxxxxxxxx", InstName.Mla_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101111xxxxxxxx0000x0xxxxxxxxxx", InstName.Mla_Ve, null, typeof(OpCodeSimdRegElem));
|
||||
SetA64("0x101110<<1xxxxx100101xxxxxxxxxx", InstName.Mls_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101111xxxxxxxx0100x0xxxxxxxxxx", InstName.Mls_Ve, null, typeof(OpCodeSimdRegElem));
|
||||
SetA64("0x001110<<1xxxxx100101xxxxxxxxxx", InstName.Mla_V, InstEmit.Mla_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101111xxxxxxxx0000x0xxxxxxxxxx", InstName.Mla_Ve, InstEmit.Mla_Ve, typeof(OpCodeSimdRegElem));
|
||||
SetA64("0x101110<<1xxxxx100101xxxxxxxxxx", InstName.Mls_V, InstEmit.Mls_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101111xxxxxxxx0100x0xxxxxxxxxx", InstName.Mls_Ve, InstEmit.Mls_Ve, typeof(OpCodeSimdRegElem));
|
||||
SetA64("0x00111100000xxx0xx001xxxxxxxxxx", InstName.Movi_V, null, typeof(OpCodeSimdImm));
|
||||
SetA64("0x00111100000xxx10x001xxxxxxxxxx", InstName.Movi_V, null, typeof(OpCodeSimdImm));
|
||||
SetA64("0x00111100000xxx110x01xxxxxxxxxx", InstName.Movi_V, null, typeof(OpCodeSimdImm));
|
||||
SetA64("0xx0111100000xxx111001xxxxxxxxxx", InstName.Movi_V, null, typeof(OpCodeSimdImm));
|
||||
SetA64("0x001110<<1xxxxx100111xxxxxxxxxx", InstName.Mul_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001111xxxxxxxx1000x0xxxxxxxxxx", InstName.Mul_Ve, null, typeof(OpCodeSimdRegElem));
|
||||
SetA64("0x001110<<1xxxxx100111xxxxxxxxxx", InstName.Mul_V, InstEmit.Mul_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001111xxxxxxxx1000x0xxxxxxxxxx", InstName.Mul_Ve, InstEmit.Mul_Ve, typeof(OpCodeSimdRegElem));
|
||||
SetA64("0x10111100000xxx0xx001xxxxxxxxxx", InstName.Mvni_V, null, typeof(OpCodeSimdImm));
|
||||
SetA64("0x10111100000xxx10x001xxxxxxxxxx", InstName.Mvni_V, null, typeof(OpCodeSimdImm));
|
||||
SetA64("0x10111100000xxx110x01xxxxxxxxxx", InstName.Mvni_V, null, typeof(OpCodeSimdImm));
|
||||
SetA64("0111111011100000101110xxxxxxxxxx", InstName.Neg_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>101110<<100000101110xxxxxxxxxx", InstName.Neg_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0111111011100000101110xxxxxxxxxx", InstName.Neg_S, InstEmit.Neg_S, typeof(OpCodeSimd));
|
||||
SetA64("0>101110<<100000101110xxxxxxxxxx", InstName.Neg_V, InstEmit.Neg_V, typeof(OpCodeSimd));
|
||||
SetA64("0x10111000100000010110xxxxxxxxxx", InstName.Not_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0x001110111xxxxx000111xxxxxxxxxx", InstName.Orn_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110101xxxxx000111xxxxxxxxxx", InstName.Orr_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x00111100000xxx<<x101xxxxxxxxxx", InstName.Orr_Vi, null, typeof(OpCodeSimdImm));
|
||||
SetA64("0x101110<<1xxxxx010000xxxxxxxxxx", InstName.Raddhn_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx010000xxxxxxxxxx", InstName.Raddhn_V, InstEmit.Raddhn_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x10111001100000010110xxxxxxxxxx", InstName.Rbit_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0x00111000100000000110xxxxxxxxxx", InstName.Rev16_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0x1011100x100000000010xxxxxxxxxx", InstName.Rev32_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0x001110<<100000000010xxxxxxxxxx", InstName.Rev64_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0x00111100>>>xxx100011xxxxxxxxxx", InstName.Rshrn_V, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0x101110<<1xxxxx011000xxxxxxxxxx", InstName.Rsubhn_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx011111xxxxxxxxxx", InstName.Saba_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx010100xxxxxxxxxx", InstName.Sabal_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx011101xxxxxxxxxx", InstName.Sabd_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx011100xxxxxxxxxx", InstName.Sabdl_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<100000011010xxxxxxxxxx", InstName.Sadalp_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0x001110<<1xxxxx000000xxxxxxxxxx", InstName.Saddl_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<100000001010xxxxxxxxxx", InstName.Saddlp_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0x001110<<1xxxxx000100xxxxxxxxxx", InstName.Saddw_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx011000xxxxxxxxxx", InstName.Rsubhn_V, InstEmit.Rsubhn_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx011111xxxxxxxxxx", InstName.Saba_V, InstEmit.Saba_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx010100xxxxxxxxxx", InstName.Sabal_V, InstEmit.Sabal_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx011101xxxxxxxxxx", InstName.Sabd_V, InstEmit.Sabd_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx011100xxxxxxxxxx", InstName.Sabdl_V, InstEmit.Sabdl_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<100000011010xxxxxxxxxx", InstName.Sadalp_V, InstEmit.Sadalp_V, typeof(OpCodeSimd));
|
||||
SetA64("0x001110<<1xxxxx000000xxxxxxxxxx", InstName.Saddl_V, InstEmit.Saddl_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<100000001010xxxxxxxxxx", InstName.Saddlp_V, InstEmit.Saddlp_V, typeof(OpCodeSimd));
|
||||
SetA64("0x001110<<1xxxxx000100xxxxxxxxxx", InstName.Saddw_V, InstEmit.Saddw_V, typeof(OpCodeSimdReg));
|
||||
SetA64("x00111100x100010000000xxxxxxxxxx", InstName.Scvtf_Gp, null, typeof(OpCodeSimdCvt));
|
||||
SetA64(">00111100x000010>xxxxxxxxxxxxxxx", InstName.Scvtf_Gp_Fixed, null, typeof(OpCodeSimdCvt));
|
||||
SetA64("010111100x100001110110xxxxxxxxxx", InstName.Scvtf_S, null, typeof(OpCodeSimd));
|
||||
|
@ -421,39 +421,43 @@ namespace ARMeilleure.Decoders
|
|||
SetA64("01011110000xxxxx010100xxxxxxxxxx", InstName.Sha256h2_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0101111000101000001010xxxxxxxxxx", InstName.Sha256su0_V, null, typeof(OpCodeSimd));
|
||||
SetA64("01011110000xxxxx011000xxxxxxxxxx", InstName.Sha256su1_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx000001xxxxxxxxxx", InstName.Shadd_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx000001xxxxxxxxxx", InstName.Shadd_V, InstEmit.Shadd_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0101111101xxxxxx010101xxxxxxxxxx", InstName.Shl_S, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0x00111100>>>xxx010101xxxxxxxxxx", InstName.Shl_V, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0100111101xxxxxx010101xxxxxxxxxx", InstName.Shl_V, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0x101110<<100001001110xxxxxxxxxx", InstName.Shll_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0x00111100>>>xxx100001xxxxxxxxxx", InstName.Shrn_V, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0x001110<<1xxxxx001001xxxxxxxxxx", InstName.Shsub_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx001001xxxxxxxxxx", InstName.Shsub_V, InstEmit.Shsub_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x1011110>>>>xxx010101xxxxxxxxxx", InstName.Sli_V, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0x001110<<1xxxxx011001xxxxxxxxxx", InstName.Smax_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx101001xxxxxxxxxx", InstName.Smaxp_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx011011xxxxxxxxxx", InstName.Smin_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx101011xxxxxxxxxx", InstName.Sminp_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx100000xxxxxxxxxx", InstName.Smlal_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001111xxxxxxxx0010x0xxxxxxxxxx", InstName.Smlal_Ve, null, typeof(OpCodeSimdRegElem));
|
||||
SetA64("0x001110<<1xxxxx101000xxxxxxxxxx", InstName.Smlsl_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001111xxxxxxxx0110x0xxxxxxxxxx", InstName.Smlsl_Ve, null, typeof(OpCodeSimdRegElem));
|
||||
SetA64("0x001110<<1xxxxx011001xxxxxxxxxx", InstName.Smax_V, InstEmit.Smax_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx101001xxxxxxxxxx", InstName.Smaxp_V, InstEmit.Smaxp_V, typeof(OpCodeSimdReg));
|
||||
SetA64("000011100x110000101010xxxxxxxxxx", InstName.Smaxv_V, InstEmit.Smaxv_V, typeof(OpCodeSimd));
|
||||
SetA64("01001110<<110000101010xxxxxxxxxx", InstName.Smaxv_V, InstEmit.Smaxv_V, typeof(OpCodeSimd));
|
||||
SetA64("0x001110<<1xxxxx011011xxxxxxxxxx", InstName.Smin_V, InstEmit.Smin_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx101011xxxxxxxxxx", InstName.Sminp_V, InstEmit.Sminp_V, typeof(OpCodeSimdReg));
|
||||
SetA64("000011100x110001101010xxxxxxxxxx", InstName.Sminv_V, InstEmit.Sminv_V, typeof(OpCodeSimd));
|
||||
SetA64("01001110<<110001101010xxxxxxxxxx", InstName.Sminv_V, InstEmit.Sminv_V, typeof(OpCodeSimd));
|
||||
SetA64("0x001110<<1xxxxx100000xxxxxxxxxx", InstName.Smlal_V, InstEmit.Smlal_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001111xxxxxxxx0010x0xxxxxxxxxx", InstName.Smlal_Ve, InstEmit.Smlal_Ve, typeof(OpCodeSimdRegElem));
|
||||
SetA64("0x001110<<1xxxxx101000xxxxxxxxxx", InstName.Smlsl_V, InstEmit.Smlsl_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001111xxxxxxxx0110x0xxxxxxxxxx", InstName.Smlsl_Ve, InstEmit.Smlsl_Ve, typeof(OpCodeSimdRegElem));
|
||||
SetA64("0x001110000xxxxx001011xxxxxxxxxx", InstName.Smov_S, null, typeof(OpCodeSimdIns));
|
||||
SetA64("0x001110<<1xxxxx110000xxxxxxxxxx", InstName.Smull_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001111xxxxxxxx1010x0xxxxxxxxxx", InstName.Smull_Ve, null, typeof(OpCodeSimdRegElem));
|
||||
SetA64("01011110xx100000011110xxxxxxxxxx", InstName.Sqabs_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>001110<<100000011110xxxxxxxxxx", InstName.Sqabs_V, null, typeof(OpCodeSimd));
|
||||
SetA64("01011110xx1xxxxx000011xxxxxxxxxx", InstName.Sqadd_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>001110<<1xxxxx000011xxxxxxxxxx", InstName.Sqadd_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("01011110011xxxxx101101xxxxxxxxxx", InstName.Sqdmulh_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("01011110101xxxxx101101xxxxxxxxxx", InstName.Sqdmulh_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110011xxxxx101101xxxxxxxxxx", InstName.Sqdmulh_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110101xxxxx101101xxxxxxxxxx", InstName.Sqdmulh_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("01111110xx100000011110xxxxxxxxxx", InstName.Sqneg_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>101110<<100000011110xxxxxxxxxx", InstName.Sqneg_V, null, typeof(OpCodeSimd));
|
||||
SetA64("01111110011xxxxx101101xxxxxxxxxx", InstName.Sqrdmulh_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("01111110101xxxxx101101xxxxxxxxxx", InstName.Sqrdmulh_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110011xxxxx101101xxxxxxxxxx", InstName.Sqrdmulh_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110101xxxxx101101xxxxxxxxxx", InstName.Sqrdmulh_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx110000xxxxxxxxxx", InstName.Smull_V, InstEmit.Smull_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001111xxxxxxxx1010x0xxxxxxxxxx", InstName.Smull_Ve, InstEmit.Smull_Ve, typeof(OpCodeSimdRegElem));
|
||||
SetA64("01011110xx100000011110xxxxxxxxxx", InstName.Sqabs_S, InstEmit.Sqabs_S, typeof(OpCodeSimd));
|
||||
SetA64("0>001110<<100000011110xxxxxxxxxx", InstName.Sqabs_V, InstEmit.Sqabs_V, typeof(OpCodeSimd));
|
||||
SetA64("01011110xx1xxxxx000011xxxxxxxxxx", InstName.Sqadd_S, InstEmit.Sqadd_S, typeof(OpCodeSimdReg));
|
||||
SetA64("0>001110<<1xxxxx000011xxxxxxxxxx", InstName.Sqadd_V, InstEmit.Sqadd_V, typeof(OpCodeSimdReg));
|
||||
SetA64("01011110011xxxxx101101xxxxxxxxxx", InstName.Sqdmulh_S, InstEmit.Sqdmulh_S, typeof(OpCodeSimdReg));
|
||||
SetA64("01011110101xxxxx101101xxxxxxxxxx", InstName.Sqdmulh_S, InstEmit.Sqdmulh_S, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110011xxxxx101101xxxxxxxxxx", InstName.Sqdmulh_V, InstEmit.Sqdmulh_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110101xxxxx101101xxxxxxxxxx", InstName.Sqdmulh_V, InstEmit.Sqdmulh_V, typeof(OpCodeSimdReg));
|
||||
SetA64("01111110xx100000011110xxxxxxxxxx", InstName.Sqneg_S, InstEmit.Sqneg_S, typeof(OpCodeSimd));
|
||||
SetA64("0>101110<<100000011110xxxxxxxxxx", InstName.Sqneg_V, InstEmit.Sqneg_V, typeof(OpCodeSimd));
|
||||
SetA64("01111110011xxxxx101101xxxxxxxxxx", InstName.Sqrdmulh_S, InstEmit.Sqrdmulh_S, typeof(OpCodeSimdReg));
|
||||
SetA64("01111110101xxxxx101101xxxxxxxxxx", InstName.Sqrdmulh_S, InstEmit.Sqrdmulh_S, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110011xxxxx101101xxxxxxxxxx", InstName.Sqrdmulh_V, InstEmit.Sqrdmulh_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110101xxxxx101101xxxxxxxxxx", InstName.Sqrdmulh_V, InstEmit.Sqrdmulh_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0>001110<<1xxxxx010111xxxxxxxxxx", InstName.Sqrshl_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0101111100>>>xxx100111xxxxxxxxxx", InstName.Sqrshrn_S, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0x00111100>>>xxx100111xxxxxxxxxx", InstName.Sqrshrn_V, null, typeof(OpCodeSimdShImm));
|
||||
|
@ -464,13 +468,13 @@ namespace ARMeilleure.Decoders
|
|||
SetA64("0x00111100>>>xxx100101xxxxxxxxxx", InstName.Sqshrn_V, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0111111100>>>xxx100001xxxxxxxxxx", InstName.Sqshrun_S, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0x10111100>>>xxx100001xxxxxxxxxx", InstName.Sqshrun_V, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("01011110xx1xxxxx001011xxxxxxxxxx", InstName.Sqsub_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>001110<<1xxxxx001011xxxxxxxxxx", InstName.Sqsub_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("01011110<<100001010010xxxxxxxxxx", InstName.Sqxtn_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0x001110<<100001010010xxxxxxxxxx", InstName.Sqxtn_V, null, typeof(OpCodeSimd));
|
||||
SetA64("01111110<<100001001010xxxxxxxxxx", InstName.Sqxtun_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0x101110<<100001001010xxxxxxxxxx", InstName.Sqxtun_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0x001110<<1xxxxx000101xxxxxxxxxx", InstName.Srhadd_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("01011110xx1xxxxx001011xxxxxxxxxx", InstName.Sqsub_S, InstEmit.Sqsub_S, typeof(OpCodeSimdReg));
|
||||
SetA64("0>001110<<1xxxxx001011xxxxxxxxxx", InstName.Sqsub_V, InstEmit.Sqsub_V, typeof(OpCodeSimdReg));
|
||||
SetA64("01011110<<100001010010xxxxxxxxxx", InstName.Sqxtn_S, InstEmit.Sqxtn_S, typeof(OpCodeSimd));
|
||||
SetA64("0x001110<<100001010010xxxxxxxxxx", InstName.Sqxtn_V, InstEmit.Sqxtn_V, typeof(OpCodeSimd));
|
||||
SetA64("01111110<<100001001010xxxxxxxxxx", InstName.Sqxtun_S, InstEmit.Sqxtun_S, typeof(OpCodeSimd));
|
||||
SetA64("0x101110<<100001001010xxxxxxxxxx", InstName.Sqxtun_V, InstEmit.Sqxtun_V, typeof(OpCodeSimd));
|
||||
SetA64("0x001110<<1xxxxx000101xxxxxxxxxx", InstName.Srhadd_V, InstEmit.Srhadd_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0>001110<<1xxxxx010101xxxxxxxxxx", InstName.Srshl_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0101111101xxxxxx001001xxxxxxxxxx", InstName.Srshr_S, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0x00111100>>>xxx001001xxxxxxxxxx", InstName.Srshr_V, null, typeof(OpCodeSimdShImm));
|
||||
|
@ -486,8 +490,8 @@ namespace ARMeilleure.Decoders
|
|||
SetA64("0101111101xxxxxx000101xxxxxxxxxx", InstName.Ssra_S, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0x00111100>>>xxx000101xxxxxxxxxx", InstName.Ssra_V, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0100111101xxxxxx000101xxxxxxxxxx", InstName.Ssra_V, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0x001110<<1xxxxx001000xxxxxxxxxx", InstName.Ssubl_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx001100xxxxxxxxxx", InstName.Ssubw_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx001000xxxxxxxxxx", InstName.Ssubl_V, InstEmit.Ssubl_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx001100xxxxxxxxxx", InstName.Ssubw_V, InstEmit.Ssubw_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x00110000000000xxxxxxxxxxxxxxxx", InstName.St__Vms, null, typeof(OpCodeSimdMemMs));
|
||||
SetA64("0x001100100xxxxxxxxxxxxxxxxxxxxx", InstName.St__Vms, null, typeof(OpCodeSimdMemMs));
|
||||
SetA64("0x00110100x00000xxxxxxxxxxxxxxxx", InstName.St__Vss, null, typeof(OpCodeSimdMemSs));
|
||||
|
@ -498,54 +502,58 @@ namespace ARMeilleure.Decoders
|
|||
SetA64("xx111100x00xxxxxxxxx11xxxxxxxxxx", InstName.Str, null, typeof(OpCodeSimdMemImm));
|
||||
SetA64("xx111101x0xxxxxxxxxxxxxxxxxxxxxx", InstName.Str, null, typeof(OpCodeSimdMemImm));
|
||||
SetA64("xx111100x01xxxxxxxxx10xxxxxxxxxx", InstName.Str, null, typeof(OpCodeSimdMemReg));
|
||||
SetA64("01111110111xxxxx100001xxxxxxxxxx", InstName.Sub_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>101110<<1xxxxx100001xxxxxxxxxx", InstName.Sub_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx011000xxxxxxxxxx", InstName.Subhn_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("01011110xx100000001110xxxxxxxxxx", InstName.Suqadd_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>001110<<100000001110xxxxxxxxxx", InstName.Suqadd_V, null, typeof(OpCodeSimd));
|
||||
SetA64("01111110111xxxxx100001xxxxxxxxxx", InstName.Sub_S, InstEmit.Sub_S, typeof(OpCodeSimdReg));
|
||||
SetA64("0>101110<<1xxxxx100001xxxxxxxxxx", InstName.Sub_V, InstEmit.Sub_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<1xxxxx011000xxxxxxxxxx", InstName.Subhn_V, InstEmit.Subhn_V, typeof(OpCodeSimdReg));
|
||||
SetA64("01011110xx100000001110xxxxxxxxxx", InstName.Suqadd_S, InstEmit.Suqadd_S, typeof(OpCodeSimd));
|
||||
SetA64("0>001110<<100000001110xxxxxxxxxx", InstName.Suqadd_V, InstEmit.Suqadd_V, typeof(OpCodeSimd));
|
||||
SetA64("0x001110000xxxxx0xx000xxxxxxxxxx", InstName.Tbl_V, null, typeof(OpCodeSimdTbl));
|
||||
SetA64("0>001110<<0xxxxx001010xxxxxxxxxx", InstName.Trn1_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>001110<<0xxxxx011010xxxxxxxxxx", InstName.Trn2_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx011111xxxxxxxxxx", InstName.Uaba_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx010100xxxxxxxxxx", InstName.Uabal_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx011101xxxxxxxxxx", InstName.Uabd_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx011100xxxxxxxxxx", InstName.Uabdl_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<100000011010xxxxxxxxxx", InstName.Uadalp_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0x101110<<1xxxxx000000xxxxxxxxxx", InstName.Uaddl_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<100000001010xxxxxxxxxx", InstName.Uaddlp_V, null, typeof(OpCodeSimd));
|
||||
SetA64("001011100x110000001110xxxxxxxxxx", InstName.Uaddlv_V, null, typeof(OpCodeSimd));
|
||||
SetA64("01101110<<110000001110xxxxxxxxxx", InstName.Uaddlv_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0x101110<<1xxxxx000100xxxxxxxxxx", InstName.Uaddw_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx011111xxxxxxxxxx", InstName.Uaba_V, InstEmit.Uaba_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx010100xxxxxxxxxx", InstName.Uabal_V, InstEmit.Uabal_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx011101xxxxxxxxxx", InstName.Uabd_V, InstEmit.Uabd_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx011100xxxxxxxxxx", InstName.Uabdl_V, InstEmit.Uabdl_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<100000011010xxxxxxxxxx", InstName.Uadalp_V, InstEmit.Uadalp_V, typeof(OpCodeSimd));
|
||||
SetA64("0x101110<<1xxxxx000000xxxxxxxxxx", InstName.Uaddl_V, InstEmit.Uaddl_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<100000001010xxxxxxxxxx", InstName.Uaddlp_V, InstEmit.Uaddlp_V, typeof(OpCodeSimd));
|
||||
SetA64("001011100x110000001110xxxxxxxxxx", InstName.Uaddlv_V, InstEmit.Uaddlv_V, typeof(OpCodeSimd));
|
||||
SetA64("01101110<<110000001110xxxxxxxxxx", InstName.Uaddlv_V, InstEmit.Uaddlv_V, typeof(OpCodeSimd));
|
||||
SetA64("0x101110<<1xxxxx000100xxxxxxxxxx", InstName.Uaddw_V, InstEmit.Uaddw_V, typeof(OpCodeSimdReg));
|
||||
SetA64("x00111100x100011000000xxxxxxxxxx", InstName.Ucvtf_Gp, null, typeof(OpCodeSimdCvt));
|
||||
SetA64(">00111100x000011>xxxxxxxxxxxxxxx", InstName.Ucvtf_Gp_Fixed, null, typeof(OpCodeSimdCvt));
|
||||
SetA64("011111100x100001110110xxxxxxxxxx", InstName.Ucvtf_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>1011100<100001110110xxxxxxxxxx", InstName.Ucvtf_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0x101110<<1xxxxx000001xxxxxxxxxx", InstName.Uhadd_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx001001xxxxxxxxxx", InstName.Uhsub_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx011001xxxxxxxxxx", InstName.Umax_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx101001xxxxxxxxxx", InstName.Umaxp_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx011011xxxxxxxxxx", InstName.Umin_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx101011xxxxxxxxxx", InstName.Uminp_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx100000xxxxxxxxxx", InstName.Umlal_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101111xxxxxxxx0010x0xxxxxxxxxx", InstName.Umlal_Ve, null, typeof(OpCodeSimdRegElem));
|
||||
SetA64("0x101110<<1xxxxx101000xxxxxxxxxx", InstName.Umlsl_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101111xxxxxxxx0110x0xxxxxxxxxx", InstName.Umlsl_Ve, null, typeof(OpCodeSimdRegElem));
|
||||
SetA64("0x101110<<1xxxxx000001xxxxxxxxxx", InstName.Uhadd_V, InstEmit.Uhadd_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx001001xxxxxxxxxx", InstName.Uhsub_V, InstEmit.Uhsub_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx011001xxxxxxxxxx", InstName.Umax_V, InstEmit.Umax_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx101001xxxxxxxxxx", InstName.Umaxp_V, InstEmit.Umaxp_V, typeof(OpCodeSimdReg));
|
||||
SetA64("001011100x110000101010xxxxxxxxxx", InstName.Umaxv_V, InstEmit.Umaxv_V, typeof(OpCodeSimd));
|
||||
SetA64("01101110<<110000101010xxxxxxxxxx", InstName.Umaxv_V, InstEmit.Umaxv_V, typeof(OpCodeSimd));
|
||||
SetA64("0x101110<<1xxxxx011011xxxxxxxxxx", InstName.Umin_V, InstEmit.Umin_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx101011xxxxxxxxxx", InstName.Uminp_V, InstEmit.Uminp_V, typeof(OpCodeSimdReg));
|
||||
SetA64("001011100x110001101010xxxxxxxxxx", InstName.Uminv_V, InstEmit.Uminv_V, typeof(OpCodeSimd));
|
||||
SetA64("01101110<<110001101010xxxxxxxxxx", InstName.Uminv_V, InstEmit.Uminv_V, typeof(OpCodeSimd));
|
||||
SetA64("0x101110<<1xxxxx100000xxxxxxxxxx", InstName.Umlal_V, InstEmit.Umlal_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101111xxxxxxxx0010x0xxxxxxxxxx", InstName.Umlal_Ve, InstEmit.Umlal_Ve, typeof(OpCodeSimdRegElem));
|
||||
SetA64("0x101110<<1xxxxx101000xxxxxxxxxx", InstName.Umlsl_V, InstEmit.Umlsl_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101111xxxxxxxx0110x0xxxxxxxxxx", InstName.Umlsl_Ve, InstEmit.Umlsl_Ve, typeof(OpCodeSimdRegElem));
|
||||
SetA64("0x001110000xxxxx001111xxxxxxxxxx", InstName.Umov_S, null, typeof(OpCodeSimdIns));
|
||||
SetA64("0x101110<<1xxxxx110000xxxxxxxxxx", InstName.Umull_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101111xxxxxxxx1010x0xxxxxxxxxx", InstName.Umull_Ve, null, typeof(OpCodeSimdRegElem));
|
||||
SetA64("01111110xx1xxxxx000011xxxxxxxxxx", InstName.Uqadd_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>101110<<1xxxxx000011xxxxxxxxxx", InstName.Uqadd_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx110000xxxxxxxxxx", InstName.Umull_V, InstEmit.Umull_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101111xxxxxxxx1010x0xxxxxxxxxx", InstName.Umull_Ve, InstEmit.Umull_Ve, typeof(OpCodeSimdRegElem));
|
||||
SetA64("01111110xx1xxxxx000011xxxxxxxxxx", InstName.Uqadd_S, InstEmit.Uqadd_S, typeof(OpCodeSimdReg));
|
||||
SetA64("0>101110<<1xxxxx000011xxxxxxxxxx", InstName.Uqadd_V, InstEmit.Uqadd_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0>101110<<1xxxxx010111xxxxxxxxxx", InstName.Uqrshl_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0111111100>>>xxx100111xxxxxxxxxx", InstName.Uqrshrn_S, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0x10111100>>>xxx100111xxxxxxxxxx", InstName.Uqrshrn_V, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0>101110<<1xxxxx010011xxxxxxxxxx", InstName.Uqshl_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0111111100>>>xxx100101xxxxxxxxxx", InstName.Uqshrn_S, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0x10111100>>>xxx100101xxxxxxxxxx", InstName.Uqshrn_V, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("01111110xx1xxxxx001011xxxxxxxxxx", InstName.Uqsub_S, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>101110<<1xxxxx001011xxxxxxxxxx", InstName.Uqsub_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("01111110<<100001010010xxxxxxxxxx", InstName.Uqxtn_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0x101110<<100001010010xxxxxxxxxx", InstName.Uqxtn_V, null, typeof(OpCodeSimd));
|
||||
SetA64("0x101110<<1xxxxx000101xxxxxxxxxx", InstName.Urhadd_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("01111110xx1xxxxx001011xxxxxxxxxx", InstName.Uqsub_S, InstEmit.Uqsub_S, typeof(OpCodeSimdReg));
|
||||
SetA64("0>101110<<1xxxxx001011xxxxxxxxxx", InstName.Uqsub_V, InstEmit.Uqsub_V, typeof(OpCodeSimdReg));
|
||||
SetA64("01111110<<100001010010xxxxxxxxxx", InstName.Uqxtn_S, InstEmit.Uqxtn_S, typeof(OpCodeSimd));
|
||||
SetA64("0x101110<<100001010010xxxxxxxxxx", InstName.Uqxtn_V, InstEmit.Uqxtn_V, typeof(OpCodeSimd));
|
||||
SetA64("0x101110<<1xxxxx000101xxxxxxxxxx", InstName.Urhadd_V, InstEmit.Urhadd_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0>101110<<1xxxxx010101xxxxxxxxxx", InstName.Urshl_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0111111101xxxxxx001001xxxxxxxxxx", InstName.Urshr_S, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0x10111100>>>xxx001001xxxxxxxxxx", InstName.Urshr_V, null, typeof(OpCodeSimdShImm));
|
||||
|
@ -558,13 +566,13 @@ namespace ARMeilleure.Decoders
|
|||
SetA64("0111111101xxxxxx000001xxxxxxxxxx", InstName.Ushr_S, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0x10111100>>>xxx000001xxxxxxxxxx", InstName.Ushr_V, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0110111101xxxxxx000001xxxxxxxxxx", InstName.Ushr_V, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("01111110xx100000001110xxxxxxxxxx", InstName.Usqadd_S, null, typeof(OpCodeSimd));
|
||||
SetA64("0>101110<<100000001110xxxxxxxxxx", InstName.Usqadd_V, null, typeof(OpCodeSimd));
|
||||
SetA64("01111110xx100000001110xxxxxxxxxx", InstName.Usqadd_S, InstEmit.Usqadd_S, typeof(OpCodeSimd));
|
||||
SetA64("0>101110<<100000001110xxxxxxxxxx", InstName.Usqadd_V, InstEmit.Usqadd_V, typeof(OpCodeSimd));
|
||||
SetA64("0111111101xxxxxx000101xxxxxxxxxx", InstName.Usra_S, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0x10111100>>>xxx000101xxxxxxxxxx", InstName.Usra_V, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0110111101xxxxxx000101xxxxxxxxxx", InstName.Usra_V, null, typeof(OpCodeSimdShImm));
|
||||
SetA64("0x101110<<1xxxxx001000xxxxxxxxxx", InstName.Usubl_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx001100xxxxxxxxxx", InstName.Usubw_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx001000xxxxxxxxxx", InstName.Usubl_V, InstEmit.Usubl_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0x101110<<1xxxxx001100xxxxxxxxxx", InstName.Usubw_V, InstEmit.Usubw_V, typeof(OpCodeSimdReg));
|
||||
SetA64("0>001110<<0xxxxx000110xxxxxxxxxx", InstName.Uzp1_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0>001110<<0xxxxx010110xxxxxxxxxx", InstName.Uzp2_V, null, typeof(OpCodeSimdReg));
|
||||
SetA64("0x001110<<100001001010xxxxxxxxxx", InstName.Xtn_V, null, typeof(OpCodeSimd));
|
||||
|
|
|
@ -3,16 +3,16 @@ using System;
|
|||
|
||||
namespace ARMeilleure.Diagnostics
|
||||
{
|
||||
class Logger
|
||||
static class Logger
|
||||
{
|
||||
public void StartPass(PassName name)
|
||||
public static void StartPass(PassName name)
|
||||
{
|
||||
#if DEBUG
|
||||
WriteOutput(name + " pass started...");
|
||||
#endif
|
||||
}
|
||||
|
||||
public void EndPass(PassName name, ControlFlowGraph cfg)
|
||||
public static void EndPass(PassName name, ControlFlowGraph cfg)
|
||||
{
|
||||
#if DEBUG
|
||||
EndPass(name);
|
||||
|
@ -23,14 +23,14 @@ namespace ARMeilleure.Diagnostics
|
|||
#endif
|
||||
}
|
||||
|
||||
public void EndPass(PassName name)
|
||||
public static void EndPass(PassName name)
|
||||
{
|
||||
#if DEBUG
|
||||
WriteOutput(name + " pass ended...");
|
||||
#endif
|
||||
}
|
||||
|
||||
private void WriteOutput(string text)
|
||||
private static void WriteOutput(string text)
|
||||
{
|
||||
Console.WriteLine(text);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ namespace ARMeilleure.Diagnostics
|
|||
enum PassName
|
||||
{
|
||||
Translation,
|
||||
SsaConstruction
|
||||
SsaConstruction,
|
||||
PreAllocation,
|
||||
RegisterAllocation
|
||||
}
|
||||
}
|
279
ARMeilleure/Instructions/CryptoHelper.cs
Normal file
279
ARMeilleure/Instructions/CryptoHelper.cs
Normal file
|
@ -0,0 +1,279 @@
|
|||
// https://www.intel.com/content/dam/doc/white-paper/advanced-encryption-standard-new-instructions-set-paper.pdf
|
||||
|
||||
using ARMeilleure.State;
|
||||
|
||||
namespace ARMeilleure.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 V128 AesInvMixColumns(V128 op)
|
||||
{
|
||||
byte[] inState = op.ToArray();
|
||||
byte[] outState = new byte[16];
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
return new V128(outState);
|
||||
}
|
||||
|
||||
public static V128 AesInvShiftRows(V128 op)
|
||||
{
|
||||
byte[] inState = op.ToArray();
|
||||
byte[] outState = new byte[16];
|
||||
|
||||
for (int idx = 0; idx <= 15; idx++)
|
||||
{
|
||||
outState[_isrPerm[idx]] = inState[idx];
|
||||
}
|
||||
|
||||
return new V128(outState);
|
||||
}
|
||||
|
||||
public static V128 AesInvSubBytes(V128 op)
|
||||
{
|
||||
byte[] inState = op.ToArray();
|
||||
byte[] outState = new byte[16];
|
||||
|
||||
for (int idx = 0; idx <= 15; idx++)
|
||||
{
|
||||
outState[idx] = _invSBox[inState[idx]];
|
||||
}
|
||||
|
||||
return new V128(outState);
|
||||
}
|
||||
|
||||
public static V128 AesMixColumns(V128 op)
|
||||
{
|
||||
byte[] inState = op.ToArray();
|
||||
byte[] outState = new byte[16];
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
return new V128(outState);
|
||||
}
|
||||
|
||||
public static V128 AesShiftRows(V128 op)
|
||||
{
|
||||
byte[] inState = op.ToArray();
|
||||
byte[] outState = new byte[16];
|
||||
|
||||
for (int idx = 0; idx <= 15; idx++)
|
||||
{
|
||||
outState[_srPerm[idx]] = inState[idx];
|
||||
}
|
||||
|
||||
return new V128(outState);
|
||||
}
|
||||
|
||||
public static V128 AesSubBytes(V128 op)
|
||||
{
|
||||
byte[] inState = op.ToArray();
|
||||
byte[] outState = new byte[16];
|
||||
|
||||
for (int idx = 0; idx <= 15; idx++)
|
||||
{
|
||||
outState[idx] = _sBox[inState[idx]];
|
||||
}
|
||||
|
||||
return new V128(outState);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@ namespace ARMeilleure.Instructions
|
|||
Operand n = GetAluN(context);
|
||||
Operand m = GetAluM(context);
|
||||
|
||||
Operand d = context.IAdd(n, m);
|
||||
Operand d = context.Add(n, m);
|
||||
|
||||
Operand carry = GetFlag(PState.CFlag);
|
||||
|
||||
|
@ -28,7 +28,7 @@ namespace ARMeilleure.Instructions
|
|||
carry = context.Copy(Local(OperandType.I64), carry);
|
||||
}
|
||||
|
||||
d = context.IAdd(d, carry);
|
||||
d = context.Add(d, carry);
|
||||
|
||||
if (setFlags)
|
||||
{
|
||||
|
@ -43,7 +43,7 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
public static void Add(EmitterContext context)
|
||||
{
|
||||
SetAluD(context, context.IAdd(GetAluN(context), GetAluM(context)));
|
||||
SetAluD(context, context.Add(GetAluN(context), GetAluM(context)));
|
||||
}
|
||||
|
||||
public static void Adds(EmitterContext context)
|
||||
|
@ -51,7 +51,7 @@ namespace ARMeilleure.Instructions
|
|||
Operand n = GetAluN(context);
|
||||
Operand m = GetAluM(context);
|
||||
|
||||
Operand d = context.IAdd(n, m);
|
||||
Operand d = context.Add(n, m);
|
||||
|
||||
EmitNZFlagsCheck(context, d);
|
||||
|
||||
|
@ -119,7 +119,7 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
Operand res = context.CountLeadingZeros(context.BitwiseExclusiveOr(nHigh, nLow));
|
||||
|
||||
res = context.ISubtract(res, Const(res.Type, 1));
|
||||
res = context.Subtract(res, Const(res.Type, 1));
|
||||
|
||||
SetAluDOrZR(context, res);
|
||||
}
|
||||
|
@ -195,7 +195,7 @@ namespace ARMeilleure.Instructions
|
|||
Operand n = GetAluN(context);
|
||||
Operand m = GetAluM(context);
|
||||
|
||||
Operand d = context.ISubtract(n, m);
|
||||
Operand d = context.Subtract(n, m);
|
||||
|
||||
Operand borrow = context.BitwiseExclusiveOr(GetFlag(PState.CFlag), Const(1));
|
||||
|
||||
|
@ -204,7 +204,7 @@ namespace ARMeilleure.Instructions
|
|||
borrow = context.Copy(Local(OperandType.I64), borrow);
|
||||
}
|
||||
|
||||
d = context.ISubtract(d, borrow);
|
||||
d = context.Subtract(d, borrow);
|
||||
|
||||
if (setFlags)
|
||||
{
|
||||
|
@ -219,7 +219,7 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
public static void Sub(EmitterContext context)
|
||||
{
|
||||
SetAluD(context, context.ISubtract(GetAluN(context), GetAluM(context)));
|
||||
SetAluD(context, context.Subtract(GetAluN(context), GetAluM(context)));
|
||||
}
|
||||
|
||||
public static void Subs(EmitterContext context)
|
||||
|
@ -227,7 +227,7 @@ namespace ARMeilleure.Instructions
|
|||
Operand n = GetAluN(context);
|
||||
Operand m = GetAluM(context);
|
||||
|
||||
Operand d = context.ISubtract(n, m);
|
||||
Operand d = context.Subtract(n, m);
|
||||
|
||||
EmitNZFlagsCheck(context, d);
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
if (isNegated)
|
||||
{
|
||||
Operand d = context.IAdd(n, m);
|
||||
Operand d = context.Add(n, m);
|
||||
|
||||
EmitNZFlagsCheck(context, d);
|
||||
|
||||
|
@ -47,7 +47,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
Operand d = context.ISubtract(n, m);
|
||||
Operand d = context.Subtract(n, m);
|
||||
|
||||
EmitNZFlagsCheck(context, d);
|
||||
|
||||
|
|
58
ARMeilleure/Instructions/InstEmitCrypto.cs
Normal file
58
ARMeilleure/Instructions/InstEmitCrypto.cs
Normal file
|
@ -0,0 +1,58 @@
|
|||
using ARMeilleure.Decoders;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.Translation;
|
||||
using System.Reflection;
|
||||
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
static partial class InstEmit
|
||||
{
|
||||
public static void Aesd_V(EmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
Operand d = GetVec(op.Rd);
|
||||
Operand n = GetVec(op.Rn);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Decrypt));
|
||||
|
||||
context.Copy(d, context.Call(info, d, n));
|
||||
}
|
||||
|
||||
public static void Aese_V(EmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
Operand d = GetVec(op.Rd);
|
||||
Operand n = GetVec(op.Rn);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Encrypt));
|
||||
|
||||
context.Copy(d, context.Call(info, d, n));
|
||||
}
|
||||
|
||||
public static void Aesimc_V(EmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
Operand n = GetVec(op.Rn);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.InverseMixColumns));
|
||||
|
||||
context.Copy(GetVec(op.Rd), context.Call(info, n));
|
||||
}
|
||||
|
||||
public static void Aesmc_V(EmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
Operand n = GetVec(op.Rn);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.MixColumns));
|
||||
|
||||
context.Copy(GetVec(op.Rd), context.Call(info, n));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -32,7 +32,7 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
if (cselOp == CselOperation.Increment)
|
||||
{
|
||||
m = context.IAdd(m, Const(m.Type, 1));
|
||||
m = context.Add(m, Const(m.Type, 1));
|
||||
}
|
||||
else if (cselOp == CselOperation.Invert)
|
||||
{
|
||||
|
@ -40,7 +40,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
else if (cselOp == CselOperation.Negate)
|
||||
{
|
||||
m = context.INegate(m);
|
||||
m = context.Negate(m);
|
||||
}
|
||||
|
||||
Operand condTrue = GetCondTrue(context, op.Cond);
|
||||
|
|
|
@ -50,8 +50,8 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
|
||||
Operand d = unsigned
|
||||
? context.IDivideUI(n, m)
|
||||
: context.IDivide (n, m);
|
||||
? context.DivideUI(n, m)
|
||||
: context.Divide (n, m);
|
||||
|
||||
SetAluDOrZR(context, d);
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
Operand address = GetAddress(context);
|
||||
|
||||
Operand address2 = context.IAdd(address, Const(1L << op.Size));
|
||||
Operand address2 = context.Add(address, Const(1L << op.Size));
|
||||
|
||||
EmitLoad(op.Rt, address);
|
||||
EmitLoad(op.Rt2, address2);
|
||||
|
@ -117,7 +117,7 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
Operand address = GetAddress(context);
|
||||
|
||||
Operand address2 = context.IAdd(address, Const(1L << op.Size));
|
||||
Operand address2 = context.Add(address, Const(1L << op.Size));
|
||||
|
||||
Operand t = GetT(context, op.Rt);
|
||||
Operand t2 = GetT(context, op.Rt2);
|
||||
|
@ -141,7 +141,7 @@ namespace ARMeilleure.Instructions
|
|||
//Pre-indexing.
|
||||
if (!op.PostIdx)
|
||||
{
|
||||
address = context.IAdd(address, Const(op.Immediate));
|
||||
address = context.Add(address, Const(op.Immediate));
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -158,7 +158,7 @@ namespace ARMeilleure.Instructions
|
|||
m = context.ShiftLeft(m, Const(op.Size));
|
||||
}
|
||||
|
||||
address = context.IAdd(n, m);
|
||||
address = context.Add(n, m);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
if (op.PostIdx)
|
||||
{
|
||||
address = context.IAdd(address, Const(op.Immediate));
|
||||
address = context.Add(address, Const(op.Immediate));
|
||||
}
|
||||
|
||||
context.Copy(GetIntOrSP(op, op.Rn), address);
|
||||
|
|
|
@ -4,7 +4,6 @@ using ARMeilleure.Translation;
|
|||
using System;
|
||||
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
|
@ -21,9 +20,9 @@ namespace ARMeilleure.Instructions
|
|||
Operand n = GetIntOrZR(op, op.Rn);
|
||||
Operand m = GetIntOrZR(op, op.Rm);
|
||||
|
||||
Operand res = context.IMultiply(n, m);
|
||||
Operand res = context.Multiply(n, m);
|
||||
|
||||
res = isAdd ? context.IAdd(a, res) : context.ISubtract(a, res);
|
||||
res = isAdd ? context.Add(a, res) : context.Subtract(a, res);
|
||||
|
||||
SetIntOrZR(context, op.Rd, res);
|
||||
}
|
||||
|
@ -67,9 +66,9 @@ namespace ARMeilleure.Instructions
|
|||
Operand n = GetExtendedRegister32(op.Rn);
|
||||
Operand m = GetExtendedRegister32(op.Rm);
|
||||
|
||||
Operand res = context.IMultiply(n, m);
|
||||
Operand res = context.Multiply(n, m);
|
||||
|
||||
res = (flags & MullFlags.Add) != 0 ? context.IAdd(a, res) : context.ISubtract(a, res);
|
||||
res = (flags & MullFlags.Add) != 0 ? context.Add(a, res) : context.Subtract(a, res);
|
||||
|
||||
SetIntOrZR(context, op.Rd, res);
|
||||
}
|
||||
|
|
3153
ARMeilleure/Instructions/InstEmitSimdArithmetic.cs
Normal file
3153
ARMeilleure/Instructions/InstEmitSimdArithmetic.cs
Normal file
File diff suppressed because it is too large
Load diff
1413
ARMeilleure/Instructions/InstEmitSimdHelper.cs
Normal file
1413
ARMeilleure/Instructions/InstEmitSimdHelper.cs
Normal file
File diff suppressed because it is too large
Load diff
35
ARMeilleure/Instructions/InstEmitSimdMove.cs
Normal file
35
ARMeilleure/Instructions/InstEmitSimdMove.cs
Normal file
|
@ -0,0 +1,35 @@
|
|||
using ARMeilleure.Decoders;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.State;
|
||||
using ARMeilleure.Translation;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitMemoryHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
||||
using static ARMeilleure.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
static partial class InstEmit
|
||||
{
|
||||
public static void Fmov_Si(EmitterContext context)
|
||||
{
|
||||
OpCodeSimdFmov op = (OpCodeSimdFmov)context.CurrOp;
|
||||
|
||||
Operand imm;
|
||||
|
||||
if (op.Size != 0)
|
||||
{
|
||||
imm = Const(op.Immediate);
|
||||
}
|
||||
else
|
||||
{
|
||||
imm = Const((int)op.Immediate);
|
||||
}
|
||||
|
||||
context.Copy(GetVec(op.Rd), imm);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -314,8 +314,10 @@ namespace ARMeilleure.Instructions
|
|||
Sli_V,
|
||||
Smax_V,
|
||||
Smaxp_V,
|
||||
Smaxv_V,
|
||||
Smin_V,
|
||||
Sminp_V,
|
||||
Sminv_V,
|
||||
Smlal_V,
|
||||
Smlal_Ve,
|
||||
Smlsl_V,
|
||||
|
@ -390,8 +392,10 @@ namespace ARMeilleure.Instructions
|
|||
Uhsub_V,
|
||||
Umax_V,
|
||||
Umaxp_V,
|
||||
Umaxv_V,
|
||||
Umin_V,
|
||||
Uminp_V,
|
||||
Uminv_V,
|
||||
Umlal_V,
|
||||
Umlal_Ve,
|
||||
Umlsl_V,
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace ARMeilleure.Instructions
|
|||
GetContext().OnUndefined(address, opCode);
|
||||
}
|
||||
|
||||
private static ExecutionContext GetContext()
|
||||
public static ExecutionContext GetContext()
|
||||
{
|
||||
return _contexts[Thread.CurrentThread];
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using ARMeilleure.State;
|
||||
using System;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
|
@ -12,7 +13,395 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
#endregion
|
||||
|
||||
#region "Rounding"
|
||||
public static double Round(double value)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
FPRoundingMode roundMode = context.Fpcr.GetRoundingMode();
|
||||
|
||||
if (roundMode == FPRoundingMode.ToNearest)
|
||||
{
|
||||
return Math.Round(value); // even
|
||||
}
|
||||
else if (roundMode == FPRoundingMode.TowardsPlusInfinity)
|
||||
{
|
||||
return Math.Ceiling(value);
|
||||
}
|
||||
else if (roundMode == FPRoundingMode.TowardsMinusInfinity)
|
||||
{
|
||||
return Math.Floor(value);
|
||||
}
|
||||
else /* if (roundMode == FPRoundingMode.TowardsZero) */
|
||||
{
|
||||
return Math.Truncate(value);
|
||||
}
|
||||
}
|
||||
|
||||
public static float RoundF(float value)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
FPRoundingMode roundMode = context.Fpcr.GetRoundingMode();
|
||||
|
||||
if (roundMode == FPRoundingMode.ToNearest)
|
||||
{
|
||||
return MathF.Round(value); // even
|
||||
}
|
||||
else if (roundMode == FPRoundingMode.TowardsPlusInfinity)
|
||||
{
|
||||
return MathF.Ceiling(value);
|
||||
}
|
||||
else if (roundMode == FPRoundingMode.TowardsMinusInfinity)
|
||||
{
|
||||
return MathF.Floor(value);
|
||||
}
|
||||
else /* if (roundMode == FPRoundingMode.TowardsZero) */
|
||||
{
|
||||
return MathF.Truncate(value);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region "Saturating"
|
||||
public static long SignedSrcSignedDstSatQ(long op, int size)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
int eSize = 8 << size;
|
||||
|
||||
long tMaxValue = (1L << (eSize - 1)) - 1L;
|
||||
long tMinValue = -(1L << (eSize - 1));
|
||||
|
||||
if (op > tMaxValue)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return tMaxValue;
|
||||
}
|
||||
else if (op < tMinValue)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return tMinValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return op;
|
||||
}
|
||||
}
|
||||
|
||||
public static ulong SignedSrcUnsignedDstSatQ(long op, int size)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
int eSize = 8 << size;
|
||||
|
||||
ulong tMaxValue = (1UL << eSize) - 1UL;
|
||||
ulong tMinValue = 0UL;
|
||||
|
||||
if (op > (long)tMaxValue)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return tMaxValue;
|
||||
}
|
||||
else if (op < (long)tMinValue)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return tMinValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (ulong)op;
|
||||
}
|
||||
}
|
||||
|
||||
public static long UnsignedSrcSignedDstSatQ(ulong op, int size)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
int eSize = 8 << size;
|
||||
|
||||
long tMaxValue = (1L << (eSize - 1)) - 1L;
|
||||
|
||||
if (op > (ulong)tMaxValue)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return tMaxValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (long)op;
|
||||
}
|
||||
}
|
||||
|
||||
public static ulong UnsignedSrcUnsignedDstSatQ(ulong op, int size)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
int eSize = 8 << size;
|
||||
|
||||
ulong tMaxValue = (1UL << eSize) - 1UL;
|
||||
|
||||
if (op > tMaxValue)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return tMaxValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return op;
|
||||
}
|
||||
}
|
||||
|
||||
public static long UnarySignedSatQAbsOrNeg(long op)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
if (op == long.MinValue)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return long.MaxValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return op;
|
||||
}
|
||||
}
|
||||
|
||||
public static long BinarySignedSatQAdd(long op1, long op2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
long add = op1 + op2;
|
||||
|
||||
if ((~(op1 ^ op2) & (op1 ^ add)) < 0L)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
if (op1 < 0L)
|
||||
{
|
||||
return long.MinValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return long.MaxValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return add;
|
||||
}
|
||||
}
|
||||
|
||||
public static ulong BinaryUnsignedSatQAdd(ulong op1, ulong op2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
ulong add = op1 + op2;
|
||||
|
||||
if ((add < op1) && (add < op2))
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return ulong.MaxValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return add;
|
||||
}
|
||||
}
|
||||
|
||||
public static long BinarySignedSatQSub(long op1, long op2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
long sub = op1 - op2;
|
||||
|
||||
if (((op1 ^ op2) & (op1 ^ sub)) < 0L)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
if (op1 < 0L)
|
||||
{
|
||||
return long.MinValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return long.MaxValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return sub;
|
||||
}
|
||||
}
|
||||
|
||||
public static ulong BinaryUnsignedSatQSub(ulong op1, ulong op2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
ulong sub = op1 - op2;
|
||||
|
||||
if (op1 < op2)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return ulong.MinValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return sub;
|
||||
}
|
||||
}
|
||||
|
||||
public static long BinarySignedSatQAcc(ulong op1, long op2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
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)
|
||||
{
|
||||
context.Fpsr |= 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
|
||||
|
||||
context.Fpsr |= 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)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return long.MaxValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (long)add;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ulong BinaryUnsignedSatQAcc(long op1, ulong op2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
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))
|
||||
{
|
||||
context.Fpsr |= 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)
|
||||
{
|
||||
context.Fpsr |= 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);
|
||||
|
@ -26,15 +415,15 @@ namespace ARMeilleure.Instructions
|
|||
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 Crc32b(uint crc, byte value) => Crc32 (crc, Crc32RevPoly, value);
|
||||
public static uint Crc32h(uint crc, ushort value) => Crc32h(crc, Crc32RevPoly, value);
|
||||
public static uint Crc32w(uint crc, uint value) => Crc32w(crc, Crc32RevPoly, value);
|
||||
public static uint Crc32x(uint crc, ulong value) => Crc32x(crc, Crc32RevPoly, value);
|
||||
|
||||
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);
|
||||
public static uint Crc32cb(uint crc, byte value) => Crc32 (crc, Crc32cRevPoly, value);
|
||||
public static uint Crc32ch(uint crc, ushort value) => Crc32h(crc, Crc32cRevPoly, value);
|
||||
public static uint Crc32cw(uint crc, uint value) => Crc32w(crc, Crc32cRevPoly, value);
|
||||
public static uint Crc32cx(uint crc, ulong value) => Crc32x(crc, Crc32cRevPoly, value);
|
||||
|
||||
private static uint Crc32h(uint crc, uint poly, ushort val)
|
||||
{
|
||||
|
@ -84,7 +473,25 @@ namespace ARMeilleure.Instructions
|
|||
#endregion
|
||||
|
||||
#region "Aes"
|
||||
public static V128 Decrypt(V128 value, V128 roundKey)
|
||||
{
|
||||
return CryptoHelper.AesInvSubBytes(CryptoHelper.AesInvShiftRows(value ^ roundKey));
|
||||
}
|
||||
|
||||
public static V128 Encrypt(V128 value, V128 roundKey)
|
||||
{
|
||||
return CryptoHelper.AesSubBytes(CryptoHelper.AesShiftRows(value ^ roundKey));
|
||||
}
|
||||
|
||||
public static V128 InverseMixColumns(V128 value)
|
||||
{
|
||||
return CryptoHelper.AesInvMixColumns(value);
|
||||
}
|
||||
|
||||
public static V128 MixColumns(V128 value)
|
||||
{
|
||||
return CryptoHelper.AesMixColumns(value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region "Sha1"
|
||||
|
|
2741
ARMeilleure/Instructions/SoftFloat.cs
Normal file
2741
ARMeilleure/Instructions/SoftFloat.cs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -54,6 +54,120 @@ namespace ARMeilleure.IntermediateRepresentation
|
|||
Store8,
|
||||
StoreToContext,
|
||||
Subtract,
|
||||
VectorExtract,
|
||||
VectorExtract16,
|
||||
VectorExtract8,
|
||||
VectorInsert,
|
||||
VectorInsert16,
|
||||
VectorInsert8,
|
||||
VectorZero,
|
||||
VectorZeroUpper64,
|
||||
VectorZeroUpper96,
|
||||
|
||||
//Intrinsics
|
||||
X86Intrinsic_Start,
|
||||
X86Addpd,
|
||||
X86Addps,
|
||||
X86Addsd,
|
||||
X86Addss,
|
||||
X86Andnpd,
|
||||
X86Andnps,
|
||||
X86Divpd,
|
||||
X86Divps,
|
||||
X86Divsd,
|
||||
X86Divss,
|
||||
X86Haddpd,
|
||||
X86Haddps,
|
||||
X86Maxpd,
|
||||
X86Maxps,
|
||||
X86Maxsd,
|
||||
X86Maxss,
|
||||
X86Minpd,
|
||||
X86Minps,
|
||||
X86Minsd,
|
||||
X86Minss,
|
||||
X86Movhlps,
|
||||
X86Movlhps,
|
||||
X86Mulpd,
|
||||
X86Mulps,
|
||||
X86Mulsd,
|
||||
X86Mulss,
|
||||
X86Paddb,
|
||||
X86Paddd,
|
||||
X86Paddq,
|
||||
X86Paddw,
|
||||
X86Pand,
|
||||
X86Pandn,
|
||||
X86Pavgb,
|
||||
X86Pavgw,
|
||||
X86Pblendvb,
|
||||
X86Pcmpeqb,
|
||||
X86Pcmpeqd,
|
||||
X86Pcmpeqq,
|
||||
X86Pcmpeqw,
|
||||
X86Pcmpgtb,
|
||||
X86Pcmpgtd,
|
||||
X86Pcmpgtq,
|
||||
X86Pcmpgtw,
|
||||
X86Pmaxsb,
|
||||
X86Pmaxsd,
|
||||
X86Pmaxsw,
|
||||
X86Pmaxub,
|
||||
X86Pmaxud,
|
||||
X86Pmaxuw,
|
||||
X86Pminsb,
|
||||
X86Pminsd,
|
||||
X86Pminsw,
|
||||
X86Pminub,
|
||||
X86Pminud,
|
||||
X86Pminuw,
|
||||
X86Pmovsxbw,
|
||||
X86Pmovsxdq,
|
||||
X86Pmovsxwd,
|
||||
X86Pmovzxbw,
|
||||
X86Pmovzxdq,
|
||||
X86Pmovzxwd,
|
||||
X86Pmulld,
|
||||
X86Pmullw,
|
||||
X86Popcnt,
|
||||
X86Por,
|
||||
X86Psllw,
|
||||
X86Psrad,
|
||||
X86Psraw,
|
||||
X86Psrld,
|
||||
X86Psrlq,
|
||||
X86Psrldq,
|
||||
X86Psrlw,
|
||||
X86Psubb,
|
||||
X86Psubd,
|
||||
X86Psubq,
|
||||
X86Psubw,
|
||||
X86Pxor,
|
||||
X86Rcpps,
|
||||
X86Rcpss,
|
||||
X86Roundpd,
|
||||
X86Roundps,
|
||||
X86Roundsd,
|
||||
X86Roundss,
|
||||
X86Rsqrtps,
|
||||
X86Rsqrtss,
|
||||
X86Shufpd,
|
||||
X86Shufps,
|
||||
X86Sqrtpd,
|
||||
X86Sqrtps,
|
||||
X86Sqrtsd,
|
||||
X86Sqrtss,
|
||||
X86Subpd,
|
||||
X86Subps,
|
||||
X86Subsd,
|
||||
X86Subss,
|
||||
X86Unpckhpd,
|
||||
X86Unpckhps,
|
||||
X86Unpcklpd,
|
||||
X86Unpcklps,
|
||||
X86Xorpd,
|
||||
X86Xorps,
|
||||
X86Intrinsic_End,
|
||||
|
||||
Count
|
||||
}
|
||||
|
|
|
@ -35,6 +35,11 @@ namespace ARMeilleure.IntermediateRepresentation
|
|||
return new Operand(BitConverter.SingleToInt32Bits(value));
|
||||
}
|
||||
|
||||
public static Operand ConstF(double value)
|
||||
{
|
||||
return new Operand(BitConverter.DoubleToInt64Bits(value));
|
||||
}
|
||||
|
||||
public static Operand Label()
|
||||
{
|
||||
return new Operand(OperandKind.Label);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
using System;
|
||||
|
||||
namespace ARMeilleure.IntermediateRepresentation
|
||||
{
|
||||
enum OperandType
|
||||
|
@ -17,5 +19,19 @@ namespace ARMeilleure.IntermediateRepresentation
|
|||
return type == OperandType.I32 ||
|
||||
type == OperandType.I64;
|
||||
}
|
||||
|
||||
public static RegisterType ToRegisterType(this OperandType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case OperandType.FP32: return RegisterType.Vector;
|
||||
case OperandType.FP64: return RegisterType.Vector;
|
||||
case OperandType.I32: return RegisterType.Integer;
|
||||
case OperandType.I64: return RegisterType.Integer;
|
||||
case OperandType.V128: return RegisterType.Vector;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"Invalid operand type \"{type}\".");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
|
||||
namespace ARMeilleure.State
|
||||
namespace ARMeilleure.IntermediateRepresentation
|
||||
{
|
||||
struct Register : IEquatable<Register>
|
||||
{
|
|
@ -1,4 +1,4 @@
|
|||
namespace ARMeilleure.State
|
||||
namespace ARMeilleure.IntermediateRepresentation
|
||||
{
|
||||
enum RegisterType
|
||||
{
|
|
@ -4,13 +4,22 @@ namespace ARMeilleure
|
|||
{
|
||||
public static bool AssumeStrictAbiCompliance { get; set; }
|
||||
|
||||
public static bool FastFP { get; set; } = true;
|
||||
public static bool FastFP { get; set; } = false;
|
||||
|
||||
public static bool UseSseIfAvailable { get; set; }
|
||||
public static bool UseSse2IfAvailable { get; set; }
|
||||
public static bool UseSse3IfAvailable { get; set; }
|
||||
public static bool UseSsse3IfAvailable { get; set; }
|
||||
public static bool UseSseIfAvailable { get; set; }
|
||||
public static bool UseSse2IfAvailable { get; set; }
|
||||
public static bool UseSse3IfAvailable { get; set; }
|
||||
public static bool UseSsse3IfAvailable { get; set; }
|
||||
public static bool UseSse41IfAvailable { get; set; }
|
||||
public static bool UseSse42IfAvailable { get; set; }
|
||||
public static bool UseSse42IfAvailable { get; set; }
|
||||
public static bool UsePopCntIfAvailable { get; set; }
|
||||
|
||||
internal static bool UseSse { get; set; } = true;
|
||||
internal static bool UseSse2 { get; set; } = true;
|
||||
internal static bool UseSse3 { get; set; } = true;
|
||||
internal static bool UseSsse3 { get; set; } = true;
|
||||
internal static bool UseSse41 { get; set; } = true;
|
||||
internal static bool UseSse42 { get; set; }
|
||||
internal static bool UsePopCnt { get; set; }
|
||||
}
|
||||
}
|
|
@ -8,6 +8,9 @@ namespace ARMeilleure.State
|
|||
|
||||
internal IntPtr NativeContextPtr => _nativeContext.BasePtr;
|
||||
|
||||
public FPCR Fpcr { get; set; }
|
||||
public FPSR Fpsr { get; set; }
|
||||
|
||||
public event EventHandler<InstExceptionEventArgs> Break;
|
||||
public event EventHandler<InstExceptionEventArgs> SupervisorCall;
|
||||
public event EventHandler<InstUndefinedEventArgs> Undefined;
|
||||
|
|
23
ARMeilleure/State/FPCR.cs
Normal file
23
ARMeilleure/State/FPCR.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
|
||||
namespace ARMeilleure.State
|
||||
{
|
||||
[Flags]
|
||||
public enum FPCR
|
||||
{
|
||||
Ufe = 1 << 11,
|
||||
Fz = 1 << 24,
|
||||
Dn = 1 << 25,
|
||||
Ahp = 1 << 26
|
||||
}
|
||||
|
||||
public static class FPCRExtensions
|
||||
{
|
||||
private const int RModeShift = 22;
|
||||
|
||||
public static FPRoundingMode GetRoundingMode(this FPCR fpcr)
|
||||
{
|
||||
return (FPRoundingMode)(((int)fpcr >> RModeShift) & 3);
|
||||
}
|
||||
}
|
||||
}
|
12
ARMeilleure/State/FPException.cs
Normal file
12
ARMeilleure/State/FPException.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ARMeilleure.State
|
||||
{
|
||||
enum FPException
|
||||
{
|
||||
InvalidOp = 0,
|
||||
DivideByZero = 1,
|
||||
Overflow = 2,
|
||||
Underflow = 3,
|
||||
Inexact = 4,
|
||||
InputDenorm = 7
|
||||
}
|
||||
}
|
10
ARMeilleure/State/FPRoundingMode.cs
Normal file
10
ARMeilleure/State/FPRoundingMode.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace ARMeilleure.State
|
||||
{
|
||||
public enum FPRoundingMode
|
||||
{
|
||||
ToNearest = 0,
|
||||
TowardsPlusInfinity = 1,
|
||||
TowardsMinusInfinity = 2,
|
||||
TowardsZero = 3
|
||||
}
|
||||
}
|
11
ARMeilleure/State/FPSR.cs
Normal file
11
ARMeilleure/State/FPSR.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
|
||||
namespace ARMeilleure.State
|
||||
{
|
||||
[Flags]
|
||||
public enum FPSR
|
||||
{
|
||||
Ufc = 1 << 3,
|
||||
Qc = 1 << 27
|
||||
}
|
||||
}
|
11
ARMeilleure/State/FPType.cs
Normal file
11
ARMeilleure/State/FPType.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace ARMeilleure.State
|
||||
{
|
||||
enum FPType
|
||||
{
|
||||
Nonzero,
|
||||
Zero,
|
||||
Infinity,
|
||||
QNaN,
|
||||
SNaN
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.Memory;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
|
|
@ -7,19 +7,45 @@ namespace ARMeilleure.State
|
|||
private ulong _e0;
|
||||
private ulong _e1;
|
||||
|
||||
public V128(float value)
|
||||
public V128(float value) : this(value, value, value, value) { }
|
||||
|
||||
public V128(double value) : this(value, value) { }
|
||||
|
||||
public V128(float e0, float e1, float e2, float e3)
|
||||
{
|
||||
_e0 = (uint)BitConverter.SingleToInt32Bits(value);
|
||||
_e1 = 0;
|
||||
_e0 = (ulong)(uint)BitConverter.SingleToInt32Bits(e0) << 0;
|
||||
_e0 |= (ulong)(uint)BitConverter.SingleToInt32Bits(e1) << 32;
|
||||
_e1 = (ulong)(uint)BitConverter.SingleToInt32Bits(e2) << 0;
|
||||
_e1 |= (ulong)(uint)BitConverter.SingleToInt32Bits(e3) << 32;
|
||||
}
|
||||
|
||||
public V128(double value)
|
||||
public V128(double e0, double e1)
|
||||
{
|
||||
_e0 = (ulong)BitConverter.DoubleToInt64Bits(value);
|
||||
_e1 = 0;
|
||||
_e0 = (ulong)BitConverter.DoubleToInt64Bits(e0);
|
||||
_e1 = (ulong)BitConverter.DoubleToInt64Bits(e1);
|
||||
}
|
||||
|
||||
public V128(long e0, long e1) : this((ulong)e0, (ulong)e1) { }
|
||||
public V128(int e0, int e1, int e2, int e3)
|
||||
{
|
||||
_e0 = (ulong)(uint)e0 << 0;
|
||||
_e0 |= (ulong)(uint)e1 << 32;
|
||||
_e1 = (ulong)(uint)e2 << 0;
|
||||
_e1 |= (ulong)(uint)e3 << 32;
|
||||
}
|
||||
|
||||
public V128(uint e0, uint e1, uint e2, uint e3)
|
||||
{
|
||||
_e0 = (ulong)e0 << 0;
|
||||
_e0 |= (ulong)e1 << 32;
|
||||
_e1 = (ulong)e2 << 0;
|
||||
_e1 |= (ulong)e3 << 32;
|
||||
}
|
||||
|
||||
public V128(long e0, long e1)
|
||||
{
|
||||
_e0 = (ulong)e0;
|
||||
_e1 = (ulong)e1;
|
||||
}
|
||||
|
||||
public V128(ulong e0, ulong e1)
|
||||
{
|
||||
|
@ -27,6 +53,12 @@ namespace ARMeilleure.State
|
|||
_e1 = e1;
|
||||
}
|
||||
|
||||
public V128(byte[] data)
|
||||
{
|
||||
_e0 = (ulong)BitConverter.ToInt64(data, 0);
|
||||
_e1 = (ulong)BitConverter.ToInt64(data, 8);
|
||||
}
|
||||
|
||||
public float AsFloat()
|
||||
{
|
||||
return GetFloat(0);
|
||||
|
@ -47,7 +79,8 @@ namespace ARMeilleure.State
|
|||
return BitConverter.Int64BitsToDouble(GetInt64(index));
|
||||
}
|
||||
|
||||
public int GetInt32(int index) => (int)GetUInt32(index);
|
||||
public int GetInt32(int index) => (int)GetUInt32(index);
|
||||
public long GetInt64(int index) => (long)GetUInt64(index);
|
||||
|
||||
public uint GetUInt32(int index)
|
||||
{
|
||||
|
@ -56,11 +89,9 @@ namespace ARMeilleure.State
|
|||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
|
||||
return (uint)((((index & 2) != 0) ? _e1 : _e0) >> (index & 1));
|
||||
return (uint)(GetUInt64(index >> 1) >> (index & 1));
|
||||
}
|
||||
|
||||
public long GetInt64(int index) => (long)GetUInt64(index);
|
||||
|
||||
public ulong GetUInt64(int index)
|
||||
{
|
||||
switch (index)
|
||||
|
@ -72,11 +103,44 @@ namespace ARMeilleure.State
|
|||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
|
||||
public byte[] ToArray()
|
||||
{
|
||||
byte[] e0Data = BitConverter.GetBytes(_e0);
|
||||
byte[] e1Data = BitConverter.GetBytes(_e1);
|
||||
|
||||
byte[] data = new byte[16];
|
||||
|
||||
Buffer.BlockCopy(e0Data, 0, data, 0, 8);
|
||||
Buffer.BlockCopy(e1Data, 0, data, 8, 8);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(_e0, _e1);
|
||||
}
|
||||
|
||||
public static V128 operator ~(V128 x)
|
||||
{
|
||||
return new V128(~x._e0, ~x._e1);
|
||||
}
|
||||
|
||||
public static V128 operator &(V128 x, V128 y)
|
||||
{
|
||||
return new V128(x._e0 & y._e0, x._e1 & y._e1);
|
||||
}
|
||||
|
||||
public static V128 operator |(V128 x, V128 y)
|
||||
{
|
||||
return new V128(x._e0 | y._e0, x._e1 | y._e1);
|
||||
}
|
||||
|
||||
public static V128 operator ^(V128 x, V128 y)
|
||||
{
|
||||
return new V128(x._e0 ^ y._e0, x._e1 ^ y._e1);
|
||||
}
|
||||
|
||||
public static bool operator ==(V128 x, V128 y)
|
||||
{
|
||||
return x.Equals(y);
|
||||
|
@ -96,5 +160,10 @@ namespace ARMeilleure.State
|
|||
{
|
||||
return other._e0 == _e0 && other._e1 == _e1;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"0x{_e1:X16}{_e0:X16}";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,6 +37,11 @@ namespace ARMeilleure.Translation
|
|||
_needsNewBlock = true;
|
||||
}
|
||||
|
||||
public Operand Add(Operand a, Operand b)
|
||||
{
|
||||
return Add(Instruction.Add, Local(a.Type), a, b);
|
||||
}
|
||||
|
||||
public Operand BitwiseAnd(Operand a, Operand b)
|
||||
{
|
||||
return Add(Instruction.BitwiseAnd, Local(a.Type), a, b);
|
||||
|
@ -158,9 +163,14 @@ namespace ARMeilleure.Translation
|
|||
return Add(Instruction.CountLeadingZeros, Local(a.Type), a);
|
||||
}
|
||||
|
||||
public Operand IAdd(Operand a, Operand b)
|
||||
public Operand Divide(Operand a, Operand b)
|
||||
{
|
||||
return Add(Instruction.Add, Local(a.Type), a, b);
|
||||
return Add(Instruction.Divide, Local(a.Type), a, b);
|
||||
}
|
||||
|
||||
public Operand DivideUI(Operand a, Operand b)
|
||||
{
|
||||
return Add(Instruction.DivideUI, Local(a.Type), a, b);
|
||||
}
|
||||
|
||||
public Operand ICompareEqual(Operand a, Operand b)
|
||||
|
@ -213,31 +223,6 @@ namespace ARMeilleure.Translation
|
|||
return Add(Instruction.CompareNotEqual, Local(OperandType.I32), a, b);
|
||||
}
|
||||
|
||||
public Operand IDivide(Operand a, Operand b)
|
||||
{
|
||||
return Add(Instruction.Divide, Local(a.Type), a, b);
|
||||
}
|
||||
|
||||
public Operand IDivideUI(Operand a, Operand b)
|
||||
{
|
||||
return Add(Instruction.DivideUI, Local(a.Type), a, b);
|
||||
}
|
||||
|
||||
public Operand IMultiply(Operand a, Operand b)
|
||||
{
|
||||
return Add(Instruction.Multiply, Local(a.Type), a, b);
|
||||
}
|
||||
|
||||
public Operand INegate(Operand a)
|
||||
{
|
||||
return Add(Instruction.Negate, Local(a.Type), a);
|
||||
}
|
||||
|
||||
public Operand ISubtract(Operand a, Operand b)
|
||||
{
|
||||
return Add(Instruction.Subtract, Local(a.Type), a, b);
|
||||
}
|
||||
|
||||
public Operand Load(Operand value, Operand address)
|
||||
{
|
||||
return Add(Instruction.Load, value, address);
|
||||
|
@ -268,6 +253,11 @@ namespace ARMeilleure.Translation
|
|||
return Add(Instruction.LoadZx8, value, address);
|
||||
}
|
||||
|
||||
public Operand Multiply(Operand a, Operand b)
|
||||
{
|
||||
return Add(Instruction.Multiply, Local(a.Type), a, b);
|
||||
}
|
||||
|
||||
public Operand Multiply64HighSI(Operand a, Operand b)
|
||||
{
|
||||
return Add(Instruction.Multiply64HighSI, Local(OperandType.I64), a, b);
|
||||
|
@ -278,6 +268,11 @@ namespace ARMeilleure.Translation
|
|||
return Add(Instruction.Multiply64HighUI, Local(OperandType.I64), a, b);
|
||||
}
|
||||
|
||||
public Operand Negate(Operand a)
|
||||
{
|
||||
return Add(Instruction.Negate, Local(a.Type), a);
|
||||
}
|
||||
|
||||
public Operand Return()
|
||||
{
|
||||
return Add(Instruction.Return);
|
||||
|
@ -338,6 +333,61 @@ namespace ARMeilleure.Translation
|
|||
Add(Instruction.Store8, null, address, value);
|
||||
}
|
||||
|
||||
public Operand Subtract(Operand a, Operand b)
|
||||
{
|
||||
return Add(Instruction.Subtract, Local(a.Type), a, b);
|
||||
}
|
||||
|
||||
public Operand VectorExtract(Operand vector, Operand value, int index)
|
||||
{
|
||||
return Add(Instruction.VectorExtract, value, vector, Const(index));
|
||||
}
|
||||
|
||||
public Operand VectorExtract16(Operand vector, Operand value, int index)
|
||||
{
|
||||
return Add(Instruction.VectorExtract16, value, vector, Const(index));
|
||||
}
|
||||
|
||||
public Operand VectorExtract8(Operand vector, Operand value, int index)
|
||||
{
|
||||
return Add(Instruction.VectorExtract8, value, vector, Const(index));
|
||||
}
|
||||
|
||||
public Operand VectorInsert(Operand vector, Operand value, int index)
|
||||
{
|
||||
return Add(Instruction.VectorInsert, Local(OperandType.V128), vector, value, Const(index));
|
||||
}
|
||||
|
||||
public Operand VectorInsert16(Operand vector, Operand value, int index)
|
||||
{
|
||||
return Add(Instruction.VectorInsert16, Local(OperandType.V128), vector, value, Const(index));
|
||||
}
|
||||
|
||||
public Operand VectorInsert8(Operand vector, Operand value, int index)
|
||||
{
|
||||
return Add(Instruction.VectorInsert8, Local(OperandType.V128), vector, value, Const(index));
|
||||
}
|
||||
|
||||
public Operand VectorZero()
|
||||
{
|
||||
return Add(Instruction.VectorZero, Local(OperandType.V128));
|
||||
}
|
||||
|
||||
public Operand VectorZeroUpper64(Operand vector)
|
||||
{
|
||||
return Add(Instruction.VectorZeroUpper64, Local(OperandType.V128), vector);
|
||||
}
|
||||
|
||||
public Operand VectorZeroUpper96(Operand vector)
|
||||
{
|
||||
return Add(Instruction.VectorZeroUpper96, Local(OperandType.V128), vector);
|
||||
}
|
||||
|
||||
public Operand AddIntrinsic(Instruction inst, params Operand[] args)
|
||||
{
|
||||
return Add(inst, Local(OperandType.V128), args);
|
||||
}
|
||||
|
||||
private Operand Add(Instruction inst, Operand dest = null, params Operand[] sources)
|
||||
{
|
||||
if (_needsNewBlock)
|
||||
|
|
|
@ -41,8 +41,6 @@ namespace ARMeilleure.Translation
|
|||
|
||||
private TranslatedFunction Translate(ulong address, ExecutionMode mode)
|
||||
{
|
||||
Logger logger = new Logger();
|
||||
|
||||
EmitterContext context = new EmitterContext();
|
||||
|
||||
Block[] blocks = Decoder.DecodeFunction(_memory, address, ExecutionMode.Aarch64);
|
||||
|
@ -55,11 +53,11 @@ namespace ARMeilleure.Translation
|
|||
|
||||
Dominance.FindDominanceFrontiers(cfg);
|
||||
|
||||
logger.StartPass(PassName.SsaConstruction);
|
||||
Logger.StartPass(PassName.SsaConstruction);
|
||||
|
||||
Ssa.Rename(cfg);
|
||||
|
||||
logger.EndPass(PassName.SsaConstruction, cfg);
|
||||
Logger.EndPass(PassName.SsaConstruction, cfg);
|
||||
|
||||
byte[] code = CodeGenerator.Generate(cfg, _memory);
|
||||
|
||||
|
|
|
@ -7,6 +7,46 @@ namespace Ryujinx.Tests.Unicorn
|
|||
private ulong _e0;
|
||||
private ulong _e1;
|
||||
|
||||
public SimdValue(float value) : this(value, value, value, value) { }
|
||||
|
||||
public SimdValue(double value) : this(value, value) { }
|
||||
|
||||
public SimdValue(float e0, float e1, float e2, float e3)
|
||||
{
|
||||
_e0 = (ulong)(uint)BitConverter.SingleToInt32Bits(e0) << 0;
|
||||
_e0 |= (ulong)(uint)BitConverter.SingleToInt32Bits(e1) << 32;
|
||||
_e1 = (ulong)(uint)BitConverter.SingleToInt32Bits(e2) << 0;
|
||||
_e1 |= (ulong)(uint)BitConverter.SingleToInt32Bits(e3) << 32;
|
||||
}
|
||||
|
||||
public SimdValue(double e0, double e1)
|
||||
{
|
||||
_e0 = (ulong)BitConverter.DoubleToInt64Bits(e0);
|
||||
_e1 = (ulong)BitConverter.DoubleToInt64Bits(e1);
|
||||
}
|
||||
|
||||
public SimdValue(int e0, int e1, int e2, int e3)
|
||||
{
|
||||
_e0 = (ulong)(uint)e0 << 0;
|
||||
_e0 |= (ulong)(uint)e1 << 32;
|
||||
_e1 = (ulong)(uint)e2 << 0;
|
||||
_e1 |= (ulong)(uint)e3 << 32;
|
||||
}
|
||||
|
||||
public SimdValue(uint e0, uint e1, uint e2, uint e3)
|
||||
{
|
||||
_e0 = (ulong)e0 << 0;
|
||||
_e0 |= (ulong)e1 << 32;
|
||||
_e1 = (ulong)e2 << 0;
|
||||
_e1 |= (ulong)e3 << 32;
|
||||
}
|
||||
|
||||
public SimdValue(long e0, long e1)
|
||||
{
|
||||
_e0 = (ulong)e0;
|
||||
_e1 = (ulong)e1;
|
||||
}
|
||||
|
||||
public SimdValue(ulong e0, ulong e1)
|
||||
{
|
||||
_e0 = e0;
|
||||
|
@ -19,19 +59,6 @@ namespace Ryujinx.Tests.Unicorn
|
|||
_e1 = (ulong)BitConverter.ToInt64(data, 8);
|
||||
}
|
||||
|
||||
public byte[] ToArray()
|
||||
{
|
||||
byte[] e0Data = BitConverter.GetBytes(_e0);
|
||||
byte[] e1Data = BitConverter.GetBytes(_e1);
|
||||
|
||||
byte[] data = new byte[16];
|
||||
|
||||
Buffer.BlockCopy(e0Data, 0, data, 0, 8);
|
||||
Buffer.BlockCopy(e1Data, 0, data, 8, 8);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public float AsFloat()
|
||||
{
|
||||
return GetFloat(0);
|
||||
|
@ -52,7 +79,8 @@ namespace Ryujinx.Tests.Unicorn
|
|||
return BitConverter.Int64BitsToDouble(GetInt64(index));
|
||||
}
|
||||
|
||||
public int GetInt32(int index) => (int)GetUInt32(index);
|
||||
public int GetInt32(int index) => (int)GetUInt32(index);
|
||||
public long GetInt64(int index) => (long)GetUInt64(index);
|
||||
|
||||
public uint GetUInt32(int index)
|
||||
{
|
||||
|
@ -61,11 +89,9 @@ namespace Ryujinx.Tests.Unicorn
|
|||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
|
||||
return (uint)((((index & 2) != 0) ? _e1 : _e0) >> (index & 1));
|
||||
return (uint)(GetUInt64(index >> 1) >> (index & 1));
|
||||
}
|
||||
|
||||
public long GetInt64(int index) => (long)GetUInt64(index);
|
||||
|
||||
public ulong GetUInt64(int index)
|
||||
{
|
||||
switch (index)
|
||||
|
@ -77,6 +103,19 @@ namespace Ryujinx.Tests.Unicorn
|
|||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
|
||||
public byte[] ToArray()
|
||||
{
|
||||
byte[] e0Data = BitConverter.GetBytes(_e0);
|
||||
byte[] e1Data = BitConverter.GetBytes(_e1);
|
||||
|
||||
byte[] data = new byte[16];
|
||||
|
||||
Buffer.BlockCopy(e0Data, 0, data, 0, 8);
|
||||
Buffer.BlockCopy(e1Data, 0, data, 8, 8);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(_e0, _e1);
|
||||
|
@ -94,12 +133,17 @@ namespace Ryujinx.Tests.Unicorn
|
|||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is SimdValue simdValue && Equals(simdValue);
|
||||
return obj is SimdValue vector && Equals(vector);
|
||||
}
|
||||
|
||||
public bool Equals(SimdValue other)
|
||||
{
|
||||
return other._e0 == _e0 && other._e1 == _e1;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"0x{_e1:X16}{_e0:X16}";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -135,8 +135,8 @@ namespace Ryujinx.Tests.Cpu
|
|||
_context.SetPstateFlag(PState.ZFlag, zero);
|
||||
_context.SetPstateFlag(PState.NFlag, negative);
|
||||
|
||||
//_thread.ThreadState.Fpcr = fpcr;
|
||||
//_thread.ThreadState.Fpsr = fpsr;
|
||||
_context.Fpcr = (FPCR)fpcr;
|
||||
_context.Fpsr = (FPSR)fpsr;
|
||||
|
||||
if (_unicornAvailable)
|
||||
{
|
||||
|
@ -361,8 +361,8 @@ namespace Ryujinx.Tests.Cpu
|
|||
Assert.That(V128ToSimdValue(_context.GetV(30)), Is.EqualTo(_unicornEmu.Q[30]));
|
||||
Assert.That(V128ToSimdValue(_context.GetV(31)), Is.EqualTo(_unicornEmu.Q[31]));
|
||||
|
||||
//Assert.That(_thread.ThreadState.Fpcr, Is.EqualTo(_unicornEmu.Fpcr));
|
||||
//Assert.That(_thread.ThreadState.Fpsr & (int)fpsrMask, Is.EqualTo(_unicornEmu.Fpsr & (int)fpsrMask));
|
||||
Assert.That((int)_context.Fpcr, Is.EqualTo(_unicornEmu.Fpcr));
|
||||
Assert.That((int)_context.Fpsr & (int)fpsrMask, Is.EqualTo(_unicornEmu.Fpsr & (int)fpsrMask));
|
||||
|
||||
Assert.That(_context.GetPstateFlag(PState.VFlag), Is.EqualTo(_unicornEmu.OverflowFlag));
|
||||
Assert.That(_context.GetPstateFlag(PState.CFlag), Is.EqualTo(_unicornEmu.CarryFlag));
|
||||
|
|
|
@ -190,7 +190,7 @@ namespace Ryujinx.Tests.Cpu
|
|||
Opcode(0xD65F03C0);
|
||||
ExecuteOpcodes();
|
||||
|
||||
Assert.That(GetVectorE0(GetContext().GetV(0)), Is.EqualTo(16f));
|
||||
Assert.That(GetContext().GetV(0).AsFloat(), Is.EqualTo(16f));
|
||||
}
|
||||
|
||||
[Explicit]
|
||||
|
|
Loading…
Add table
Reference in a new issue