Compare commits
66 Commits
Author | SHA1 | Date | |
---|---|---|---|
67cbdc3a6a | |||
131b43170e | |||
730d2f4b9b | |||
f6a7309b14 | |||
472a621589 | |||
311c2661b8 | |||
a92e2028cb | |||
6922862db8 | |||
6592d64751 | |||
8001c832d9 | |||
87919b193c | |||
8de033e60e | |||
90432946ac | |||
9bad71afbf | |||
923089a298 | |||
d9aa15eb24 | |||
12c89a61f9 | |||
f5235fff29 | |||
eba682b767 | |||
b994dafe7a | |||
54421760c3 | |||
88a0e720cb | |||
53cc9e0561 | |||
7defc59b9d | |||
951700fdd8 | |||
eb6430f103 | |||
80a879cb44 | |||
2197f41506 | |||
c8f9292bab | |||
0ec933a615 | |||
2135b6a51a | |||
00e35d9bf6 | |||
6dfb6ccf8c | |||
e87e8b012c | |||
e8f1ca8427 | |||
ad47bd2d4e | |||
a5ff0024fb | |||
f9661a54d2 | |||
66e7fdb871 | |||
2bb9b33da1 | |||
1080f64df9 | |||
c48a75979f | |||
842cb26ba5 | |||
e235d5e7bb | |||
ed0b10c81f | |||
f92650fcff | |||
712361f6e1 | |||
2232e4ae87 | |||
14ce9e1567 | |||
952d013c67 | |||
46c8129bf5 | |||
8cfec5de4b | |||
37b6e081da | |||
3c3bcd82fe | |||
a00c59a46c | |||
1825bd87b4 | |||
62f8ceb60b | |||
1a888ae087 | |||
84d0ca5645 | |||
31b8d413d5 | |||
6e02cac952 | |||
3a3380fa25 | |||
2d252db0a7 | |||
7f8a3541eb | |||
b34de74f81 | |||
5811d121df |
@ -58,7 +58,6 @@ namespace ARMeilleure.CodeGen.Linking
|
|||||||
/// <param name="a">First instance</param>
|
/// <param name="a">First instance</param>
|
||||||
/// <param name="b">Second instance</param>
|
/// <param name="b">Second instance</param>
|
||||||
/// <returns><see langword="true"/> if not equal; otherwise <see langword="false"/></returns>
|
/// <returns><see langword="true"/> if not equal; otherwise <see langword="false"/></returns>
|
||||||
/// <inheritdoc/>
|
|
||||||
public static bool operator !=(Symbol a, Symbol b)
|
public static bool operator !=(Symbol a, Symbol b)
|
||||||
{
|
{
|
||||||
return !(a == b);
|
return !(a == b);
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
using ARMeilleure.Common;
|
|
||||||
using ARMeilleure.IntermediateRepresentation;
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace ARMeilleure.CodeGen.RegisterAllocators
|
namespace ARMeilleure.CodeGen.RegisterAllocators
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,11 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
{
|
{
|
||||||
partial class Assembler
|
partial class Assembler
|
||||||
{
|
{
|
||||||
|
public static bool SupportsVexPrefix(X86Instruction inst)
|
||||||
|
{
|
||||||
|
return _instTable[(int)inst].Flags.HasFlag(InstructionFlags.Vex);
|
||||||
|
}
|
||||||
|
|
||||||
private const int BadOp = 0;
|
private const int BadOp = 0;
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
@ -152,6 +157,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Add(X86Instruction.Paddd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000ffe, InstructionFlags.Vex | InstructionFlags.Prefix66));
|
Add(X86Instruction.Paddd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000ffe, InstructionFlags.Vex | InstructionFlags.Prefix66));
|
||||||
Add(X86Instruction.Paddq, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000fd4, InstructionFlags.Vex | InstructionFlags.Prefix66));
|
Add(X86Instruction.Paddq, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000fd4, InstructionFlags.Vex | InstructionFlags.Prefix66));
|
||||||
Add(X86Instruction.Paddw, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000ffd, InstructionFlags.Vex | InstructionFlags.Prefix66));
|
Add(X86Instruction.Paddw, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000ffd, InstructionFlags.Vex | InstructionFlags.Prefix66));
|
||||||
|
Add(X86Instruction.Palignr, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x000f3a0f, InstructionFlags.Vex | InstructionFlags.Prefix66));
|
||||||
Add(X86Instruction.Pand, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000fdb, InstructionFlags.Vex | InstructionFlags.Prefix66));
|
Add(X86Instruction.Pand, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000fdb, InstructionFlags.Vex | InstructionFlags.Prefix66));
|
||||||
Add(X86Instruction.Pandn, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000fdf, InstructionFlags.Vex | InstructionFlags.Prefix66));
|
Add(X86Instruction.Pandn, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000fdf, InstructionFlags.Vex | InstructionFlags.Prefix66));
|
||||||
Add(X86Instruction.Pavgb, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000fe0, InstructionFlags.Vex | InstructionFlags.Prefix66));
|
Add(X86Instruction.Pavgb, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000fe0, InstructionFlags.Vex | InstructionFlags.Prefix66));
|
||||||
@ -234,6 +240,9 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Add(X86Instruction.Rsqrtss, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f52, InstructionFlags.Vex | InstructionFlags.PrefixF3));
|
Add(X86Instruction.Rsqrtss, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f52, InstructionFlags.Vex | InstructionFlags.PrefixF3));
|
||||||
Add(X86Instruction.Sar, new InstructionInfo(0x070000d3, 0x070000c1, BadOp, BadOp, BadOp, InstructionFlags.None));
|
Add(X86Instruction.Sar, new InstructionInfo(0x070000d3, 0x070000c1, BadOp, BadOp, BadOp, InstructionFlags.None));
|
||||||
Add(X86Instruction.Setcc, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f90, InstructionFlags.Reg8Dest));
|
Add(X86Instruction.Setcc, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f90, InstructionFlags.Reg8Dest));
|
||||||
|
Add(X86Instruction.Sha256Msg1, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x000f38cc, InstructionFlags.None));
|
||||||
|
Add(X86Instruction.Sha256Msg2, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x000f38cd, InstructionFlags.None));
|
||||||
|
Add(X86Instruction.Sha256Rnds2, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x000f38cb, InstructionFlags.None));
|
||||||
Add(X86Instruction.Shl, new InstructionInfo(0x040000d3, 0x040000c1, BadOp, BadOp, BadOp, InstructionFlags.None));
|
Add(X86Instruction.Shl, new InstructionInfo(0x040000d3, 0x040000c1, BadOp, BadOp, BadOp, InstructionFlags.None));
|
||||||
Add(X86Instruction.Shr, new InstructionInfo(0x050000d3, 0x050000c1, BadOp, BadOp, BadOp, InstructionFlags.None));
|
Add(X86Instruction.Shr, new InstructionInfo(0x050000d3, 0x050000c1, BadOp, BadOp, BadOp, InstructionFlags.None));
|
||||||
Add(X86Instruction.Shufpd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000fc6, InstructionFlags.Vex | InstructionFlags.Prefix66));
|
Add(X86Instruction.Shufpd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000fc6, InstructionFlags.Vex | InstructionFlags.Prefix66));
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace ARMeilleure.CodeGen.X86
|
namespace ARMeilleure.CodeGen.X86
|
||||||
{
|
{
|
||||||
|
@ -12,21 +12,28 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
(_, _, int ecx, int edx) = X86Base.CpuId(0x00000001, 0x00000000);
|
(int maxNum, _, _, _) = X86Base.CpuId(0x00000000, 0x00000000);
|
||||||
|
|
||||||
FeatureInfoEdx = (FeatureFlagsEdx)edx;
|
(_, _, int ecx1, int edx1) = X86Base.CpuId(0x00000001, 0x00000000);
|
||||||
FeatureInfoEcx = (FeatureFlagsEcx)ecx;
|
FeatureInfo1Edx = (FeatureFlags1Edx)edx1;
|
||||||
|
FeatureInfo1Ecx = (FeatureFlags1Ecx)ecx1;
|
||||||
|
|
||||||
|
if (maxNum >= 7)
|
||||||
|
{
|
||||||
|
(_, int ebx7, _, _) = X86Base.CpuId(0x00000007, 0x00000000);
|
||||||
|
FeatureInfo7Ebx = (FeatureFlags7Ebx)ebx7;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum FeatureFlagsEdx
|
public enum FeatureFlags1Edx
|
||||||
{
|
{
|
||||||
Sse = 1 << 25,
|
Sse = 1 << 25,
|
||||||
Sse2 = 1 << 26
|
Sse2 = 1 << 26
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum FeatureFlagsEcx
|
public enum FeatureFlags1Ecx
|
||||||
{
|
{
|
||||||
Sse3 = 1 << 0,
|
Sse3 = 1 << 0,
|
||||||
Pclmulqdq = 1 << 1,
|
Pclmulqdq = 1 << 1,
|
||||||
@ -40,21 +47,31 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
F16c = 1 << 29
|
F16c = 1 << 29
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FeatureFlagsEdx FeatureInfoEdx { get; }
|
[Flags]
|
||||||
public static FeatureFlagsEcx FeatureInfoEcx { get; }
|
public enum FeatureFlags7Ebx
|
||||||
|
{
|
||||||
|
Avx2 = 1 << 5,
|
||||||
|
Sha = 1 << 29
|
||||||
|
}
|
||||||
|
|
||||||
public static bool SupportsSse => FeatureInfoEdx.HasFlag(FeatureFlagsEdx.Sse);
|
public static FeatureFlags1Edx FeatureInfo1Edx { get; }
|
||||||
public static bool SupportsSse2 => FeatureInfoEdx.HasFlag(FeatureFlagsEdx.Sse2);
|
public static FeatureFlags1Ecx FeatureInfo1Ecx { get; }
|
||||||
public static bool SupportsSse3 => FeatureInfoEcx.HasFlag(FeatureFlagsEcx.Sse3);
|
public static FeatureFlags7Ebx FeatureInfo7Ebx { get; } = 0;
|
||||||
public static bool SupportsPclmulqdq => FeatureInfoEcx.HasFlag(FeatureFlagsEcx.Pclmulqdq);
|
|
||||||
public static bool SupportsSsse3 => FeatureInfoEcx.HasFlag(FeatureFlagsEcx.Ssse3);
|
public static bool SupportsSse => FeatureInfo1Edx.HasFlag(FeatureFlags1Edx.Sse);
|
||||||
public static bool SupportsFma => FeatureInfoEcx.HasFlag(FeatureFlagsEcx.Fma);
|
public static bool SupportsSse2 => FeatureInfo1Edx.HasFlag(FeatureFlags1Edx.Sse2);
|
||||||
public static bool SupportsSse41 => FeatureInfoEcx.HasFlag(FeatureFlagsEcx.Sse41);
|
public static bool SupportsSse3 => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Sse3);
|
||||||
public static bool SupportsSse42 => FeatureInfoEcx.HasFlag(FeatureFlagsEcx.Sse42);
|
public static bool SupportsPclmulqdq => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Pclmulqdq);
|
||||||
public static bool SupportsPopcnt => FeatureInfoEcx.HasFlag(FeatureFlagsEcx.Popcnt);
|
public static bool SupportsSsse3 => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Ssse3);
|
||||||
public static bool SupportsAesni => FeatureInfoEcx.HasFlag(FeatureFlagsEcx.Aes);
|
public static bool SupportsFma => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Fma);
|
||||||
public static bool SupportsAvx => FeatureInfoEcx.HasFlag(FeatureFlagsEcx.Avx);
|
public static bool SupportsSse41 => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Sse41);
|
||||||
public static bool SupportsF16c => FeatureInfoEcx.HasFlag(FeatureFlagsEcx.F16c);
|
public static bool SupportsSse42 => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Sse42);
|
||||||
|
public static bool SupportsPopcnt => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Popcnt);
|
||||||
|
public static bool SupportsAesni => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Aes);
|
||||||
|
public static bool SupportsAvx => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Avx);
|
||||||
|
public static bool SupportsAvx2 => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Avx2) && SupportsAvx;
|
||||||
|
public static bool SupportsF16c => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.F16c);
|
||||||
|
public static bool SupportsSha => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Sha);
|
||||||
|
|
||||||
public static bool ForceLegacySse { get; set; }
|
public static bool ForceLegacySse { get; set; }
|
||||||
|
|
||||||
|
@ -82,6 +82,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Add(Intrinsic.X86Paddd, new IntrinsicInfo(X86Instruction.Paddd, IntrinsicType.Binary));
|
Add(Intrinsic.X86Paddd, new IntrinsicInfo(X86Instruction.Paddd, IntrinsicType.Binary));
|
||||||
Add(Intrinsic.X86Paddq, new IntrinsicInfo(X86Instruction.Paddq, IntrinsicType.Binary));
|
Add(Intrinsic.X86Paddq, new IntrinsicInfo(X86Instruction.Paddq, IntrinsicType.Binary));
|
||||||
Add(Intrinsic.X86Paddw, new IntrinsicInfo(X86Instruction.Paddw, IntrinsicType.Binary));
|
Add(Intrinsic.X86Paddw, new IntrinsicInfo(X86Instruction.Paddw, IntrinsicType.Binary));
|
||||||
|
Add(Intrinsic.X86Palignr, new IntrinsicInfo(X86Instruction.Palignr, IntrinsicType.TernaryImm));
|
||||||
Add(Intrinsic.X86Pand, new IntrinsicInfo(X86Instruction.Pand, IntrinsicType.Binary));
|
Add(Intrinsic.X86Pand, new IntrinsicInfo(X86Instruction.Pand, IntrinsicType.Binary));
|
||||||
Add(Intrinsic.X86Pandn, new IntrinsicInfo(X86Instruction.Pandn, IntrinsicType.Binary));
|
Add(Intrinsic.X86Pandn, new IntrinsicInfo(X86Instruction.Pandn, IntrinsicType.Binary));
|
||||||
Add(Intrinsic.X86Pavgb, new IntrinsicInfo(X86Instruction.Pavgb, IntrinsicType.Binary));
|
Add(Intrinsic.X86Pavgb, new IntrinsicInfo(X86Instruction.Pavgb, IntrinsicType.Binary));
|
||||||
@ -151,6 +152,9 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Add(Intrinsic.X86Roundss, new IntrinsicInfo(X86Instruction.Roundss, IntrinsicType.BinaryImm));
|
Add(Intrinsic.X86Roundss, new IntrinsicInfo(X86Instruction.Roundss, IntrinsicType.BinaryImm));
|
||||||
Add(Intrinsic.X86Rsqrtps, new IntrinsicInfo(X86Instruction.Rsqrtps, IntrinsicType.Unary));
|
Add(Intrinsic.X86Rsqrtps, new IntrinsicInfo(X86Instruction.Rsqrtps, IntrinsicType.Unary));
|
||||||
Add(Intrinsic.X86Rsqrtss, new IntrinsicInfo(X86Instruction.Rsqrtss, IntrinsicType.Unary));
|
Add(Intrinsic.X86Rsqrtss, new IntrinsicInfo(X86Instruction.Rsqrtss, IntrinsicType.Unary));
|
||||||
|
Add(Intrinsic.X86Sha256Msg1, new IntrinsicInfo(X86Instruction.Sha256Msg1, IntrinsicType.Binary));
|
||||||
|
Add(Intrinsic.X86Sha256Msg2, new IntrinsicInfo(X86Instruction.Sha256Msg2, IntrinsicType.Binary));
|
||||||
|
Add(Intrinsic.X86Sha256Rnds2, new IntrinsicInfo(X86Instruction.Sha256Rnds2, IntrinsicType.Ternary));
|
||||||
Add(Intrinsic.X86Shufpd, new IntrinsicInfo(X86Instruction.Shufpd, IntrinsicType.TernaryImm));
|
Add(Intrinsic.X86Shufpd, new IntrinsicInfo(X86Instruction.Shufpd, IntrinsicType.TernaryImm));
|
||||||
Add(Intrinsic.X86Shufps, new IntrinsicInfo(X86Instruction.Shufps, IntrinsicType.TernaryImm));
|
Add(Intrinsic.X86Shufps, new IntrinsicInfo(X86Instruction.Shufps, IntrinsicType.TernaryImm));
|
||||||
Add(Intrinsic.X86Sqrtpd, new IntrinsicInfo(X86Instruction.Sqrtpd, IntrinsicType.Unary));
|
Add(Intrinsic.X86Sqrtpd, new IntrinsicInfo(X86Instruction.Sqrtpd, IntrinsicType.Unary));
|
||||||
|
@ -308,11 +308,13 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
case Instruction.Extended:
|
case Instruction.Extended:
|
||||||
{
|
{
|
||||||
|
bool isBlend = node.Intrinsic == Intrinsic.X86Blendvpd ||
|
||||||
|
node.Intrinsic == Intrinsic.X86Blendvps ||
|
||||||
|
node.Intrinsic == Intrinsic.X86Pblendvb;
|
||||||
|
|
||||||
// BLENDVPD, BLENDVPS, PBLENDVB last operand is always implied to be XMM0 when VEX is not supported.
|
// BLENDVPD, BLENDVPS, PBLENDVB last operand is always implied to be XMM0 when VEX is not supported.
|
||||||
if ((node.Intrinsic == Intrinsic.X86Blendvpd ||
|
// SHA256RNDS2 always has an implied XMM0 as a last operand.
|
||||||
node.Intrinsic == Intrinsic.X86Blendvps ||
|
if ((isBlend && !HardwareCapabilities.SupportsVexEncoding) || node.Intrinsic == Intrinsic.X86Sha256Rnds2)
|
||||||
node.Intrinsic == Intrinsic.X86Pblendvb) &&
|
|
||||||
!HardwareCapabilities.SupportsVexEncoding)
|
|
||||||
{
|
{
|
||||||
Operand xmm0 = Xmm(X86Register.Xmm0, OperandType.V128);
|
Operand xmm0 = Xmm(X86Register.Xmm0, OperandType.V128);
|
||||||
|
|
||||||
@ -1297,11 +1299,15 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
{
|
{
|
||||||
if (IsIntrinsic(operation.Instruction))
|
if (IsIntrinsic(operation.Instruction))
|
||||||
{
|
{
|
||||||
|
IntrinsicInfo info = IntrinsicTable.GetInfo(operation.Intrinsic);
|
||||||
|
|
||||||
|
bool hasVex = HardwareCapabilities.SupportsVexEncoding && Assembler.SupportsVexPrefix(info.Inst);
|
||||||
|
|
||||||
bool isUnary = operation.SourcesCount < 2;
|
bool isUnary = operation.SourcesCount < 2;
|
||||||
|
|
||||||
bool hasVecDest = operation.Destination != default && operation.Destination.Type == OperandType.V128;
|
bool hasVecDest = operation.Destination != default && operation.Destination.Type == OperandType.V128;
|
||||||
|
|
||||||
return !HardwareCapabilities.SupportsVexEncoding && !isUnary && hasVecDest;
|
return !hasVex && !isUnary && hasVecDest;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -98,6 +98,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Paddd,
|
Paddd,
|
||||||
Paddq,
|
Paddq,
|
||||||
Paddw,
|
Paddw,
|
||||||
|
Palignr,
|
||||||
Pand,
|
Pand,
|
||||||
Pandn,
|
Pandn,
|
||||||
Pavgb,
|
Pavgb,
|
||||||
@ -180,6 +181,9 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Rsqrtss,
|
Rsqrtss,
|
||||||
Sar,
|
Sar,
|
||||||
Setcc,
|
Setcc,
|
||||||
|
Sha256Msg1,
|
||||||
|
Sha256Msg2,
|
||||||
|
Sha256Rnds2,
|
||||||
Shl,
|
Shl,
|
||||||
Shr,
|
Shr,
|
||||||
Shufpd,
|
Shufpd,
|
||||||
|
@ -206,7 +206,7 @@ namespace ARMeilleure.Common
|
|||||||
/// <typeparam name="T">Type of elements</typeparam>
|
/// <typeparam name="T">Type of elements</typeparam>
|
||||||
/// <param name="length">Number of elements</param>
|
/// <param name="length">Number of elements</param>
|
||||||
/// <param name="fill">Fill value</param>
|
/// <param name="fill">Fill value</param>
|
||||||
/// <param name="leaf"><see langword="true"/> if leaf; otherwise <see langword=""="false"/></param>
|
/// <param name="leaf"><see langword="true"/> if leaf; otherwise <see langword="false"/></param>
|
||||||
/// <returns>Allocated block</returns>
|
/// <returns>Allocated block</returns>
|
||||||
private IntPtr Allocate<T>(int length, T fill, bool leaf) where T : unmanaged
|
private IntPtr Allocate<T>(int length, T fill, bool leaf) where T : unmanaged
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace ARMeilleure.Common
|
namespace ARMeilleure.Common
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,9 @@ namespace ARMeilleure.Common
|
|||||||
class Counter<T> : IDisposable where T : unmanaged
|
class Counter<T> : IDisposable where T : unmanaged
|
||||||
{
|
{
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
|
/// <summary>
|
||||||
|
/// Index in the <see cref="EntryTable{T}"/>
|
||||||
|
/// </summary>
|
||||||
private readonly int _index;
|
private readonly int _index;
|
||||||
private readonly EntryTable<T> _countTable;
|
private readonly EntryTable<T> _countTable;
|
||||||
|
|
||||||
@ -17,7 +20,6 @@ namespace ARMeilleure.Common
|
|||||||
/// <see cref="EntryTable{T}"/> instance and index.
|
/// <see cref="EntryTable{T}"/> instance and index.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="countTable"><see cref="EntryTable{T}"/> instance</param>
|
/// <param name="countTable"><see cref="EntryTable{T}"/> instance</param>
|
||||||
/// <param name="index">Index in the <see cref="EntryTable{T}"/></param>
|
|
||||||
/// <exception cref="ArgumentNullException"><paramref name="countTable"/> is <see langword="null"/></exception>
|
/// <exception cref="ArgumentNullException"><paramref name="countTable"/> is <see langword="null"/></exception>
|
||||||
/// <exception cref="ArgumentException"><typeparamref name="T"/> is unsupported</exception>
|
/// <exception cref="ArgumentException"><typeparamref name="T"/> is unsupported</exception>
|
||||||
public Counter(EntryTable<T> countTable)
|
public Counter(EntryTable<T> countTable)
|
||||||
@ -68,7 +70,7 @@ namespace ARMeilleure.Common
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Releases all unmanaged and optionally managed resources used by the <see cref="Counter{T}"/> instance.
|
/// Releases all unmanaged and optionally managed resources used by the <see cref="Counter{T}"/> instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="disposing"><see langword="true"/> to dispose managed resources also; otherwise just unmanaged resouces</param>
|
/// <param name="disposing"><see langword="true"/> to dispose managed resources also; otherwise just unmanaged resources</param>
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (!_disposed)
|
if (!_disposed)
|
||||||
|
8
ARMeilleure/Decoders/IOpCode32MemRsImm.cs
Normal file
8
ARMeilleure/Decoders/IOpCode32MemRsImm.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace ARMeilleure.Decoders
|
||||||
|
{
|
||||||
|
interface IOpCode32MemRsImm : IOpCode32Mem
|
||||||
|
{
|
||||||
|
int Rm { get; }
|
||||||
|
ShiftType ShiftType { get; }
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
|
||||||
namespace ARMeilleure.Decoders
|
namespace ARMeilleure.Decoders
|
||||||
{
|
{
|
||||||
class OpCode32MemMult : OpCode32, IOpCode32MemMult
|
class OpCode32MemMult : OpCode32, IOpCode32MemMult
|
||||||
@ -23,14 +25,7 @@ namespace ARMeilleure.Decoders
|
|||||||
|
|
||||||
RegisterMask = opCode & 0xffff;
|
RegisterMask = opCode & 0xffff;
|
||||||
|
|
||||||
int regsSize = 0;
|
int regsSize = BitOperations.PopCount((uint)RegisterMask) * 4;
|
||||||
|
|
||||||
for (int index = 0; index < 16; index++)
|
|
||||||
{
|
|
||||||
regsSize += (RegisterMask >> index) & 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
regsSize *= 4;
|
|
||||||
|
|
||||||
if (!u)
|
if (!u)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
namespace ARMeilleure.Decoders
|
namespace ARMeilleure.Decoders
|
||||||
{
|
{
|
||||||
class OpCode32MemRsImm : OpCode32Mem
|
class OpCode32MemRsImm : OpCode32Mem, IOpCode32MemRsImm
|
||||||
{
|
{
|
||||||
public int Rm { get; }
|
public int Rm { get; }
|
||||||
public ShiftType ShiftType { get; }
|
public ShiftType ShiftType { get; }
|
||||||
|
16
ARMeilleure/Decoders/OpCode32Mrs.cs
Normal file
16
ARMeilleure/Decoders/OpCode32Mrs.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
namespace ARMeilleure.Decoders
|
||||||
|
{
|
||||||
|
class OpCode32Mrs : OpCode32
|
||||||
|
{
|
||||||
|
public bool R { get; }
|
||||||
|
public int Rd { get; }
|
||||||
|
|
||||||
|
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32Mrs(inst, address, opCode);
|
||||||
|
|
||||||
|
public OpCode32Mrs(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||||
|
{
|
||||||
|
R = ((opCode >> 22) & 1) != 0;
|
||||||
|
Rd = (opCode >> 12) & 0xf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,10 @@
|
|||||||
namespace ARMeilleure.Decoders
|
namespace ARMeilleure.Decoders
|
||||||
{
|
{
|
||||||
class OpCodeT16BImmCmp : OpCodeT16
|
class OpCodeT16BImmCmp : OpCodeT16, IOpCode32BImm
|
||||||
{
|
{
|
||||||
public int Rn { get; }
|
public int Rn { get; }
|
||||||
|
|
||||||
public int Immediate { get; }
|
public long Immediate { get; }
|
||||||
|
|
||||||
public static new OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16BImmCmp(inst, address, opCode);
|
public static new OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16BImmCmp(inst, address, opCode);
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection.Emit;
|
|
||||||
|
|
||||||
namespace ARMeilleure.Decoders
|
namespace ARMeilleure.Decoders
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
using ARMeilleure.Instructions;
|
namespace ARMeilleure.Decoders
|
||||||
|
|
||||||
namespace ARMeilleure.Decoders
|
|
||||||
{
|
{
|
||||||
class OpCodeT32BImm20 : OpCodeT32, IOpCode32BImm
|
class OpCodeT32BImm20 : OpCodeT32, IOpCode32BImm
|
||||||
{
|
{
|
||||||
|
31
ARMeilleure/Decoders/OpCodeT32MemImm8D.cs
Normal file
31
ARMeilleure/Decoders/OpCodeT32MemImm8D.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
namespace ARMeilleure.Decoders
|
||||||
|
{
|
||||||
|
class OpCodeT32MemImm8D : OpCodeT32, IOpCode32Mem
|
||||||
|
{
|
||||||
|
public int Rt { get; }
|
||||||
|
public int Rt2 { get; }
|
||||||
|
public int Rn { get; }
|
||||||
|
public bool WBack { get; }
|
||||||
|
public bool IsLoad { get; }
|
||||||
|
public bool Index { get; }
|
||||||
|
public bool Add { get; }
|
||||||
|
public int Immediate { get; }
|
||||||
|
|
||||||
|
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32MemImm8D(inst, address, opCode);
|
||||||
|
|
||||||
|
public OpCodeT32MemImm8D(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||||
|
{
|
||||||
|
Rt2 = (opCode >> 8) & 0xf;
|
||||||
|
Rt = (opCode >> 12) & 0xf;
|
||||||
|
Rn = (opCode >> 16) & 0xf;
|
||||||
|
|
||||||
|
Index = ((opCode >> 24) & 1) != 0;
|
||||||
|
Add = ((opCode >> 23) & 1) != 0;
|
||||||
|
WBack = ((opCode >> 21) & 1) != 0;
|
||||||
|
|
||||||
|
Immediate = opCode & 0xff;
|
||||||
|
|
||||||
|
IsLoad = ((opCode >> 20) & 1) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
ARMeilleure/Decoders/OpCodeT32MemLdEx.cs
Normal file
24
ARMeilleure/Decoders/OpCodeT32MemLdEx.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
namespace ARMeilleure.Decoders
|
||||||
|
{
|
||||||
|
class OpCodeT32MemLdEx : OpCodeT32, IOpCode32MemEx
|
||||||
|
{
|
||||||
|
public int Rd => 0;
|
||||||
|
public int Rt { get; }
|
||||||
|
public int Rn { get; }
|
||||||
|
|
||||||
|
public bool WBack => false;
|
||||||
|
public bool IsLoad => true;
|
||||||
|
public bool Index => false;
|
||||||
|
public bool Add => false;
|
||||||
|
|
||||||
|
public int Immediate => 0;
|
||||||
|
|
||||||
|
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32MemLdEx(inst, address, opCode);
|
||||||
|
|
||||||
|
public OpCodeT32MemLdEx(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||||
|
{
|
||||||
|
Rt = (opCode >> 12) & 0xf;
|
||||||
|
Rn = (opCode >> 16) & 0xf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
52
ARMeilleure/Decoders/OpCodeT32MemMult.cs
Normal file
52
ARMeilleure/Decoders/OpCodeT32MemMult.cs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Decoders
|
||||||
|
{
|
||||||
|
class OpCodeT32MemMult : OpCodeT32, IOpCode32MemMult
|
||||||
|
{
|
||||||
|
public int Rn { get; }
|
||||||
|
|
||||||
|
public int RegisterMask { get; }
|
||||||
|
public int Offset { get; }
|
||||||
|
public int PostOffset { get; }
|
||||||
|
|
||||||
|
public bool IsLoad { get; }
|
||||||
|
|
||||||
|
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32MemMult(inst, address, opCode);
|
||||||
|
|
||||||
|
public OpCodeT32MemMult(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||||
|
{
|
||||||
|
Rn = (opCode >> 16) & 0xf;
|
||||||
|
|
||||||
|
bool isLoad = (opCode & (1 << 20)) != 0;
|
||||||
|
bool w = (opCode & (1 << 21)) != 0;
|
||||||
|
bool u = (opCode & (1 << 23)) != 0;
|
||||||
|
bool p = (opCode & (1 << 24)) != 0;
|
||||||
|
|
||||||
|
RegisterMask = opCode & 0xffff;
|
||||||
|
|
||||||
|
int regsSize = BitOperations.PopCount((uint)RegisterMask) * 4;
|
||||||
|
|
||||||
|
if (!u)
|
||||||
|
{
|
||||||
|
Offset -= regsSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u == p)
|
||||||
|
{
|
||||||
|
Offset += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (w)
|
||||||
|
{
|
||||||
|
PostOffset = u ? regsSize : -regsSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PostOffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
IsLoad = isLoad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
ARMeilleure/Decoders/OpCodeT32MemRsImm.cs
Normal file
30
ARMeilleure/Decoders/OpCodeT32MemRsImm.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
namespace ARMeilleure.Decoders
|
||||||
|
{
|
||||||
|
class OpCodeT32MemRsImm : OpCodeT32, IOpCode32MemRsImm
|
||||||
|
{
|
||||||
|
public int Rt { get; }
|
||||||
|
public int Rn { get; }
|
||||||
|
public int Rm { get; }
|
||||||
|
public ShiftType ShiftType => ShiftType.Lsl;
|
||||||
|
|
||||||
|
public bool WBack => false;
|
||||||
|
public bool IsLoad { get; }
|
||||||
|
public bool Index => true;
|
||||||
|
public bool Add => true;
|
||||||
|
|
||||||
|
public int Immediate { get; }
|
||||||
|
|
||||||
|
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32MemRsImm(inst, address, opCode);
|
||||||
|
|
||||||
|
public OpCodeT32MemRsImm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||||
|
{
|
||||||
|
Rm = (opCode >> 0) & 0xf;
|
||||||
|
Rt = (opCode >> 12) & 0xf;
|
||||||
|
Rn = (opCode >> 16) & 0xf;
|
||||||
|
|
||||||
|
IsLoad = (opCode & (1 << 20)) != 0;
|
||||||
|
|
||||||
|
Immediate = (opCode >> 4) & 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
ARMeilleure/Decoders/OpCodeT32MemStEx.cs
Normal file
25
ARMeilleure/Decoders/OpCodeT32MemStEx.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
namespace ARMeilleure.Decoders
|
||||||
|
{
|
||||||
|
class OpCodeT32MemStEx : OpCodeT32, IOpCode32MemEx
|
||||||
|
{
|
||||||
|
public int Rd { get; }
|
||||||
|
public int Rt { get; }
|
||||||
|
public int Rn { get; }
|
||||||
|
|
||||||
|
public bool WBack => false;
|
||||||
|
public bool IsLoad => false;
|
||||||
|
public bool Index => false;
|
||||||
|
public bool Add => false;
|
||||||
|
|
||||||
|
public int Immediate => 0;
|
||||||
|
|
||||||
|
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32MemStEx(inst, address, opCode);
|
||||||
|
|
||||||
|
public OpCodeT32MemStEx(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||||
|
{
|
||||||
|
Rd = (opCode >> 0) & 0xf;
|
||||||
|
Rt = (opCode >> 12) & 0xf;
|
||||||
|
Rn = (opCode >> 16) & 0xf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -704,6 +704,7 @@ namespace ARMeilleure.Decoders
|
|||||||
SetA32("<<<<00110100xxxxxxxxxxxxxxxxxxxx", InstName.Movt, InstEmit32.Movt, OpCode32AluImm16.Create);
|
SetA32("<<<<00110100xxxxxxxxxxxxxxxxxxxx", InstName.Movt, InstEmit32.Movt, OpCode32AluImm16.Create);
|
||||||
SetA32("<<<<1110xxx1xxxxxxxx111xxxx1xxxx", InstName.Mrc, InstEmit32.Mrc, OpCode32System.Create);
|
SetA32("<<<<1110xxx1xxxxxxxx111xxxx1xxxx", InstName.Mrc, InstEmit32.Mrc, OpCode32System.Create);
|
||||||
SetA32("<<<<11000101xxxxxxxx111xxxxxxxxx", InstName.Mrrc, InstEmit32.Mrrc, OpCode32System.Create);
|
SetA32("<<<<11000101xxxxxxxx111xxxxxxxxx", InstName.Mrrc, InstEmit32.Mrrc, OpCode32System.Create);
|
||||||
|
SetA32("<<<<00010x001111xxxx000000000000", InstName.Mrs, InstEmit32.Mrs, OpCode32Mrs.Create);
|
||||||
SetA32("<<<<00010x10xxxx111100000000xxxx", InstName.Msr, InstEmit32.Msr, OpCode32MsrReg.Create);
|
SetA32("<<<<00010x10xxxx111100000000xxxx", InstName.Msr, InstEmit32.Msr, OpCode32MsrReg.Create);
|
||||||
SetA32("<<<<0000000xxxxx0000xxxx1001xxxx", InstName.Mul, InstEmit32.Mul, OpCode32AluMla.Create);
|
SetA32("<<<<0000000xxxxx0000xxxx1001xxxx", InstName.Mul, InstEmit32.Mul, OpCode32AluMla.Create);
|
||||||
SetA32("<<<<0011111x0000xxxxxxxxxxxxxxxx", InstName.Mvn, InstEmit32.Mvn, OpCode32AluImm.Create);
|
SetA32("<<<<0011111x0000xxxxxxxxxxxxxxxx", InstName.Mvn, InstEmit32.Mvn, OpCode32AluImm.Create);
|
||||||
@ -792,185 +793,189 @@ namespace ARMeilleure.Decoders
|
|||||||
SetA32("<<<<01101111xxxxxxxxxx000111xxxx", InstName.Uxth, InstEmit32.Uxth, OpCode32AluUx.Create);
|
SetA32("<<<<01101111xxxxxxxxxx000111xxxx", InstName.Uxth, InstEmit32.Uxth, OpCode32AluUx.Create);
|
||||||
|
|
||||||
// FP & SIMD
|
// FP & SIMD
|
||||||
SetA32("111100111x110000xxx0001101x0xxx0", InstName.Aesd_V, InstEmit32.Aesd_V, OpCode32Simd.Create);
|
SetA32("111100111x110000xxx0001101x0xxx0", InstName.Aesd_V, InstEmit32.Aesd_V, OpCode32Simd.Create);
|
||||||
SetA32("111100111x110000xxx0001100x0xxx0", InstName.Aese_V, InstEmit32.Aese_V, OpCode32Simd.Create);
|
SetA32("111100111x110000xxx0001100x0xxx0", InstName.Aese_V, InstEmit32.Aese_V, OpCode32Simd.Create);
|
||||||
SetA32("111100111x110000xxx0001111x0xxx0", InstName.Aesimc_V, InstEmit32.Aesimc_V, OpCode32Simd.Create);
|
SetA32("111100111x110000xxx0001111x0xxx0", InstName.Aesimc_V, InstEmit32.Aesimc_V, OpCode32Simd.Create);
|
||||||
SetA32("111100111x110000xxx0001110x0xxx0", InstName.Aesmc_V, InstEmit32.Aesmc_V, OpCode32Simd.Create);
|
SetA32("111100111x110000xxx0001110x0xxx0", InstName.Aesmc_V, InstEmit32.Aesmc_V, OpCode32Simd.Create);
|
||||||
SetA32("1111001x0x<<xxxxxxxx0111xxx0xxxx", InstName.Vabd, InstEmit32.Vabd_I, OpCode32SimdReg.Create);
|
SetA32("111100110x00xxx0xxx01100x1x0xxx0", InstName.Sha256h_V, InstEmit32.Sha256h_V, OpCode32SimdReg.Create);
|
||||||
SetA32("1111001x1x<<xxxxxxxx0111x0x0xxxx", InstName.Vabdl, InstEmit32.Vabdl_I, OpCode32SimdRegLong.Create);
|
SetA32("111100110x01xxx0xxx01100x1x0xxx0", InstName.Sha256h2_V, InstEmit32.Sha256h2_V, OpCode32SimdReg.Create);
|
||||||
SetA32("<<<<11101x110000xxxx101x11x0xxxx", InstName.Vabs, InstEmit32.Vabs_S, OpCode32SimdS.Create);
|
SetA32("111100111x111010xxx0001111x0xxx0", InstName.Sha256su0_V, InstEmit32.Sha256su0_V, OpCode32Simd.Create);
|
||||||
SetA32("111100111x11<<01xxxx00110xx0xxxx", InstName.Vabs, InstEmit32.Vabs_V, OpCode32SimdCmpZ.Create);
|
SetA32("111100110x10xxx0xxx01100x1x0xxx0", InstName.Sha256su1_V, InstEmit32.Sha256su1_V, OpCode32SimdReg.Create);
|
||||||
SetA32("111100111x111001xxxx01110xx0xxxx", InstName.Vabs, InstEmit32.Vabs_V, OpCode32SimdCmpZ.Create);
|
SetA32("1111001x0x<<xxxxxxxx0111xxx0xxxx", InstName.Vabd, InstEmit32.Vabd_I, OpCode32SimdReg.Create);
|
||||||
SetA32("111100100xxxxxxxxxxx1000xxx0xxxx", InstName.Vadd, InstEmit32.Vadd_I, OpCode32SimdReg.Create);
|
SetA32("1111001x1x<<xxxxxxxx0111x0x0xxxx", InstName.Vabdl, InstEmit32.Vabdl_I, OpCode32SimdRegLong.Create);
|
||||||
SetA32("<<<<11100x11xxxxxxxx101xx0x0xxxx", InstName.Vadd, InstEmit32.Vadd_S, OpCode32SimdRegS.Create);
|
SetA32("<<<<11101x110000xxxx101x11x0xxxx", InstName.Vabs, InstEmit32.Vabs_S, OpCode32SimdS.Create);
|
||||||
SetA32("111100100x00xxxxxxxx1101xxx0xxxx", InstName.Vadd, InstEmit32.Vadd_V, OpCode32SimdReg.Create);
|
SetA32("111100111x11<<01xxxx00110xx0xxxx", InstName.Vabs, InstEmit32.Vabs_V, OpCode32SimdCmpZ.Create);
|
||||||
SetA32("1111001x1x<<xxxxxxxx0000x0x0xxxx", InstName.Vaddl, InstEmit32.Vaddl_I, OpCode32SimdRegLong.Create);
|
SetA32("111100111x111001xxxx01110xx0xxxx", InstName.Vabs, InstEmit32.Vabs_V, OpCode32SimdCmpZ.Create);
|
||||||
SetA32("1111001x1x<<xxxxxxxx0001x0x0xxxx", InstName.Vaddw, InstEmit32.Vaddw_I, OpCode32SimdRegWide.Create);
|
SetA32("111100100xxxxxxxxxxx1000xxx0xxxx", InstName.Vadd, InstEmit32.Vadd_I, OpCode32SimdReg.Create);
|
||||||
SetA32("111100100x00xxxxxxxx0001xxx1xxxx", InstName.Vand, InstEmit32.Vand_I, OpCode32SimdBinary.Create);
|
SetA32("<<<<11100x11xxxxxxxx101xx0x0xxxx", InstName.Vadd, InstEmit32.Vadd_S, OpCode32SimdRegS.Create);
|
||||||
SetA32("111100100x01xxxxxxxx0001xxx1xxxx", InstName.Vbic, InstEmit32.Vbic_I, OpCode32SimdBinary.Create);
|
SetA32("111100100x00xxxxxxxx1101xxx0xxxx", InstName.Vadd, InstEmit32.Vadd_V, OpCode32SimdReg.Create);
|
||||||
SetA32("1111001x1x000xxxxxxx<<x10x11xxxx", InstName.Vbic, InstEmit32.Vbic_II, OpCode32SimdImm.Create);
|
SetA32("1111001x1x<<xxxxxxxx0000x0x0xxxx", InstName.Vaddl, InstEmit32.Vaddl_I, OpCode32SimdRegLong.Create);
|
||||||
SetA32("111100110x11xxxxxxxx0001xxx1xxxx", InstName.Vbif, InstEmit32.Vbif, OpCode32SimdBinary.Create);
|
SetA32("1111001x1x<<xxxxxxxx0001x0x0xxxx", InstName.Vaddw, InstEmit32.Vaddw_I, OpCode32SimdRegWide.Create);
|
||||||
SetA32("111100110x10xxxxxxxx0001xxx1xxxx", InstName.Vbit, InstEmit32.Vbit, OpCode32SimdBinary.Create);
|
SetA32("111100100x00xxxxxxxx0001xxx1xxxx", InstName.Vand, InstEmit32.Vand_I, OpCode32SimdBinary.Create);
|
||||||
SetA32("111100110x01xxxxxxxx0001xxx1xxxx", InstName.Vbsl, InstEmit32.Vbsl, OpCode32SimdBinary.Create);
|
SetA32("111100100x01xxxxxxxx0001xxx1xxxx", InstName.Vbic, InstEmit32.Vbic_I, OpCode32SimdBinary.Create);
|
||||||
SetA32("111100110x<<xxxxxxxx1000xxx1xxxx", InstName.Vceq, InstEmit32.Vceq_I, OpCode32SimdReg.Create);
|
SetA32("1111001x1x000xxxxxxx<<x10x11xxxx", InstName.Vbic, InstEmit32.Vbic_II, OpCode32SimdImm.Create);
|
||||||
SetA32("111100100x00xxxxxxxx1110xxx0xxxx", InstName.Vceq, InstEmit32.Vceq_V, OpCode32SimdReg.Create);
|
SetA32("111100110x11xxxxxxxx0001xxx1xxxx", InstName.Vbif, InstEmit32.Vbif, OpCode32SimdBinary.Create);
|
||||||
SetA32("111100111x11xx01xxxx0x010xx0xxxx", InstName.Vceq, InstEmit32.Vceq_Z, OpCode32SimdCmpZ.Create);
|
SetA32("111100110x10xxxxxxxx0001xxx1xxxx", InstName.Vbit, InstEmit32.Vbit, OpCode32SimdBinary.Create);
|
||||||
SetA32("1111001x0x<<xxxxxxxx0011xxx1xxxx", InstName.Vcge, InstEmit32.Vcge_I, OpCode32SimdReg.Create);
|
SetA32("111100110x01xxxxxxxx0001xxx1xxxx", InstName.Vbsl, InstEmit32.Vbsl, OpCode32SimdBinary.Create);
|
||||||
SetA32("111100110x00xxxxxxxx1110xxx0xxxx", InstName.Vcge, InstEmit32.Vcge_V, OpCode32SimdReg.Create);
|
SetA32("111100110x<<xxxxxxxx1000xxx1xxxx", InstName.Vceq, InstEmit32.Vceq_I, OpCode32SimdReg.Create);
|
||||||
SetA32("111100111x11xx01xxxx0x001xx0xxxx", InstName.Vcge, InstEmit32.Vcge_Z, OpCode32SimdCmpZ.Create);
|
SetA32("111100100x00xxxxxxxx1110xxx0xxxx", InstName.Vceq, InstEmit32.Vceq_V, OpCode32SimdReg.Create);
|
||||||
SetA32("1111001x0x<<xxxxxxxx0011xxx0xxxx", InstName.Vcgt, InstEmit32.Vcgt_I, OpCode32SimdReg.Create);
|
SetA32("111100111x11xx01xxxx0x010xx0xxxx", InstName.Vceq, InstEmit32.Vceq_Z, OpCode32SimdCmpZ.Create);
|
||||||
SetA32("111100110x10xxxxxxxx1110xxx0xxxx", InstName.Vcgt, InstEmit32.Vcgt_V, OpCode32SimdReg.Create);
|
SetA32("1111001x0x<<xxxxxxxx0011xxx1xxxx", InstName.Vcge, InstEmit32.Vcge_I, OpCode32SimdReg.Create);
|
||||||
SetA32("111100111x11xx01xxxx0x000xx0xxxx", InstName.Vcgt, InstEmit32.Vcgt_Z, OpCode32SimdCmpZ.Create);
|
SetA32("111100110x00xxxxxxxx1110xxx0xxxx", InstName.Vcge, InstEmit32.Vcge_V, OpCode32SimdReg.Create);
|
||||||
SetA32("111100111x11xx01xxxx0x011xx0xxxx", InstName.Vcle, InstEmit32.Vcle_Z, OpCode32SimdCmpZ.Create);
|
SetA32("111100111x11xx01xxxx0x001xx0xxxx", InstName.Vcge, InstEmit32.Vcge_Z, OpCode32SimdCmpZ.Create);
|
||||||
SetA32("111100111x11xx01xxxx0x100xx0xxxx", InstName.Vclt, InstEmit32.Vclt_Z, OpCode32SimdCmpZ.Create);
|
SetA32("1111001x0x<<xxxxxxxx0011xxx0xxxx", InstName.Vcgt, InstEmit32.Vcgt_I, OpCode32SimdReg.Create);
|
||||||
SetA32("<<<<11101x11010xxxxx101x01x0xxxx", InstName.Vcmp, InstEmit32.Vcmp, OpCode32SimdS.Create);
|
SetA32("111100110x10xxxxxxxx1110xxx0xxxx", InstName.Vcgt, InstEmit32.Vcgt_V, OpCode32SimdReg.Create);
|
||||||
SetA32("<<<<11101x11010xxxxx101x11x0xxxx", InstName.Vcmpe, InstEmit32.Vcmpe, OpCode32SimdS.Create);
|
SetA32("111100111x11xx01xxxx0x000xx0xxxx", InstName.Vcgt, InstEmit32.Vcgt_Z, OpCode32SimdCmpZ.Create);
|
||||||
SetA32("111100111x110000xxxx01010xx0xxxx", InstName.Vcnt, InstEmit32.Vcnt, OpCode32SimdCmpZ.Create);
|
SetA32("111100111x11xx01xxxx0x011xx0xxxx", InstName.Vcle, InstEmit32.Vcle_Z, OpCode32SimdCmpZ.Create);
|
||||||
SetA32("<<<<11101x110111xxxx101x11x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FD, OpCode32SimdS.Create); // FP 32 and 64, scalar.
|
SetA32("111100111x11xx01xxxx0x100xx0xxxx", InstName.Vclt, InstEmit32.Vclt_Z, OpCode32SimdCmpZ.Create);
|
||||||
SetA32("<<<<11101x11110xxxxx101x11x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FI, OpCode32SimdCvtFI.Create); // FP32 to int.
|
SetA32("<<<<11101x11010xxxxx101x01x0xxxx", InstName.Vcmp, InstEmit32.Vcmp, OpCode32SimdS.Create);
|
||||||
SetA32("<<<<11101x111000xxxx101xx1x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FI, OpCode32SimdCvtFI.Create); // Int to FP32.
|
SetA32("<<<<11101x11010xxxxx101x11x0xxxx", InstName.Vcmpe, InstEmit32.Vcmpe, OpCode32SimdS.Create);
|
||||||
SetA32("111111101x1111xxxxxx101xx1x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_RM, OpCode32SimdCvtFI.Create); // The many FP32 to int encodings (fp).
|
SetA32("111100111x110000xxxx01010xx0xxxx", InstName.Vcnt, InstEmit32.Vcnt, OpCode32SimdCmpZ.Create);
|
||||||
SetA32("111100111x111011xxxx011xxxx0xxxx", InstName.Vcvt, InstEmit32.Vcvt_V, OpCode32SimdCmpZ.Create); // FP and integer, vector.
|
SetA32("<<<<11101x110111xxxx101x11x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FD, OpCode32SimdS.Create); // FP 32 and 64, scalar.
|
||||||
SetA32("<<<<11101x00xxxxxxxx101xx0x0xxxx", InstName.Vdiv, InstEmit32.Vdiv_S, OpCode32SimdRegS.Create);
|
SetA32("<<<<11101x11110xxxxx101x11x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FI, OpCode32SimdCvtFI.Create); // FP32 to int.
|
||||||
SetA32("<<<<11101xx0xxxxxxxx1011x0x10000", InstName.Vdup, InstEmit32.Vdup, OpCode32SimdDupGP.Create);
|
SetA32("<<<<11101x111000xxxx101xx1x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FI, OpCode32SimdCvtFI.Create); // Int to FP32.
|
||||||
SetA32("111100111x11xxxxxxxx11000xx0xxxx", InstName.Vdup, InstEmit32.Vdup_1, OpCode32SimdDupElem.Create);
|
SetA32("111111101x1111xxxxxx101xx1x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_RM, OpCode32SimdCvtFI.Create); // The many FP32 to int encodings (fp).
|
||||||
SetA32("111100110x00xxxxxxxx0001xxx1xxxx", InstName.Veor, InstEmit32.Veor_I, OpCode32SimdBinary.Create);
|
SetA32("111100111x111011xxxx011xxxx0xxxx", InstName.Vcvt, InstEmit32.Vcvt_V, OpCode32SimdCmpZ.Create); // FP and integer, vector.
|
||||||
SetA32("111100101x11xxxxxxxxxxxxxxx0xxxx", InstName.Vext, InstEmit32.Vext, OpCode32SimdExt.Create);
|
SetA32("<<<<11101x00xxxxxxxx101xx0x0xxxx", InstName.Vdiv, InstEmit32.Vdiv_S, OpCode32SimdRegS.Create);
|
||||||
SetA32("<<<<11101x10xxxxxxxx101xx0x0xxxx", InstName.Vfma, InstEmit32.Vfma_S, OpCode32SimdRegS.Create);
|
SetA32("<<<<11101xx0xxxxxxxx1011x0x10000", InstName.Vdup, InstEmit32.Vdup, OpCode32SimdDupGP.Create);
|
||||||
SetA32("111100100x00xxxxxxxx1100xxx1xxxx", InstName.Vfma, InstEmit32.Vfma_V, OpCode32SimdReg.Create);
|
SetA32("111100111x11xxxxxxxx11000xx0xxxx", InstName.Vdup, InstEmit32.Vdup_1, OpCode32SimdDupElem.Create);
|
||||||
SetA32("<<<<11101x10xxxxxxxx101xx1x0xxxx", InstName.Vfms, InstEmit32.Vfms_S, OpCode32SimdRegS.Create);
|
SetA32("111100110x00xxxxxxxx0001xxx1xxxx", InstName.Veor, InstEmit32.Veor_I, OpCode32SimdBinary.Create);
|
||||||
SetA32("111100100x10xxxxxxxx1100xxx1xxxx", InstName.Vfms, InstEmit32.Vfms_V, OpCode32SimdReg.Create);
|
SetA32("111100101x11xxxxxxxxxxxxxxx0xxxx", InstName.Vext, InstEmit32.Vext, OpCode32SimdExt.Create);
|
||||||
SetA32("<<<<11101x01xxxxxxxx101xx1x0xxxx", InstName.Vfnma, InstEmit32.Vfnma_S, OpCode32SimdRegS.Create);
|
SetA32("<<<<11101x10xxxxxxxx101xx0x0xxxx", InstName.Vfma, InstEmit32.Vfma_S, OpCode32SimdRegS.Create);
|
||||||
SetA32("<<<<11101x01xxxxxxxx101xx0x0xxxx", InstName.Vfnms, InstEmit32.Vfnms_S, OpCode32SimdRegS.Create);
|
SetA32("111100100x00xxxxxxxx1100xxx1xxxx", InstName.Vfma, InstEmit32.Vfma_V, OpCode32SimdReg.Create);
|
||||||
SetA32("1111001x0x<<xxxxxxxx0000xxx0xxxx", InstName.Vhadd, InstEmit32.Vhadd, OpCode32SimdReg.Create);
|
SetA32("<<<<11101x10xxxxxxxx101xx1x0xxxx", InstName.Vfms, InstEmit32.Vfms_S, OpCode32SimdRegS.Create);
|
||||||
SetA32("111101001x10xxxxxxxxxx00xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, OpCode32SimdMemSingle.Create);
|
SetA32("111100100x10xxxxxxxx1100xxx1xxxx", InstName.Vfms, InstEmit32.Vfms_V, OpCode32SimdReg.Create);
|
||||||
SetA32("111101000x10xxxxxxxx0111xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, OpCode32SimdMemPair.Create); // Regs = 1.
|
SetA32("<<<<11101x01xxxxxxxx101xx1x0xxxx", InstName.Vfnma, InstEmit32.Vfnma_S, OpCode32SimdRegS.Create);
|
||||||
SetA32("111101000x10xxxxxxxx1010xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, OpCode32SimdMemPair.Create); // Regs = 2.
|
SetA32("<<<<11101x01xxxxxxxx101xx0x0xxxx", InstName.Vfnms, InstEmit32.Vfnms_S, OpCode32SimdRegS.Create);
|
||||||
SetA32("111101000x10xxxxxxxx0110xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, OpCode32SimdMemPair.Create); // Regs = 3.
|
SetA32("1111001x0x<<xxxxxxxx0000xxx0xxxx", InstName.Vhadd, InstEmit32.Vhadd, OpCode32SimdReg.Create);
|
||||||
SetA32("111101000x10xxxxxxxx0010xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, OpCode32SimdMemPair.Create); // Regs = 4.
|
SetA32("111101001x10xxxxxxxxxx00xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, OpCode32SimdMemSingle.Create);
|
||||||
SetA32("111101001x10xxxxxxxxxx01xxxxxxxx", InstName.Vld2, InstEmit32.Vld2, OpCode32SimdMemSingle.Create);
|
SetA32("111101000x10xxxxxxxx0111xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, OpCode32SimdMemPair.Create); // Regs = 1.
|
||||||
SetA32("111101000x10xxxxxxxx100xxxxxxxxx", InstName.Vld2, InstEmit32.Vld2, OpCode32SimdMemPair.Create); // Regs = 1, inc = 1/2 (itype).
|
SetA32("111101000x10xxxxxxxx1010xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, OpCode32SimdMemPair.Create); // Regs = 2.
|
||||||
SetA32("111101000x10xxxxxxxx0011xxxxxxxx", InstName.Vld2, InstEmit32.Vld2, OpCode32SimdMemPair.Create); // Regs = 2, inc = 2.
|
SetA32("111101000x10xxxxxxxx0110xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, OpCode32SimdMemPair.Create); // Regs = 3.
|
||||||
SetA32("111101001x10xxxxxxxxxx10xxxxxxxx", InstName.Vld3, InstEmit32.Vld3, OpCode32SimdMemSingle.Create);
|
SetA32("111101000x10xxxxxxxx0010xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, OpCode32SimdMemPair.Create); // Regs = 4.
|
||||||
SetA32("111101000x10xxxxxxxx010xxxxxxxxx", InstName.Vld3, InstEmit32.Vld3, OpCode32SimdMemPair.Create); // Inc = 1/2 (itype).
|
SetA32("111101001x10xxxxxxxxxx01xxxxxxxx", InstName.Vld2, InstEmit32.Vld2, OpCode32SimdMemSingle.Create);
|
||||||
SetA32("111101001x10xxxxxxxxxx11xxxxxxxx", InstName.Vld4, InstEmit32.Vld4, OpCode32SimdMemSingle.Create);
|
SetA32("111101000x10xxxxxxxx100xxxxxxxxx", InstName.Vld2, InstEmit32.Vld2, OpCode32SimdMemPair.Create); // Regs = 1, inc = 1/2 (itype).
|
||||||
SetA32("111101000x10xxxxxxxx000xxxxxxxxx", InstName.Vld4, InstEmit32.Vld4, OpCode32SimdMemPair.Create); // Inc = 1/2 (itype).
|
SetA32("111101000x10xxxxxxxx0011xxxxxxxx", InstName.Vld2, InstEmit32.Vld2, OpCode32SimdMemPair.Create); // Regs = 2, inc = 2.
|
||||||
SetA32("<<<<11001x01xxxxxxxx1011xxxxxxx0", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create);
|
SetA32("111101001x10xxxxxxxxxx10xxxxxxxx", InstName.Vld3, InstEmit32.Vld3, OpCode32SimdMemSingle.Create);
|
||||||
SetA32("<<<<11001x11xxxxxxxx1011xxxxxxx0", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create);
|
SetA32("111101000x10xxxxxxxx010xxxxxxxxx", InstName.Vld3, InstEmit32.Vld3, OpCode32SimdMemPair.Create); // Inc = 1/2 (itype).
|
||||||
SetA32("<<<<11010x11xxxxxxxx1011xxxxxxx0", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create);
|
SetA32("111101001x10xxxxxxxxxx11xxxxxxxx", InstName.Vld4, InstEmit32.Vld4, OpCode32SimdMemSingle.Create);
|
||||||
SetA32("<<<<11001x01xxxxxxxx1010xxxxxxxx", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create);
|
SetA32("111101000x10xxxxxxxx000xxxxxxxxx", InstName.Vld4, InstEmit32.Vld4, OpCode32SimdMemPair.Create); // Inc = 1/2 (itype).
|
||||||
SetA32("<<<<11001x11xxxxxxxx1010xxxxxxxx", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create);
|
SetA32("<<<<11001x01xxxxxxxx1011xxxxxxx0", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create);
|
||||||
SetA32("<<<<11010x11xxxxxxxx1010xxxxxxxx", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create);
|
SetA32("<<<<11001x11xxxxxxxx1011xxxxxxx0", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create);
|
||||||
SetA32("<<<<1101xx01xxxxxxxx101xxxxxxxxx", InstName.Vldr, InstEmit32.Vldr, OpCode32SimdMemImm.Create);
|
SetA32("<<<<11010x11xxxxxxxx1011xxxxxxx0", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create);
|
||||||
SetA32("1111001x0x<<xxxxxxxx0110xxx0xxxx", InstName.Vmax, InstEmit32.Vmax_I, OpCode32SimdReg.Create);
|
SetA32("<<<<11001x01xxxxxxxx1010xxxxxxxx", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create);
|
||||||
SetA32("111100100x00xxxxxxxx1111xxx0xxxx", InstName.Vmax, InstEmit32.Vmax_V, OpCode32SimdReg.Create);
|
SetA32("<<<<11001x11xxxxxxxx1010xxxxxxxx", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create);
|
||||||
SetA32("1111001x0x<<xxxxxxxx0110xxx1xxxx", InstName.Vmin, InstEmit32.Vmin_I, OpCode32SimdReg.Create);
|
SetA32("<<<<11010x11xxxxxxxx1010xxxxxxxx", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create);
|
||||||
SetA32("111100100x10xxxxxxxx1111xxx0xxxx", InstName.Vmin, InstEmit32.Vmin_V, OpCode32SimdReg.Create);
|
SetA32("<<<<1101xx01xxxxxxxx101xxxxxxxxx", InstName.Vldr, InstEmit32.Vldr, OpCode32SimdMemImm.Create);
|
||||||
SetA32("111111101x00xxxxxxxx10>>x0x0xxxx", InstName.Vmaxnm, InstEmit32.Vmaxnm_S, OpCode32SimdRegS.Create);
|
SetA32("1111001x0x<<xxxxxxxx0110xxx0xxxx", InstName.Vmax, InstEmit32.Vmax_I, OpCode32SimdReg.Create);
|
||||||
SetA32("111100110x0xxxxxxxxx1111xxx1xxxx", InstName.Vmaxnm, InstEmit32.Vmaxnm_V, OpCode32SimdReg.Create);
|
SetA32("111100100x00xxxxxxxx1111xxx0xxxx", InstName.Vmax, InstEmit32.Vmax_V, OpCode32SimdReg.Create);
|
||||||
SetA32("111111101x00xxxxxxxx10>>x1x0xxxx", InstName.Vminnm, InstEmit32.Vminnm_S, OpCode32SimdRegS.Create);
|
SetA32("1111001x0x<<xxxxxxxx0110xxx1xxxx", InstName.Vmin, InstEmit32.Vmin_I, OpCode32SimdReg.Create);
|
||||||
SetA32("111100110x1xxxxxxxxx1111xxx1xxxx", InstName.Vminnm, InstEmit32.Vminnm_V, OpCode32SimdReg.Create);
|
SetA32("111100100x10xxxxxxxx1111xxx0xxxx", InstName.Vmin, InstEmit32.Vmin_V, OpCode32SimdReg.Create);
|
||||||
SetA32("1111001x1x<<xxxxxxxx000xx1x0xxxx", InstName.Vmla, InstEmit32.Vmla_1, OpCode32SimdRegElem.Create);
|
SetA32("111111101x00xxxxxxxx10>>x0x0xxxx", InstName.Vmaxnm, InstEmit32.Vmaxnm_S, OpCode32SimdRegS.Create);
|
||||||
SetA32("111100100xxxxxxxxxxx1001xxx0xxxx", InstName.Vmla, InstEmit32.Vmla_I, OpCode32SimdReg.Create);
|
SetA32("111100110x0xxxxxxxxx1111xxx1xxxx", InstName.Vmaxnm, InstEmit32.Vmaxnm_V, OpCode32SimdReg.Create);
|
||||||
SetA32("<<<<11100x00xxxxxxxx101xx0x0xxxx", InstName.Vmla, InstEmit32.Vmla_S, OpCode32SimdRegS.Create);
|
SetA32("111111101x00xxxxxxxx10>>x1x0xxxx", InstName.Vminnm, InstEmit32.Vminnm_S, OpCode32SimdRegS.Create);
|
||||||
SetA32("111100100x00xxxxxxxx1101xxx1xxxx", InstName.Vmla, InstEmit32.Vmla_V, OpCode32SimdReg.Create);
|
SetA32("111100110x1xxxxxxxxx1111xxx1xxxx", InstName.Vminnm, InstEmit32.Vminnm_V, OpCode32SimdReg.Create);
|
||||||
SetA32("1111001x1x<<xxxxxxxx010xx1x0xxxx", InstName.Vmls, InstEmit32.Vmls_1, OpCode32SimdRegElem.Create);
|
SetA32("1111001x1x<<xxxxxxxx000xx1x0xxxx", InstName.Vmla, InstEmit32.Vmla_1, OpCode32SimdRegElem.Create);
|
||||||
SetA32("<<<<11100x00xxxxxxxx101xx1x0xxxx", InstName.Vmls, InstEmit32.Vmls_S, OpCode32SimdRegS.Create);
|
SetA32("111100100xxxxxxxxxxx1001xxx0xxxx", InstName.Vmla, InstEmit32.Vmla_I, OpCode32SimdReg.Create);
|
||||||
SetA32("111100100x10xxxxxxxx1101xxx1xxxx", InstName.Vmls, InstEmit32.Vmls_V, OpCode32SimdReg.Create);
|
SetA32("<<<<11100x00xxxxxxxx101xx0x0xxxx", InstName.Vmla, InstEmit32.Vmla_S, OpCode32SimdRegS.Create);
|
||||||
SetA32("111100110xxxxxxxxxxx1001xxx0xxxx", InstName.Vmls, InstEmit32.Vmls_I, OpCode32SimdReg.Create);
|
SetA32("111100100x00xxxxxxxx1101xxx1xxxx", InstName.Vmla, InstEmit32.Vmla_V, OpCode32SimdReg.Create);
|
||||||
SetA32("1111001x1x<<xxxxxxx01010x0x0xxxx", InstName.Vmlsl, InstEmit32.Vmlsl_I, OpCode32SimdRegLong.Create);
|
SetA32("1111001x1x<<xxxxxxxx010xx1x0xxxx", InstName.Vmls, InstEmit32.Vmls_1, OpCode32SimdRegElem.Create);
|
||||||
SetA32("<<<<11100xx0xxxxxxxx1011xxx10000", InstName.Vmov, InstEmit32.Vmov_G1, OpCode32SimdMovGpElem.Create); // From gen purpose.
|
SetA32("<<<<11100x00xxxxxxxx101xx1x0xxxx", InstName.Vmls, InstEmit32.Vmls_S, OpCode32SimdRegS.Create);
|
||||||
SetA32("<<<<1110xxx1xxxxxxxx1011xxx10000", InstName.Vmov, InstEmit32.Vmov_G1, OpCode32SimdMovGpElem.Create); // To gen purpose.
|
SetA32("111100100x10xxxxxxxx1101xxx1xxxx", InstName.Vmls, InstEmit32.Vmls_V, OpCode32SimdReg.Create);
|
||||||
SetA32("<<<<1100010xxxxxxxxx101000x1xxxx", InstName.Vmov, InstEmit32.Vmov_G2, OpCode32SimdMovGpDouble.Create); // To/from gen purpose x2 and single precision x2.
|
SetA32("111100110xxxxxxxxxxx1001xxx0xxxx", InstName.Vmls, InstEmit32.Vmls_I, OpCode32SimdReg.Create);
|
||||||
SetA32("<<<<1100010xxxxxxxxx101100x1xxxx", InstName.Vmov, InstEmit32.Vmov_GD, OpCode32SimdMovGpDouble.Create); // To/from gen purpose x2 and double precision.
|
SetA32("1111001x1x<<xxxxxxx01010x0x0xxxx", InstName.Vmlsl, InstEmit32.Vmlsl_I, OpCode32SimdRegLong.Create);
|
||||||
SetA32("<<<<1110000xxxxxxxxx1010x0010000", InstName.Vmov, InstEmit32.Vmov_GS, OpCode32SimdMovGp.Create); // To/from gen purpose and single precision.
|
SetA32("<<<<11100xx0xxxxxxxx1011xxx10000", InstName.Vmov, InstEmit32.Vmov_G1, OpCode32SimdMovGpElem.Create); // From gen purpose.
|
||||||
SetA32("1111001x1x000xxxxxxx0xx00x01xxxx", InstName.Vmov, InstEmit32.Vmov_I, OpCode32SimdImm.Create); // D/Q vector I32.
|
SetA32("<<<<1110xxx1xxxxxxxx1011xxx10000", InstName.Vmov, InstEmit32.Vmov_G1, OpCode32SimdMovGpElem.Create); // To gen purpose.
|
||||||
SetA32("<<<<11101x11xxxxxxxx101x0000xxxx", InstName.Vmov, InstEmit32.Vmov_I, OpCode32SimdImm44.Create); // Scalar f16/32/64 based on size 01 10 11.
|
SetA32("<<<<1100010xxxxxxxxx101000x1xxxx", InstName.Vmov, InstEmit32.Vmov_G2, OpCode32SimdMovGpDouble.Create); // To/from gen purpose x2 and single precision x2.
|
||||||
SetA32("1111001x1x000xxxxxxx10x00x01xxxx", InstName.Vmov, InstEmit32.Vmov_I, OpCode32SimdImm.Create); // D/Q I16.
|
SetA32("<<<<1100010xxxxxxxxx101100x1xxxx", InstName.Vmov, InstEmit32.Vmov_GD, OpCode32SimdMovGpDouble.Create); // To/from gen purpose x2 and double precision.
|
||||||
SetA32("1111001x1x000xxxxxxx11xx0x01xxxx", InstName.Vmov, InstEmit32.Vmov_I, OpCode32SimdImm.Create); // D/Q (dt - from cmode).
|
SetA32("<<<<1110000xxxxxxxxx1010x0010000", InstName.Vmov, InstEmit32.Vmov_GS, OpCode32SimdMovGp.Create); // To/from gen purpose and single precision.
|
||||||
SetA32("1111001x1x000xxxxxxx11100x11xxxx", InstName.Vmov, InstEmit32.Vmov_I, OpCode32SimdImm.Create); // D/Q I64.
|
SetA32("1111001x1x000xxxxxxx0xx00x01xxxx", InstName.Vmov, InstEmit32.Vmov_I, OpCode32SimdImm.Create); // D/Q vector I32.
|
||||||
SetA32("<<<<11101x110000xxxx101x01x0xxxx", InstName.Vmov, InstEmit32.Vmov_S, OpCode32SimdS.Create);
|
SetA32("<<<<11101x11xxxxxxxx101x0000xxxx", InstName.Vmov, InstEmit32.Vmov_I, OpCode32SimdImm44.Create); // Scalar f16/32/64 based on size 01 10 11.
|
||||||
SetA32("1111001x1x001000xxx0101000x1xxxx", InstName.Vmovl, InstEmit32.Vmovl, OpCode32SimdLong.Create);
|
SetA32("1111001x1x000xxxxxxx10x00x01xxxx", InstName.Vmov, InstEmit32.Vmov_I, OpCode32SimdImm.Create); // D/Q I16.
|
||||||
SetA32("1111001x1x010000xxx0101000x1xxxx", InstName.Vmovl, InstEmit32.Vmovl, OpCode32SimdLong.Create);
|
SetA32("1111001x1x000xxxxxxx11xx0x01xxxx", InstName.Vmov, InstEmit32.Vmov_I, OpCode32SimdImm.Create); // D/Q (dt - from cmode).
|
||||||
SetA32("1111001x1x100000xxx0101000x1xxxx", InstName.Vmovl, InstEmit32.Vmovl, OpCode32SimdLong.Create);
|
SetA32("1111001x1x000xxxxxxx11100x11xxxx", InstName.Vmov, InstEmit32.Vmov_I, OpCode32SimdImm.Create); // D/Q I64.
|
||||||
SetA32("111100111x11xx10xxxx001000x0xxx0", InstName.Vmovn, InstEmit32.Vmovn, OpCode32SimdCmpZ.Create);
|
SetA32("<<<<11101x110000xxxx101x01x0xxxx", InstName.Vmov, InstEmit32.Vmov_S, OpCode32SimdS.Create);
|
||||||
SetA32("<<<<11101111xxxxxxxx101000010000", InstName.Vmrs, InstEmit32.Vmrs, OpCode32SimdSpecial.Create);
|
SetA32("1111001x1x001000xxx0101000x1xxxx", InstName.Vmovl, InstEmit32.Vmovl, OpCode32SimdLong.Create);
|
||||||
SetA32("<<<<11101110xxxxxxxx101000010000", InstName.Vmsr, InstEmit32.Vmsr, OpCode32SimdSpecial.Create);
|
SetA32("1111001x1x010000xxx0101000x1xxxx", InstName.Vmovl, InstEmit32.Vmovl, OpCode32SimdLong.Create);
|
||||||
SetA32("1111001x1x<<xxxxxxxx100xx1x0xxxx", InstName.Vmul, InstEmit32.Vmul_1, OpCode32SimdRegElem.Create);
|
SetA32("1111001x1x100000xxx0101000x1xxxx", InstName.Vmovl, InstEmit32.Vmovl, OpCode32SimdLong.Create);
|
||||||
SetA32("111100100x<<xxxxxxxx1001xxx1xxxx", InstName.Vmul, InstEmit32.Vmul_I, OpCode32SimdReg.Create);
|
SetA32("111100111x11xx10xxxx001000x0xxx0", InstName.Vmovn, InstEmit32.Vmovn, OpCode32SimdCmpZ.Create);
|
||||||
SetA32("111100110x00xxxxxxxx1001xxx1xxxx", InstName.Vmul, InstEmit32.Vmul_I, OpCode32SimdReg.Create);
|
SetA32("<<<<11101111xxxxxxxx101000010000", InstName.Vmrs, InstEmit32.Vmrs, OpCode32SimdSpecial.Create);
|
||||||
SetA32("<<<<11100x10xxxxxxxx101xx0x0xxxx", InstName.Vmul, InstEmit32.Vmul_S, OpCode32SimdRegS.Create);
|
SetA32("<<<<11101110xxxxxxxx101000010000", InstName.Vmsr, InstEmit32.Vmsr, OpCode32SimdSpecial.Create);
|
||||||
SetA32("111100110x00xxxxxxxx1101xxx1xxxx", InstName.Vmul, InstEmit32.Vmul_V, OpCode32SimdReg.Create);
|
SetA32("1111001x1x<<xxxxxxxx100xx1x0xxxx", InstName.Vmul, InstEmit32.Vmul_1, OpCode32SimdRegElem.Create);
|
||||||
SetA32("1111001x1x<<xxxxxxx01010x1x0xxxx", InstName.Vmull, InstEmit32.Vmull_1, OpCode32SimdRegElemLong.Create);
|
SetA32("111100100x<<xxxxxxxx1001xxx1xxxx", InstName.Vmul, InstEmit32.Vmul_I, OpCode32SimdReg.Create);
|
||||||
SetA32("1111001x1x<<xxxxxxx01100x0x0xxxx", InstName.Vmull, InstEmit32.Vmull_I, OpCode32SimdRegLong.Create);
|
SetA32("111100110x00xxxxxxxx1001xxx1xxxx", InstName.Vmul, InstEmit32.Vmul_I, OpCode32SimdReg.Create);
|
||||||
SetA32("111100101xx0xxxxxxx01110x0x0xxxx", InstName.Vmull, InstEmit32.Vmull_I, OpCode32SimdRegLong.Create); // P8/P64
|
SetA32("<<<<11100x10xxxxxxxx101xx0x0xxxx", InstName.Vmul, InstEmit32.Vmul_S, OpCode32SimdRegS.Create);
|
||||||
SetA32("111100111x110000xxxx01011xx0xxxx", InstName.Vmvn, InstEmit32.Vmvn_I, OpCode32SimdBinary.Create);
|
SetA32("111100110x00xxxxxxxx1101xxx1xxxx", InstName.Vmul, InstEmit32.Vmul_V, OpCode32SimdReg.Create);
|
||||||
SetA32("1111001x1x000xxxxxxx0xx00x11xxxx", InstName.Vmvn, InstEmit32.Vmvn_II, OpCode32SimdImm.Create); // D/Q vector I32.
|
SetA32("1111001x1x<<xxxxxxx01010x1x0xxxx", InstName.Vmull, InstEmit32.Vmull_1, OpCode32SimdRegElemLong.Create);
|
||||||
SetA32("1111001x1x000xxxxxxx10x00x11xxxx", InstName.Vmvn, InstEmit32.Vmvn_II, OpCode32SimdImm.Create);
|
SetA32("1111001x1x<<xxxxxxx01100x0x0xxxx", InstName.Vmull, InstEmit32.Vmull_I, OpCode32SimdRegLong.Create);
|
||||||
SetA32("1111001x1x000xxxxxxx110x0x11xxxx", InstName.Vmvn, InstEmit32.Vmvn_II, OpCode32SimdImm.Create);
|
SetA32("111100101xx0xxxxxxx01110x0x0xxxx", InstName.Vmull, InstEmit32.Vmull_I, OpCode32SimdRegLong.Create); // P8/P64
|
||||||
SetA32("<<<<11101x110001xxxx101x01x0xxxx", InstName.Vneg, InstEmit32.Vneg_S, OpCode32SimdS.Create);
|
SetA32("111100111x110000xxxx01011xx0xxxx", InstName.Vmvn, InstEmit32.Vmvn_I, OpCode32SimdBinary.Create);
|
||||||
SetA32("111100111x11<<01xxxx00111xx0xxxx", InstName.Vneg, InstEmit32.Vneg_V, OpCode32SimdCmpZ.Create);
|
SetA32("1111001x1x000xxxxxxx0xx00x11xxxx", InstName.Vmvn, InstEmit32.Vmvn_II, OpCode32SimdImm.Create); // D/Q vector I32.
|
||||||
SetA32("111100111x111001xxxx01111xx0xxxx", InstName.Vneg, InstEmit32.Vneg_V, OpCode32SimdCmpZ.Create);
|
SetA32("1111001x1x000xxxxxxx10x00x11xxxx", InstName.Vmvn, InstEmit32.Vmvn_II, OpCode32SimdImm.Create);
|
||||||
SetA32("<<<<11100x01xxxxxxxx101xx1x0xxxx", InstName.Vnmla, InstEmit32.Vnmla_S, OpCode32SimdRegS.Create);
|
SetA32("1111001x1x000xxxxxxx110x0x11xxxx", InstName.Vmvn, InstEmit32.Vmvn_II, OpCode32SimdImm.Create);
|
||||||
SetA32("<<<<11100x01xxxxxxxx101xx0x0xxxx", InstName.Vnmls, InstEmit32.Vnmls_S, OpCode32SimdRegS.Create);
|
SetA32("<<<<11101x110001xxxx101x01x0xxxx", InstName.Vneg, InstEmit32.Vneg_S, OpCode32SimdS.Create);
|
||||||
SetA32("<<<<11100x10xxxxxxxx101xx1x0xxxx", InstName.Vnmul, InstEmit32.Vnmul_S, OpCode32SimdRegS.Create);
|
SetA32("111100111x11<<01xxxx00111xx0xxxx", InstName.Vneg, InstEmit32.Vneg_V, OpCode32SimdCmpZ.Create);
|
||||||
SetA32("111100100x11xxxxxxxx0001xxx1xxxx", InstName.Vorn, InstEmit32.Vorn_I, OpCode32SimdBinary.Create);
|
SetA32("111100111x111001xxxx01111xx0xxxx", InstName.Vneg, InstEmit32.Vneg_V, OpCode32SimdCmpZ.Create);
|
||||||
SetA32("111100100x10xxxxxxxx0001xxx1xxxx", InstName.Vorr, InstEmit32.Vorr_I, OpCode32SimdBinary.Create);
|
SetA32("<<<<11100x01xxxxxxxx101xx1x0xxxx", InstName.Vnmla, InstEmit32.Vnmla_S, OpCode32SimdRegS.Create);
|
||||||
SetA32("1111001x1x000xxxxxxx<<x10x01xxxx", InstName.Vorr, InstEmit32.Vorr_II, OpCode32SimdImm.Create);
|
SetA32("<<<<11100x01xxxxxxxx101xx0x0xxxx", InstName.Vnmls, InstEmit32.Vnmls_S, OpCode32SimdRegS.Create);
|
||||||
SetA32("111100100x<<xxxxxxxx1011x0x1xxxx", InstName.Vpadd, InstEmit32.Vpadd_I, OpCode32SimdReg.Create);
|
SetA32("<<<<11100x10xxxxxxxx101xx1x0xxxx", InstName.Vnmul, InstEmit32.Vnmul_S, OpCode32SimdRegS.Create);
|
||||||
SetA32("111100110x00xxxxxxxx1101x0x0xxxx", InstName.Vpadd, InstEmit32.Vpadd_V, OpCode32SimdReg.Create);
|
SetA32("111100100x11xxxxxxxx0001xxx1xxxx", InstName.Vorn, InstEmit32.Vorn_I, OpCode32SimdBinary.Create);
|
||||||
SetA32("1111001x0x<<xxxxxxxx1010x0x0xxxx", InstName.Vpmax, InstEmit32.Vpmax_I, OpCode32SimdReg.Create);
|
SetA32("111100100x10xxxxxxxx0001xxx1xxxx", InstName.Vorr, InstEmit32.Vorr_I, OpCode32SimdBinary.Create);
|
||||||
SetA32("111100110x00xxxxxxxx1111x0x0xxxx", InstName.Vpmax, InstEmit32.Vpmax_V, OpCode32SimdReg.Create);
|
SetA32("1111001x1x000xxxxxxx<<x10x01xxxx", InstName.Vorr, InstEmit32.Vorr_II, OpCode32SimdImm.Create);
|
||||||
SetA32("1111001x0x<<xxxxxxxx1010x0x1xxxx", InstName.Vpmin, InstEmit32.Vpmin_I, OpCode32SimdReg.Create);
|
SetA32("111100100x<<xxxxxxxx1011x0x1xxxx", InstName.Vpadd, InstEmit32.Vpadd_I, OpCode32SimdReg.Create);
|
||||||
SetA32("111100110x10xxxxxxxx1111x0x0xxxx", InstName.Vpmin, InstEmit32.Vpmin_V, OpCode32SimdReg.Create);
|
SetA32("111100110x00xxxxxxxx1101x0x0xxxx", InstName.Vpadd, InstEmit32.Vpadd_V, OpCode32SimdReg.Create);
|
||||||
SetA32("1111001x1x>>>xxxxxxx100101x1xxx0", InstName.Vqrshrn, InstEmit32.Vqrshrn, OpCode32SimdShImmNarrow.Create);
|
SetA32("1111001x0x<<xxxxxxxx1010x0x0xxxx", InstName.Vpmax, InstEmit32.Vpmax_I, OpCode32SimdReg.Create);
|
||||||
SetA32("111100111x>>>xxxxxxx100001x1xxx0", InstName.Vqrshrun, InstEmit32.Vqrshrun, OpCode32SimdShImmNarrow.Create);
|
SetA32("111100110x00xxxxxxxx1111x0x0xxxx", InstName.Vpmax, InstEmit32.Vpmax_V, OpCode32SimdReg.Create);
|
||||||
SetA32("1111001x1x>>>xxxxxxx100100x1xxx0", InstName.Vqshrn, InstEmit32.Vqshrn, OpCode32SimdShImmNarrow.Create);
|
SetA32("1111001x0x<<xxxxxxxx1010x0x1xxxx", InstName.Vpmin, InstEmit32.Vpmin_I, OpCode32SimdReg.Create);
|
||||||
SetA32("111100111x111011xxxx010x0xx0xxxx", InstName.Vrecpe, InstEmit32.Vrecpe, OpCode32SimdSqrte.Create);
|
SetA32("111100110x10xxxxxxxx1111x0x0xxxx", InstName.Vpmin, InstEmit32.Vpmin_V, OpCode32SimdReg.Create);
|
||||||
SetA32("111100100x00xxxxxxxx1111xxx1xxxx", InstName.Vrecps, InstEmit32.Vrecps, OpCode32SimdReg.Create);
|
SetA32("1111001x1x>>>xxxxxxx100101x1xxx0", InstName.Vqrshrn, InstEmit32.Vqrshrn, OpCode32SimdShImmNarrow.Create);
|
||||||
SetA32("111100111x11xx00xxxx000<<xx0xxxx", InstName.Vrev, InstEmit32.Vrev, OpCode32SimdRev.Create);
|
SetA32("111100111x>>>xxxxxxx100001x1xxx0", InstName.Vqrshrun, InstEmit32.Vqrshrun, OpCode32SimdShImmNarrow.Create);
|
||||||
SetA32("111111101x1110xxxxxx101x01x0xxxx", InstName.Vrint, InstEmit32.Vrint_RM, OpCode32SimdS.Create);
|
SetA32("1111001x1x>>>xxxxxxx100100x1xxx0", InstName.Vqshrn, InstEmit32.Vqshrn, OpCode32SimdShImmNarrow.Create);
|
||||||
SetA32("<<<<11101x110110xxxx101x11x0xxxx", InstName.Vrint, InstEmit32.Vrint_Z, OpCode32SimdS.Create);
|
SetA32("111100111x111011xxxx010x0xx0xxxx", InstName.Vrecpe, InstEmit32.Vrecpe, OpCode32SimdSqrte.Create);
|
||||||
SetA32("<<<<11101x110111xxxx101x01x0xxxx", InstName.Vrintx, InstEmit32.Vrintx_S, OpCode32SimdS.Create);
|
SetA32("111100100x00xxxxxxxx1111xxx1xxxx", InstName.Vrecps, InstEmit32.Vrecps, OpCode32SimdReg.Create);
|
||||||
SetA32("1111001x1x>>>xxxxxxx0010>xx1xxxx", InstName.Vrshr, InstEmit32.Vrshr, OpCode32SimdShImm.Create);
|
SetA32("111100111x11xx00xxxx000<<xx0xxxx", InstName.Vrev, InstEmit32.Vrev, OpCode32SimdRev.Create);
|
||||||
SetA32("111100111x111011xxxx010x1xx0xxxx", InstName.Vrsqrte, InstEmit32.Vrsqrte, OpCode32SimdSqrte.Create);
|
SetA32("111111101x1110xxxxxx101x01x0xxxx", InstName.Vrint, InstEmit32.Vrint_RM, OpCode32SimdS.Create);
|
||||||
SetA32("111100100x10xxxxxxxx1111xxx1xxxx", InstName.Vrsqrts, InstEmit32.Vrsqrts, OpCode32SimdReg.Create);
|
SetA32("<<<<11101x110110xxxx101x11x0xxxx", InstName.Vrint, InstEmit32.Vrint_Z, OpCode32SimdS.Create);
|
||||||
SetA32("111111100xxxxxxxxxxx101xx0x0xxxx", InstName.Vsel, InstEmit32.Vsel, OpCode32SimdSel.Create);
|
SetA32("<<<<11101x110111xxxx101x01x0xxxx", InstName.Vrintx, InstEmit32.Vrintx_S, OpCode32SimdS.Create);
|
||||||
SetA32("111100101x>>>xxxxxxx0101>xx1xxxx", InstName.Vshl, InstEmit32.Vshl, OpCode32SimdShImm.Create);
|
SetA32("1111001x1x>>>xxxxxxx0010>xx1xxxx", InstName.Vrshr, InstEmit32.Vrshr, OpCode32SimdShImm.Create);
|
||||||
SetA32("1111001x0xxxxxxxxxxx0100xxx0xxxx", InstName.Vshl, InstEmit32.Vshl_I, OpCode32SimdReg.Create);
|
SetA32("111100111x111011xxxx010x1xx0xxxx", InstName.Vrsqrte, InstEmit32.Vrsqrte, OpCode32SimdSqrte.Create);
|
||||||
SetA32("1111001x1x>>>xxxxxxx101000x1xxxx", InstName.Vshll, InstEmit32.Vshll, OpCode32SimdShImmLong.Create); // A1 encoding.
|
SetA32("111100100x10xxxxxxxx1111xxx1xxxx", InstName.Vrsqrts, InstEmit32.Vrsqrts, OpCode32SimdReg.Create);
|
||||||
SetA32("1111001x1x>>>xxxxxxx0000>xx1xxxx", InstName.Vshr, InstEmit32.Vshr, OpCode32SimdShImm.Create);
|
SetA32("111111100xxxxxxxxxxx101xx0x0xxxx", InstName.Vsel, InstEmit32.Vsel, OpCode32SimdSel.Create);
|
||||||
SetA32("111100101x>>>xxxxxxx100000x1xxx0", InstName.Vshrn, InstEmit32.Vshrn, OpCode32SimdShImmNarrow.Create);
|
SetA32("111100101x>>>xxxxxxx0101>xx1xxxx", InstName.Vshl, InstEmit32.Vshl, OpCode32SimdShImm.Create);
|
||||||
SetA32("<<<<11101x110001xxxx101x11x0xxxx", InstName.Vsqrt, InstEmit32.Vsqrt_S, OpCode32SimdS.Create);
|
SetA32("1111001x0xxxxxxxxxxx0100xxx0xxxx", InstName.Vshl, InstEmit32.Vshl_I, OpCode32SimdReg.Create);
|
||||||
SetA32("1111001x1x>>>xxxxxxx0001>xx1xxxx", InstName.Vsra, InstEmit32.Vsra, OpCode32SimdShImm.Create);
|
SetA32("1111001x1x>>>xxxxxxx101000x1xxxx", InstName.Vshll, InstEmit32.Vshll, OpCode32SimdShImmLong.Create); // A1 encoding.
|
||||||
SetA32("111101001x00xxxxxxxx<<00xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemSingle.Create);
|
SetA32("1111001x1x>>>xxxxxxx0000>xx1xxxx", InstName.Vshr, InstEmit32.Vshr, OpCode32SimdShImm.Create);
|
||||||
SetA32("111101000x00xxxxxxxx0111xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemPair.Create); // Regs = 1.
|
SetA32("111100101x>>>xxxxxxx100000x1xxx0", InstName.Vshrn, InstEmit32.Vshrn, OpCode32SimdShImmNarrow.Create);
|
||||||
SetA32("111101000x00xxxxxxxx1010xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemPair.Create); // Regs = 2.
|
SetA32("<<<<11101x110001xxxx101x11x0xxxx", InstName.Vsqrt, InstEmit32.Vsqrt_S, OpCode32SimdS.Create);
|
||||||
SetA32("111101000x00xxxxxxxx0110xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemPair.Create); // Regs = 3.
|
SetA32("1111001x1x>>>xxxxxxx0001>xx1xxxx", InstName.Vsra, InstEmit32.Vsra, OpCode32SimdShImm.Create);
|
||||||
SetA32("111101000x00xxxxxxxx0010xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemPair.Create); // Regs = 4.
|
SetA32("111101001x00xxxxxxxx<<00xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemSingle.Create);
|
||||||
SetA32("111101001x00xxxxxxxx<<01xxxxxxxx", InstName.Vst2, InstEmit32.Vst2, OpCode32SimdMemSingle.Create);
|
SetA32("111101000x00xxxxxxxx0111xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemPair.Create); // Regs = 1.
|
||||||
SetA32("111101000x00xxxxxxxx100xxxxxxxxx", InstName.Vst2, InstEmit32.Vst2, OpCode32SimdMemPair.Create); // Regs = 1, inc = 1/2 (itype).
|
SetA32("111101000x00xxxxxxxx1010xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemPair.Create); // Regs = 2.
|
||||||
SetA32("111101000x00xxxxxxxx0011xxxxxxxx", InstName.Vst2, InstEmit32.Vst2, OpCode32SimdMemPair.Create); // Regs = 2, inc = 2.
|
SetA32("111101000x00xxxxxxxx0110xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemPair.Create); // Regs = 3.
|
||||||
SetA32("111101001x00xxxxxxxx<<10xxxxxxxx", InstName.Vst3, InstEmit32.Vst3, OpCode32SimdMemSingle.Create);
|
SetA32("111101000x00xxxxxxxx0010xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemPair.Create); // Regs = 4.
|
||||||
SetA32("111101000x00xxxxxxxx010xxxxxxxxx", InstName.Vst3, InstEmit32.Vst3, OpCode32SimdMemPair.Create); // Inc = 1/2 (itype).
|
SetA32("111101001x00xxxxxxxx<<01xxxxxxxx", InstName.Vst2, InstEmit32.Vst2, OpCode32SimdMemSingle.Create);
|
||||||
SetA32("111101001x00xxxxxxxx<<11xxxxxxxx", InstName.Vst4, InstEmit32.Vst4, OpCode32SimdMemSingle.Create);
|
SetA32("111101000x00xxxxxxxx100xxxxxxxxx", InstName.Vst2, InstEmit32.Vst2, OpCode32SimdMemPair.Create); // Regs = 1, inc = 1/2 (itype).
|
||||||
SetA32("111101000x00xxxxxxxx000xxxxxxxxx", InstName.Vst4, InstEmit32.Vst4, OpCode32SimdMemPair.Create); // Inc = 1/2 (itype).
|
SetA32("111101000x00xxxxxxxx0011xxxxxxxx", InstName.Vst2, InstEmit32.Vst2, OpCode32SimdMemPair.Create); // Regs = 2, inc = 2.
|
||||||
SetA32("<<<<11001x00xxxxxxxx1011xxxxxxx0", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create);
|
SetA32("111101001x00xxxxxxxx<<10xxxxxxxx", InstName.Vst3, InstEmit32.Vst3, OpCode32SimdMemSingle.Create);
|
||||||
SetA32("<<<<11001x10xxxxxxxx1011xxxxxxx0", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create);
|
SetA32("111101000x00xxxxxxxx010xxxxxxxxx", InstName.Vst3, InstEmit32.Vst3, OpCode32SimdMemPair.Create); // Inc = 1/2 (itype).
|
||||||
SetA32("<<<<11010x10xxxxxxxx1011xxxxxxx0", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create);
|
SetA32("111101001x00xxxxxxxx<<11xxxxxxxx", InstName.Vst4, InstEmit32.Vst4, OpCode32SimdMemSingle.Create);
|
||||||
SetA32("<<<<11001x00xxxxxxxx1010xxxxxxxx", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create);
|
SetA32("111101000x00xxxxxxxx000xxxxxxxxx", InstName.Vst4, InstEmit32.Vst4, OpCode32SimdMemPair.Create); // Inc = 1/2 (itype).
|
||||||
SetA32("<<<<11001x10xxxxxxxx1010xxxxxxxx", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create);
|
SetA32("<<<<11001x00xxxxxxxx1011xxxxxxx0", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create);
|
||||||
SetA32("<<<<11010x10xxxxxxxx1010xxxxxxxx", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create);
|
SetA32("<<<<11001x10xxxxxxxx1011xxxxxxx0", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create);
|
||||||
SetA32("<<<<1101xx00xxxxxxxx101xxxxxxxxx", InstName.Vstr, InstEmit32.Vstr, OpCode32SimdMemImm.Create);
|
SetA32("<<<<11010x10xxxxxxxx1011xxxxxxx0", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create);
|
||||||
SetA32("111100110xxxxxxxxxxx1000xxx0xxxx", InstName.Vsub, InstEmit32.Vsub_I, OpCode32SimdReg.Create);
|
SetA32("<<<<11001x00xxxxxxxx1010xxxxxxxx", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create);
|
||||||
SetA32("<<<<11100x11xxxxxxxx101xx1x0xxxx", InstName.Vsub, InstEmit32.Vsub_S, OpCode32SimdRegS.Create);
|
SetA32("<<<<11001x10xxxxxxxx1010xxxxxxxx", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create);
|
||||||
SetA32("111100100x10xxxxxxxx1101xxx0xxxx", InstName.Vsub, InstEmit32.Vsub_V, OpCode32SimdReg.Create);
|
SetA32("<<<<11010x10xxxxxxxx1010xxxxxxxx", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create);
|
||||||
SetA32("1111001x1x<<xxxxxxxx0011x0x0xxxx", InstName.Vsubw, InstEmit32.Vsubw_I, OpCode32SimdRegWide.Create);
|
SetA32("<<<<1101xx00xxxxxxxx101xxxxxxxxx", InstName.Vstr, InstEmit32.Vstr, OpCode32SimdMemImm.Create);
|
||||||
SetA32("111100111x11xxxxxxxx10xxxxx0xxxx", InstName.Vtbl, InstEmit32.Vtbl, OpCode32SimdTbl.Create);
|
SetA32("111100110xxxxxxxxxxx1000xxx0xxxx", InstName.Vsub, InstEmit32.Vsub_I, OpCode32SimdReg.Create);
|
||||||
SetA32("111100111x11<<10xxxx00001xx0xxxx", InstName.Vtrn, InstEmit32.Vtrn, OpCode32SimdCmpZ.Create);
|
SetA32("<<<<11100x11xxxxxxxx101xx1x0xxxx", InstName.Vsub, InstEmit32.Vsub_S, OpCode32SimdRegS.Create);
|
||||||
SetA32("111100100x<<xxxxxxxx1000xxx1xxxx", InstName.Vtst, InstEmit32.Vtst, OpCode32SimdReg.Create);
|
SetA32("111100100x10xxxxxxxx1101xxx0xxxx", InstName.Vsub, InstEmit32.Vsub_V, OpCode32SimdReg.Create);
|
||||||
SetA32("111100111x11<<10xxxx00010xx0xxxx", InstName.Vuzp, InstEmit32.Vuzp, OpCode32SimdCmpZ.Create);
|
SetA32("1111001x1x<<xxxxxxxx0011x0x0xxxx", InstName.Vsubw, InstEmit32.Vsubw_I, OpCode32SimdRegWide.Create);
|
||||||
SetA32("111100111x11<<10xxxx00011xx0xxxx", InstName.Vzip, InstEmit32.Vzip, OpCode32SimdCmpZ.Create);
|
SetA32("111100111x11xxxxxxxx10xxxxx0xxxx", InstName.Vtbl, InstEmit32.Vtbl, OpCode32SimdTbl.Create);
|
||||||
|
SetA32("111100111x11<<10xxxx00001xx0xxxx", InstName.Vtrn, InstEmit32.Vtrn, OpCode32SimdCmpZ.Create);
|
||||||
|
SetA32("111100100x<<xxxxxxxx1000xxx1xxxx", InstName.Vtst, InstEmit32.Vtst, OpCode32SimdReg.Create);
|
||||||
|
SetA32("111100111x11<<10xxxx00010xx0xxxx", InstName.Vuzp, InstEmit32.Vuzp, OpCode32SimdCmpZ.Create);
|
||||||
|
SetA32("111100111x11<<10xxxx00011xx0xxxx", InstName.Vzip, InstEmit32.Vzip, OpCode32SimdCmpZ.Create);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region "OpCode Table (AArch32, T16)"
|
#region "OpCode Table (AArch32, T16)"
|
||||||
@ -1065,14 +1070,19 @@ namespace ARMeilleure.Decoders
|
|||||||
SetT32("11110x011011xxxx0xxx1111xxxxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCodeT32AluImm.Create);
|
SetT32("11110x011011xxxx0xxx1111xxxxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCodeT32AluImm.Create);
|
||||||
SetT32("11101010100<xxxx0xxx<<<<xxxxxxxx", InstName.Eor, InstEmit32.Eor, OpCodeT32AluRsImm.Create);
|
SetT32("11101010100<xxxx0xxx<<<<xxxxxxxx", InstName.Eor, InstEmit32.Eor, OpCodeT32AluRsImm.Create);
|
||||||
SetT32("11110x00100<xxxx0xxx<<<<xxxxxxxx", InstName.Eor, InstEmit32.Eor, OpCodeT32AluImm.Create);
|
SetT32("11110x00100<xxxx0xxx<<<<xxxxxxxx", InstName.Eor, InstEmit32.Eor, OpCodeT32AluImm.Create);
|
||||||
|
SetT32("111010001101xxxxxxxx111111101111", InstName.Ldaex, InstEmit32.Ldaex, OpCodeT32MemLdEx.Create);
|
||||||
|
SetT32("1110100010x1xxxxxxxxxxxxxxxxxxxx", InstName.Ldm, InstEmit32.Ldm, OpCodeT32MemMult.Create);
|
||||||
|
SetT32("1110100100x1xxxxxxxxxxxxxxxxxxxx", InstName.Ldm, InstEmit32.Ldm, OpCodeT32MemMult.Create);
|
||||||
SetT32("111110000101xxxx<<<<10x1xxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm8.Create);
|
SetT32("111110000101xxxx<<<<10x1xxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm8.Create);
|
||||||
SetT32("111110000101xxxx<<<<1100xxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm8.Create);
|
SetT32("111110000101xxxx<<<<1100xxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm8.Create);
|
||||||
SetT32("111110000101xxxx<<<<11x1xxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm8.Create);
|
SetT32("111110000101xxxx<<<<11x1xxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm8.Create);
|
||||||
SetT32("111110001101xxxxxxxxxxxxxxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm12.Create);
|
SetT32("111110001101xxxxxxxxxxxxxxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm12.Create);
|
||||||
|
SetT32("111110000101<<<<xxxx000000xxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemRsImm.Create);
|
||||||
SetT32("111110000001xxxx<<<<10x1xxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm8.Create);
|
SetT32("111110000001xxxx<<<<10x1xxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm8.Create);
|
||||||
SetT32("111110000001xxxx<<<<1100xxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm8.Create);
|
SetT32("111110000001xxxx<<<<1100xxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm8.Create);
|
||||||
SetT32("111110000001xxxx<<<<11x1xxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm8.Create);
|
SetT32("111110000001xxxx<<<<11x1xxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm8.Create);
|
||||||
SetT32("111110001001xxxxxxxxxxxxxxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm12.Create);
|
SetT32("111110001001xxxxxxxxxxxxxxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm12.Create);
|
||||||
|
SetT32("1110100>x1>1<<<<xxxxxxxxxxxxxxxx", InstName.Ldrd, InstEmit32.Ldrd, OpCodeT32MemImm8D.Create);
|
||||||
SetT32("111110000011xxxx<<<<10x1xxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm8.Create);
|
SetT32("111110000011xxxx<<<<10x1xxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm8.Create);
|
||||||
SetT32("111110000011xxxx<<<<1100xxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm8.Create);
|
SetT32("111110000011xxxx<<<<1100xxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm8.Create);
|
||||||
SetT32("111110000011xxxx<<<<11x1xxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm8.Create);
|
SetT32("111110000011xxxx<<<<11x1xxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm8.Create);
|
||||||
@ -1097,10 +1107,15 @@ namespace ARMeilleure.Decoders
|
|||||||
SetT32("11110x01110xxxxx0xxxxxxxxxxxxxxx", InstName.Rsb, InstEmit32.Rsb, OpCodeT32AluImm.Create);
|
SetT32("11110x01110xxxxx0xxxxxxxxxxxxxxx", InstName.Rsb, InstEmit32.Rsb, OpCodeT32AluImm.Create);
|
||||||
SetT32("11101011011xxxxx0xxxxxxxxxxxxxxx", InstName.Sbc, InstEmit32.Sbc, OpCodeT32AluRsImm.Create);
|
SetT32("11101011011xxxxx0xxxxxxxxxxxxxxx", InstName.Sbc, InstEmit32.Sbc, OpCodeT32AluRsImm.Create);
|
||||||
SetT32("11110x01011xxxxx0xxxxxxxxxxxxxxx", InstName.Sbc, InstEmit32.Sbc, OpCodeT32AluImm.Create);
|
SetT32("11110x01011xxxxx0xxxxxxxxxxxxxxx", InstName.Sbc, InstEmit32.Sbc, OpCodeT32AluImm.Create);
|
||||||
|
SetT32("111010001100xxxxxxxx11111110xxxx", InstName.Stlex, InstEmit32.Stlex, OpCodeT32MemStEx.Create);
|
||||||
|
SetT32("1110100010x0xxxx0xxxxxxxxxxxxxxx", InstName.Stm, InstEmit32.Stm, OpCodeT32MemMult.Create);
|
||||||
|
SetT32("1110100100x0xxxx0xxxxxxxxxxxxxxx", InstName.Stm, InstEmit32.Stm, OpCodeT32MemMult.Create);
|
||||||
SetT32("111110000100xxxxxxxx1<<>xxxxxxxx", InstName.Str, InstEmit32.Str, OpCodeT32MemImm8.Create);
|
SetT32("111110000100xxxxxxxx1<<>xxxxxxxx", InstName.Str, InstEmit32.Str, OpCodeT32MemImm8.Create);
|
||||||
SetT32("111110001100xxxxxxxxxxxxxxxxxxxx", InstName.Str, InstEmit32.Str, OpCodeT32MemImm12.Create);
|
SetT32("111110001100xxxxxxxxxxxxxxxxxxxx", InstName.Str, InstEmit32.Str, OpCodeT32MemImm12.Create);
|
||||||
|
SetT32("111110000100<<<<xxxx000000xxxxxx", InstName.Str, InstEmit32.Str, OpCodeT32MemRsImm.Create);
|
||||||
SetT32("111110000000xxxxxxxx1<<>xxxxxxxx", InstName.Strb, InstEmit32.Strb, OpCodeT32MemImm8.Create);
|
SetT32("111110000000xxxxxxxx1<<>xxxxxxxx", InstName.Strb, InstEmit32.Strb, OpCodeT32MemImm8.Create);
|
||||||
SetT32("111110001000xxxxxxxxxxxxxxxxxxxx", InstName.Strb, InstEmit32.Strb, OpCodeT32MemImm12.Create);
|
SetT32("111110001000xxxxxxxxxxxxxxxxxxxx", InstName.Strb, InstEmit32.Strb, OpCodeT32MemImm12.Create);
|
||||||
|
SetT32("1110100>x1>0<<<<xxxxxxxxxxxxxxxx", InstName.Strd, InstEmit32.Strd, OpCodeT32MemImm8D.Create);
|
||||||
SetT32("111110000010xxxxxxxx1<<>xxxxxxxx", InstName.Strh, InstEmit32.Strh, OpCodeT32MemImm8.Create);
|
SetT32("111110000010xxxxxxxx1<<>xxxxxxxx", InstName.Strh, InstEmit32.Strh, OpCodeT32MemImm8.Create);
|
||||||
SetT32("111110001010xxxxxxxxxxxxxxxxxxxx", InstName.Strh, InstEmit32.Strh, OpCodeT32MemImm12.Create);
|
SetT32("111110001010xxxxxxxxxxxxxxxxxxxx", InstName.Strh, InstEmit32.Strh, OpCodeT32MemImm12.Create);
|
||||||
SetT32("11101011101<xxxx0xxx<<<<xxxxxxxx", InstName.Sub, InstEmit32.Sub, OpCodeT32AluRsImm.Create);
|
SetT32("11101011101<xxxx0xxx<<<<xxxxxxxx", InstName.Sub, InstEmit32.Sub, OpCodeT32AluRsImm.Create);
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
using ARMeilleure.Decoders;
|
using ARMeilleure.Decoders;
|
||||||
using ARMeilleure.Translation;
|
using ARMeilleure.Translation;
|
||||||
|
|
||||||
using static ARMeilleure.Instructions.InstEmitFlowHelper;
|
|
||||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||||
|
|
||||||
namespace ARMeilleure.Instructions
|
namespace ARMeilleure.Instructions
|
||||||
|
@ -88,7 +88,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
OpCodeT16BImmCmp op = (OpCodeT16BImmCmp)context.CurrOp;
|
OpCodeT16BImmCmp op = (OpCodeT16BImmCmp)context.CurrOp;
|
||||||
|
|
||||||
Operand value = GetIntOrZR(context, op.Rn);
|
Operand value = GetIntA32(context, op.Rn);
|
||||||
Operand lblTarget = context.GetLabel((ulong)op.Immediate);
|
Operand lblTarget = context.GetLabel((ulong)op.Immediate);
|
||||||
|
|
||||||
if (onNotZero)
|
if (onNotZero)
|
||||||
|
@ -547,7 +547,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
switch (context.CurrOp)
|
switch (context.CurrOp)
|
||||||
{
|
{
|
||||||
case OpCode32MemRsImm op: return GetMShiftedByImmediate(context, op, setCarry);
|
case IOpCode32MemRsImm op: return GetMShiftedByImmediate(context, op, setCarry);
|
||||||
|
|
||||||
case IOpCode32MemReg op: return GetIntA32(context, op.Rm);
|
case IOpCode32MemReg op: return GetIntA32(context, op.Rm);
|
||||||
|
|
||||||
@ -564,7 +564,7 @@ namespace ARMeilleure.Instructions
|
|||||||
return new InvalidOperationException($"Invalid OpCode type \"{opCode?.GetType().Name ?? "null"}\".");
|
return new InvalidOperationException($"Invalid OpCode type \"{opCode?.GetType().Name ?? "null"}\".");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Operand GetMShiftedByImmediate(ArmEmitterContext context, OpCode32MemRsImm op, bool setCarry)
|
public static Operand GetMShiftedByImmediate(ArmEmitterContext context, IOpCode32MemRsImm op, bool setCarry)
|
||||||
{
|
{
|
||||||
Operand m = GetIntA32(context, op.Rm);
|
Operand m = GetIntA32(context, op.Rm);
|
||||||
|
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
using ARMeilleure.IntermediateRepresentation;
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
using ARMeilleure.Translation;
|
using ARMeilleure.Translation;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
using static ARMeilleure.Instructions.InstEmitFlowHelper;
|
using static ARMeilleure.Instructions.InstEmitFlowHelper;
|
||||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||||
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
||||||
|
@ -100,7 +100,7 @@ namespace ARMeilleure.Instructions
|
|||||||
Operand n = GetVec(op.Rn);
|
Operand n = GetVec(op.Rn);
|
||||||
Operand m = GetVec(op.Rm);
|
Operand m = GetVec(op.Rm);
|
||||||
|
|
||||||
Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashLower)), d, n, m);
|
Operand res = InstEmitSimdHashHelper.EmitSha256h(context, d, n, m, part2: false);
|
||||||
|
|
||||||
context.Copy(GetVec(op.Rd), res);
|
context.Copy(GetVec(op.Rd), res);
|
||||||
}
|
}
|
||||||
@ -113,7 +113,7 @@ namespace ARMeilleure.Instructions
|
|||||||
Operand n = GetVec(op.Rn);
|
Operand n = GetVec(op.Rn);
|
||||||
Operand m = GetVec(op.Rm);
|
Operand m = GetVec(op.Rm);
|
||||||
|
|
||||||
Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashUpper)), d, n, m);
|
Operand res = InstEmitSimdHashHelper.EmitSha256h(context, n, d, m, part2: true);
|
||||||
|
|
||||||
context.Copy(GetVec(op.Rd), res);
|
context.Copy(GetVec(op.Rd), res);
|
||||||
}
|
}
|
||||||
@ -125,7 +125,7 @@ namespace ARMeilleure.Instructions
|
|||||||
Operand d = GetVec(op.Rd);
|
Operand d = GetVec(op.Rd);
|
||||||
Operand n = GetVec(op.Rn);
|
Operand n = GetVec(op.Rn);
|
||||||
|
|
||||||
Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart1)), d, n);
|
Operand res = InstEmitSimdHashHelper.EmitSha256su0(context, d, n);
|
||||||
|
|
||||||
context.Copy(GetVec(op.Rd), res);
|
context.Copy(GetVec(op.Rd), res);
|
||||||
}
|
}
|
||||||
@ -138,7 +138,7 @@ namespace ARMeilleure.Instructions
|
|||||||
Operand n = GetVec(op.Rn);
|
Operand n = GetVec(op.Rn);
|
||||||
Operand m = GetVec(op.Rm);
|
Operand m = GetVec(op.Rm);
|
||||||
|
|
||||||
Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart2)), d, n, m);
|
Operand res = InstEmitSimdHashHelper.EmitSha256su1(context, d, n, m);
|
||||||
|
|
||||||
context.Copy(GetVec(op.Rd), res);
|
context.Copy(GetVec(op.Rd), res);
|
||||||
}
|
}
|
||||||
|
64
ARMeilleure/Instructions/InstEmitSimdHash32.cs
Normal file
64
ARMeilleure/Instructions/InstEmitSimdHash32.cs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
using ARMeilleure.Decoders;
|
||||||
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
|
using ARMeilleure.Translation;
|
||||||
|
|
||||||
|
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Instructions
|
||||||
|
{
|
||||||
|
static partial class InstEmit32
|
||||||
|
{
|
||||||
|
#region "Sha256"
|
||||||
|
public static void Sha256h_V(ArmEmitterContext context)
|
||||||
|
{
|
||||||
|
OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;
|
||||||
|
|
||||||
|
Operand d = GetVecA32(op.Qd);
|
||||||
|
Operand n = GetVecA32(op.Qn);
|
||||||
|
Operand m = GetVecA32(op.Qm);
|
||||||
|
|
||||||
|
Operand res = InstEmitSimdHashHelper.EmitSha256h(context, d, n, m, part2: false);
|
||||||
|
|
||||||
|
context.Copy(GetVecA32(op.Qd), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Sha256h2_V(ArmEmitterContext context)
|
||||||
|
{
|
||||||
|
OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;
|
||||||
|
|
||||||
|
Operand d = GetVecA32(op.Qd);
|
||||||
|
Operand n = GetVecA32(op.Qn);
|
||||||
|
Operand m = GetVecA32(op.Qm);
|
||||||
|
|
||||||
|
Operand res = InstEmitSimdHashHelper.EmitSha256h(context, n, d, m, part2: true);
|
||||||
|
|
||||||
|
context.Copy(GetVecA32(op.Qd), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Sha256su0_V(ArmEmitterContext context)
|
||||||
|
{
|
||||||
|
OpCode32Simd op = (OpCode32Simd)context.CurrOp;
|
||||||
|
|
||||||
|
Operand d = GetVecA32(op.Qd);
|
||||||
|
Operand m = GetVecA32(op.Qm);
|
||||||
|
|
||||||
|
Operand res = InstEmitSimdHashHelper.EmitSha256su0(context, d, m);
|
||||||
|
|
||||||
|
context.Copy(GetVecA32(op.Qd), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Sha256su1_V(ArmEmitterContext context)
|
||||||
|
{
|
||||||
|
OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;
|
||||||
|
|
||||||
|
Operand d = GetVecA32(op.Qd);
|
||||||
|
Operand n = GetVecA32(op.Qn);
|
||||||
|
Operand m = GetVecA32(op.Qm);
|
||||||
|
|
||||||
|
Operand res = InstEmitSimdHashHelper.EmitSha256su1(context, d, n, m);
|
||||||
|
|
||||||
|
context.Copy(GetVecA32(op.Qd), res);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
56
ARMeilleure/Instructions/InstEmitSimdHashHelper.cs
Normal file
56
ARMeilleure/Instructions/InstEmitSimdHashHelper.cs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
|
using ARMeilleure.Translation;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Instructions
|
||||||
|
{
|
||||||
|
static class InstEmitSimdHashHelper
|
||||||
|
{
|
||||||
|
public static Operand EmitSha256h(ArmEmitterContext context, Operand x, Operand y, Operand w, bool part2)
|
||||||
|
{
|
||||||
|
if (Optimizations.UseSha)
|
||||||
|
{
|
||||||
|
Operand src1 = context.AddIntrinsic(Intrinsic.X86Shufps, y, x, Const(0xbb));
|
||||||
|
Operand src2 = context.AddIntrinsic(Intrinsic.X86Shufps, y, x, Const(0x11));
|
||||||
|
Operand w2 = context.AddIntrinsic(Intrinsic.X86Punpckhqdq, w, w);
|
||||||
|
|
||||||
|
Operand round2 = context.AddIntrinsic(Intrinsic.X86Sha256Rnds2, src1, src2, w);
|
||||||
|
Operand round4 = context.AddIntrinsic(Intrinsic.X86Sha256Rnds2, src2, round2, w2);
|
||||||
|
|
||||||
|
Operand res = context.AddIntrinsic(Intrinsic.X86Shufps, round4, round2, Const(part2 ? 0x11 : 0xbb));
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
String method = part2 ? nameof(SoftFallback.HashUpper) : nameof(SoftFallback.HashLower);
|
||||||
|
return context.Call(typeof(SoftFallback).GetMethod(method), x, y, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Operand EmitSha256su0(ArmEmitterContext context, Operand x, Operand y)
|
||||||
|
{
|
||||||
|
if (Optimizations.UseSha)
|
||||||
|
{
|
||||||
|
return context.AddIntrinsic(Intrinsic.X86Sha256Msg1, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart1)), x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Operand EmitSha256su1(ArmEmitterContext context, Operand x, Operand y, Operand z)
|
||||||
|
{
|
||||||
|
if (Optimizations.UseSha && Optimizations.UseSsse3)
|
||||||
|
{
|
||||||
|
Operand extr = context.AddIntrinsic(Intrinsic.X86Palignr, z, y, Const(4));
|
||||||
|
Operand tmp = context.AddIntrinsic(Intrinsic.X86Paddd, extr, x);
|
||||||
|
|
||||||
|
Operand res = context.AddIntrinsic(Intrinsic.X86Sha256Msg2, tmp, z);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart2)), x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -169,6 +169,31 @@ namespace ARMeilleure.Instructions
|
|||||||
SetIntA32(context, op.CRn, context.ConvertI64ToI32(context.ShiftRightUI(result, Const(32))));
|
SetIntA32(context, op.CRn, context.ConvertI64ToI32(context.ShiftRightUI(result, Const(32))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Mrs(ArmEmitterContext context)
|
||||||
|
{
|
||||||
|
OpCode32Mrs op = (OpCode32Mrs)context.CurrOp;
|
||||||
|
|
||||||
|
if (op.R)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("SPSR");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Operand vSh = context.ShiftLeft(GetFlag(PState.VFlag), Const((int)PState.VFlag));
|
||||||
|
Operand cSh = context.ShiftLeft(GetFlag(PState.CFlag), Const((int)PState.CFlag));
|
||||||
|
Operand zSh = context.ShiftLeft(GetFlag(PState.ZFlag), Const((int)PState.ZFlag));
|
||||||
|
Operand nSh = context.ShiftLeft(GetFlag(PState.NFlag), Const((int)PState.NFlag));
|
||||||
|
Operand qSh = context.ShiftLeft(GetFlag(PState.QFlag), Const((int)PState.QFlag));
|
||||||
|
|
||||||
|
Operand spsr = context.BitwiseOr(context.BitwiseOr(nSh, zSh), context.BitwiseOr(cSh, vSh));
|
||||||
|
spsr = context.BitwiseOr(spsr, qSh);
|
||||||
|
|
||||||
|
// TODO: Remaining flags.
|
||||||
|
|
||||||
|
SetIntA32(context, op.Rd, spsr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void Msr(ArmEmitterContext context)
|
public static void Msr(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
OpCode32MsrReg op = (OpCode32MsrReg)context.CurrOp;
|
OpCode32MsrReg op = (OpCode32MsrReg)context.CurrOp;
|
||||||
|
@ -2,8 +2,6 @@ using ARMeilleure.Memory;
|
|||||||
using ARMeilleure.State;
|
using ARMeilleure.State;
|
||||||
using ARMeilleure.Translation;
|
using ARMeilleure.Translation;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace ARMeilleure.Instructions
|
namespace ARMeilleure.Instructions
|
||||||
{
|
{
|
||||||
|
@ -1129,7 +1129,7 @@ namespace ARMeilleure.Instructions
|
|||||||
return Sha256Hash(hash_abcd, hash_efgh, wk, part1: true);
|
return Sha256Hash(hash_abcd, hash_efgh, wk, part1: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static V128 HashUpper(V128 hash_efgh, V128 hash_abcd, V128 wk)
|
public static V128 HashUpper(V128 hash_abcd, V128 hash_efgh, V128 wk)
|
||||||
{
|
{
|
||||||
return Sha256Hash(hash_abcd, hash_efgh, wk, part1: false);
|
return Sha256Hash(hash_abcd, hash_efgh, wk, part1: false);
|
||||||
}
|
}
|
||||||
|
@ -71,6 +71,7 @@ namespace ARMeilleure.IntermediateRepresentation
|
|||||||
X86Paddd,
|
X86Paddd,
|
||||||
X86Paddq,
|
X86Paddq,
|
||||||
X86Paddw,
|
X86Paddw,
|
||||||
|
X86Palignr,
|
||||||
X86Pand,
|
X86Pand,
|
||||||
X86Pandn,
|
X86Pandn,
|
||||||
X86Pavgb,
|
X86Pavgb,
|
||||||
@ -140,6 +141,9 @@ namespace ARMeilleure.IntermediateRepresentation
|
|||||||
X86Roundss,
|
X86Roundss,
|
||||||
X86Rsqrtps,
|
X86Rsqrtps,
|
||||||
X86Rsqrtss,
|
X86Rsqrtss,
|
||||||
|
X86Sha256Msg1,
|
||||||
|
X86Sha256Msg2,
|
||||||
|
X86Sha256Rnds2,
|
||||||
X86Shufpd,
|
X86Shufpd,
|
||||||
X86Shufps,
|
X86Shufps,
|
||||||
X86Sqrtpd,
|
X86Sqrtpd,
|
||||||
|
@ -21,6 +21,7 @@ namespace ARMeilleure
|
|||||||
public static bool UseFmaIfAvailable { get; set; } = true;
|
public static bool UseFmaIfAvailable { get; set; } = true;
|
||||||
public static bool UseAesniIfAvailable { get; set; } = true;
|
public static bool UseAesniIfAvailable { get; set; } = true;
|
||||||
public static bool UsePclmulqdqIfAvailable { get; set; } = true;
|
public static bool UsePclmulqdqIfAvailable { get; set; } = true;
|
||||||
|
public static bool UseShaIfAvailable { get; set; } = true;
|
||||||
|
|
||||||
public static bool ForceLegacySse
|
public static bool ForceLegacySse
|
||||||
{
|
{
|
||||||
@ -40,5 +41,6 @@ namespace ARMeilleure
|
|||||||
internal static bool UseFma => UseFmaIfAvailable && HardwareCapabilities.SupportsFma;
|
internal static bool UseFma => UseFmaIfAvailable && HardwareCapabilities.SupportsFma;
|
||||||
internal static bool UseAesni => UseAesniIfAvailable && HardwareCapabilities.SupportsAesni;
|
internal static bool UseAesni => UseAesniIfAvailable && HardwareCapabilities.SupportsAesni;
|
||||||
internal static bool UsePclmulqdq => UsePclmulqdqIfAvailable && HardwareCapabilities.SupportsPclmulqdq;
|
internal static bool UsePclmulqdq => UsePclmulqdqIfAvailable && HardwareCapabilities.SupportsPclmulqdq;
|
||||||
|
internal static bool UseSha => UseShaIfAvailable && HardwareCapabilities.SupportsSha;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -197,12 +197,29 @@ namespace ARMeilleure.Signal
|
|||||||
// Only call tracking if in range.
|
// Only call tracking if in range.
|
||||||
context.BranchIfFalse(nextLabel, inRange, BasicBlockFrequency.Cold);
|
context.BranchIfFalse(nextLabel, inRange, BasicBlockFrequency.Cold);
|
||||||
|
|
||||||
context.Copy(inRegionLocal, Const(1));
|
|
||||||
Operand offset = context.BitwiseAnd(context.Subtract(faultAddress, rangeAddress), Const(~PageMask));
|
Operand offset = context.BitwiseAnd(context.Subtract(faultAddress, rangeAddress), Const(~PageMask));
|
||||||
|
|
||||||
// Call the tracking action, with the pointer's relative offset to the base address.
|
// Call the tracking action, with the pointer's relative offset to the base address.
|
||||||
Operand trackingActionPtr = context.Load(OperandType.I64, Const((ulong)signalStructPtr + rangeBaseOffset + 20));
|
Operand trackingActionPtr = context.Load(OperandType.I64, Const((ulong)signalStructPtr + rangeBaseOffset + 20));
|
||||||
context.Call(trackingActionPtr, OperandType.I32, offset, Const(PageSize), isWrite, Const(0));
|
|
||||||
|
context.Copy(inRegionLocal, Const(0));
|
||||||
|
|
||||||
|
Operand skipActionLabel = Label();
|
||||||
|
|
||||||
|
// Tracking action should be non-null to call it, otherwise assume false return.
|
||||||
|
context.BranchIfFalse(skipActionLabel, trackingActionPtr);
|
||||||
|
Operand result = context.Call(trackingActionPtr, OperandType.I32, offset, Const(PageSize), isWrite, Const(0));
|
||||||
|
context.Copy(inRegionLocal, result);
|
||||||
|
|
||||||
|
context.MarkLabel(skipActionLabel);
|
||||||
|
|
||||||
|
// If the tracking action returns false or does not exist, it might be an invalid access due to a partial overlap on Windows.
|
||||||
|
if (OperatingSystem.IsWindows())
|
||||||
|
{
|
||||||
|
context.BranchIfTrue(endLabel, inRegionLocal);
|
||||||
|
|
||||||
|
context.Copy(inRegionLocal, WindowsPartialUnmapHandler.EmitRetryFromAccessViolation(context));
|
||||||
|
}
|
||||||
|
|
||||||
context.Branch(endLabel);
|
context.Branch(endLabel);
|
||||||
|
|
||||||
|
84
ARMeilleure/Signal/TestMethods.cs
Normal file
84
ARMeilleure/Signal/TestMethods.cs
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
|
using ARMeilleure.Translation;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Signal
|
||||||
|
{
|
||||||
|
public struct NativeWriteLoopState
|
||||||
|
{
|
||||||
|
public int Running;
|
||||||
|
public int Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TestMethods
|
||||||
|
{
|
||||||
|
public delegate bool DebugPartialUnmap();
|
||||||
|
public delegate int DebugThreadLocalMapGetOrReserve(int threadId, int initialState);
|
||||||
|
public delegate void DebugNativeWriteLoop(IntPtr nativeWriteLoopPtr, IntPtr writePtr);
|
||||||
|
|
||||||
|
public static DebugPartialUnmap GenerateDebugPartialUnmap()
|
||||||
|
{
|
||||||
|
EmitterContext context = new EmitterContext();
|
||||||
|
|
||||||
|
var result = WindowsPartialUnmapHandler.EmitRetryFromAccessViolation(context);
|
||||||
|
|
||||||
|
context.Return(result);
|
||||||
|
|
||||||
|
// Compile and return the function.
|
||||||
|
|
||||||
|
ControlFlowGraph cfg = context.GetControlFlowGraph();
|
||||||
|
|
||||||
|
OperandType[] argTypes = new OperandType[] { OperandType.I64 };
|
||||||
|
|
||||||
|
return Compiler.Compile(cfg, argTypes, OperandType.I32, CompilerOptions.HighCq).Map<DebugPartialUnmap>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DebugThreadLocalMapGetOrReserve GenerateDebugThreadLocalMapGetOrReserve(IntPtr structPtr)
|
||||||
|
{
|
||||||
|
EmitterContext context = new EmitterContext();
|
||||||
|
|
||||||
|
var result = WindowsPartialUnmapHandler.EmitThreadLocalMapIntGetOrReserve(context, structPtr, context.LoadArgument(OperandType.I32, 0), context.LoadArgument(OperandType.I32, 1));
|
||||||
|
|
||||||
|
context.Return(result);
|
||||||
|
|
||||||
|
// Compile and return the function.
|
||||||
|
|
||||||
|
ControlFlowGraph cfg = context.GetControlFlowGraph();
|
||||||
|
|
||||||
|
OperandType[] argTypes = new OperandType[] { OperandType.I64 };
|
||||||
|
|
||||||
|
return Compiler.Compile(cfg, argTypes, OperandType.I32, CompilerOptions.HighCq).Map<DebugThreadLocalMapGetOrReserve>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DebugNativeWriteLoop GenerateDebugNativeWriteLoop()
|
||||||
|
{
|
||||||
|
EmitterContext context = new EmitterContext();
|
||||||
|
|
||||||
|
// Loop a write to the target address until "running" is false.
|
||||||
|
|
||||||
|
Operand structPtr = context.Copy(context.LoadArgument(OperandType.I64, 0));
|
||||||
|
Operand writePtr = context.Copy(context.LoadArgument(OperandType.I64, 1));
|
||||||
|
|
||||||
|
Operand loopLabel = Label();
|
||||||
|
context.MarkLabel(loopLabel);
|
||||||
|
|
||||||
|
context.Store(writePtr, Const(12345));
|
||||||
|
|
||||||
|
Operand running = context.Load(OperandType.I32, structPtr);
|
||||||
|
|
||||||
|
context.BranchIfTrue(loopLabel, running);
|
||||||
|
|
||||||
|
context.Return();
|
||||||
|
|
||||||
|
// Compile and return the function.
|
||||||
|
|
||||||
|
ControlFlowGraph cfg = context.GetControlFlowGraph();
|
||||||
|
|
||||||
|
OperandType[] argTypes = new OperandType[] { OperandType.I64 };
|
||||||
|
|
||||||
|
return Compiler.Compile(cfg, argTypes, OperandType.None, CompilerOptions.HighCq).Map<DebugNativeWriteLoop>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
186
ARMeilleure/Signal/WindowsPartialUnmapHandler.cs
Normal file
186
ARMeilleure/Signal/WindowsPartialUnmapHandler.cs
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
|
using ARMeilleure.Translation;
|
||||||
|
using Ryujinx.Common.Memory.PartialUnmaps;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Signal
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Methods to handle signals caused by partial unmaps. See the structs for C# implementations of the methods.
|
||||||
|
/// </summary>
|
||||||
|
internal static class WindowsPartialUnmapHandler
|
||||||
|
{
|
||||||
|
public static Operand EmitRetryFromAccessViolation(EmitterContext context)
|
||||||
|
{
|
||||||
|
IntPtr partialRemapStatePtr = PartialUnmapState.GlobalState;
|
||||||
|
IntPtr localCountsPtr = IntPtr.Add(partialRemapStatePtr, PartialUnmapState.LocalCountsOffset);
|
||||||
|
|
||||||
|
// Get the lock first.
|
||||||
|
EmitNativeReaderLockAcquire(context, IntPtr.Add(partialRemapStatePtr, PartialUnmapState.PartialUnmapLockOffset));
|
||||||
|
|
||||||
|
IntPtr getCurrentThreadId = WindowsSignalHandlerRegistration.GetCurrentThreadIdFunc();
|
||||||
|
Operand threadId = context.Call(Const((ulong)getCurrentThreadId), OperandType.I32);
|
||||||
|
Operand threadIndex = EmitThreadLocalMapIntGetOrReserve(context, localCountsPtr, threadId, Const(0));
|
||||||
|
|
||||||
|
Operand endLabel = Label();
|
||||||
|
Operand retry = context.AllocateLocal(OperandType.I32);
|
||||||
|
Operand threadIndexValidLabel = Label();
|
||||||
|
|
||||||
|
context.BranchIfFalse(threadIndexValidLabel, context.ICompareEqual(threadIndex, Const(-1)));
|
||||||
|
|
||||||
|
context.Copy(retry, Const(1)); // Always retry when thread local cannot be allocated.
|
||||||
|
|
||||||
|
context.Branch(endLabel);
|
||||||
|
|
||||||
|
context.MarkLabel(threadIndexValidLabel);
|
||||||
|
|
||||||
|
Operand threadLocalPartialUnmapsPtr = EmitThreadLocalMapIntGetValuePtr(context, localCountsPtr, threadIndex);
|
||||||
|
Operand threadLocalPartialUnmaps = context.Load(OperandType.I32, threadLocalPartialUnmapsPtr);
|
||||||
|
Operand partialUnmapsCount = context.Load(OperandType.I32, Const((ulong)IntPtr.Add(partialRemapStatePtr, PartialUnmapState.PartialUnmapsCountOffset)));
|
||||||
|
|
||||||
|
context.Copy(retry, context.ICompareNotEqual(threadLocalPartialUnmaps, partialUnmapsCount));
|
||||||
|
|
||||||
|
Operand noRetryLabel = Label();
|
||||||
|
|
||||||
|
context.BranchIfFalse(noRetryLabel, retry);
|
||||||
|
|
||||||
|
// if (retry) {
|
||||||
|
|
||||||
|
context.Store(threadLocalPartialUnmapsPtr, partialUnmapsCount);
|
||||||
|
|
||||||
|
context.Branch(endLabel);
|
||||||
|
|
||||||
|
context.MarkLabel(noRetryLabel);
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
context.MarkLabel(endLabel);
|
||||||
|
|
||||||
|
// Finally, release the lock and return the retry value.
|
||||||
|
EmitNativeReaderLockRelease(context, IntPtr.Add(partialRemapStatePtr, PartialUnmapState.PartialUnmapLockOffset));
|
||||||
|
|
||||||
|
return retry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Operand EmitThreadLocalMapIntGetOrReserve(EmitterContext context, IntPtr threadLocalMapPtr, Operand threadId, Operand initialState)
|
||||||
|
{
|
||||||
|
Operand idsPtr = Const((ulong)IntPtr.Add(threadLocalMapPtr, ThreadLocalMap<int>.ThreadIdsOffset));
|
||||||
|
|
||||||
|
Operand i = context.AllocateLocal(OperandType.I32);
|
||||||
|
|
||||||
|
context.Copy(i, Const(0));
|
||||||
|
|
||||||
|
// (Loop 1) Check all slots for a matching Thread ID (while also trying to allocate)
|
||||||
|
|
||||||
|
Operand endLabel = Label();
|
||||||
|
|
||||||
|
Operand loopLabel = Label();
|
||||||
|
context.MarkLabel(loopLabel);
|
||||||
|
|
||||||
|
Operand offset = context.Multiply(i, Const(sizeof(int)));
|
||||||
|
Operand idPtr = context.Add(idsPtr, context.SignExtend32(OperandType.I64, offset));
|
||||||
|
|
||||||
|
// Check that this slot has the thread ID.
|
||||||
|
Operand existingId = context.CompareAndSwap(idPtr, threadId, threadId);
|
||||||
|
|
||||||
|
// If it was already the thread ID, then we just need to return i.
|
||||||
|
context.BranchIfTrue(endLabel, context.ICompareEqual(existingId, threadId));
|
||||||
|
|
||||||
|
context.Copy(i, context.Add(i, Const(1)));
|
||||||
|
|
||||||
|
context.BranchIfTrue(loopLabel, context.ICompareLess(i, Const(ThreadLocalMap<int>.MapSize)));
|
||||||
|
|
||||||
|
// (Loop 2) Try take a slot that is 0 with our Thread ID.
|
||||||
|
|
||||||
|
context.Copy(i, Const(0)); // Reset i.
|
||||||
|
|
||||||
|
Operand loop2Label = Label();
|
||||||
|
context.MarkLabel(loop2Label);
|
||||||
|
|
||||||
|
Operand offset2 = context.Multiply(i, Const(sizeof(int)));
|
||||||
|
Operand idPtr2 = context.Add(idsPtr, context.SignExtend32(OperandType.I64, offset2));
|
||||||
|
|
||||||
|
// Try and swap in the thread id on top of 0.
|
||||||
|
Operand existingId2 = context.CompareAndSwap(idPtr2, Const(0), threadId);
|
||||||
|
|
||||||
|
Operand idNot0Label = Label();
|
||||||
|
|
||||||
|
// If it was 0, then we need to initialize the struct entry and return i.
|
||||||
|
context.BranchIfFalse(idNot0Label, context.ICompareEqual(existingId2, Const(0)));
|
||||||
|
|
||||||
|
Operand structsPtr = Const((ulong)IntPtr.Add(threadLocalMapPtr, ThreadLocalMap<int>.StructsOffset));
|
||||||
|
Operand structPtr = context.Add(structsPtr, context.SignExtend32(OperandType.I64, offset2));
|
||||||
|
context.Store(structPtr, initialState);
|
||||||
|
|
||||||
|
context.Branch(endLabel);
|
||||||
|
|
||||||
|
context.MarkLabel(idNot0Label);
|
||||||
|
|
||||||
|
context.Copy(i, context.Add(i, Const(1)));
|
||||||
|
|
||||||
|
context.BranchIfTrue(loop2Label, context.ICompareLess(i, Const(ThreadLocalMap<int>.MapSize)));
|
||||||
|
|
||||||
|
context.Copy(i, Const(-1)); // Could not place the thread in the list.
|
||||||
|
|
||||||
|
context.MarkLabel(endLabel);
|
||||||
|
|
||||||
|
return context.Copy(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Operand EmitThreadLocalMapIntGetValuePtr(EmitterContext context, IntPtr threadLocalMapPtr, Operand index)
|
||||||
|
{
|
||||||
|
Operand offset = context.Multiply(index, Const(sizeof(int)));
|
||||||
|
Operand structsPtr = Const((ulong)IntPtr.Add(threadLocalMapPtr, ThreadLocalMap<int>.StructsOffset));
|
||||||
|
|
||||||
|
return context.Add(structsPtr, context.SignExtend32(OperandType.I64, offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EmitThreadLocalMapIntRelease(EmitterContext context, IntPtr threadLocalMapPtr, Operand threadId, Operand index)
|
||||||
|
{
|
||||||
|
Operand offset = context.Multiply(index, Const(sizeof(int)));
|
||||||
|
Operand idsPtr = Const((ulong)IntPtr.Add(threadLocalMapPtr, ThreadLocalMap<int>.ThreadIdsOffset));
|
||||||
|
Operand idPtr = context.Add(idsPtr, context.SignExtend32(OperandType.I64, offset));
|
||||||
|
|
||||||
|
context.CompareAndSwap(idPtr, threadId, Const(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EmitAtomicAddI32(EmitterContext context, Operand ptr, Operand additive)
|
||||||
|
{
|
||||||
|
Operand loop = Label();
|
||||||
|
context.MarkLabel(loop);
|
||||||
|
|
||||||
|
Operand initial = context.Load(OperandType.I32, ptr);
|
||||||
|
Operand newValue = context.Add(initial, additive);
|
||||||
|
|
||||||
|
Operand replaced = context.CompareAndSwap(ptr, initial, newValue);
|
||||||
|
|
||||||
|
context.BranchIfFalse(loop, context.ICompareEqual(initial, replaced));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EmitNativeReaderLockAcquire(EmitterContext context, IntPtr nativeReaderLockPtr)
|
||||||
|
{
|
||||||
|
Operand writeLockPtr = Const((ulong)IntPtr.Add(nativeReaderLockPtr, NativeReaderWriterLock.WriteLockOffset));
|
||||||
|
|
||||||
|
// Spin until we can acquire the write lock.
|
||||||
|
Operand spinLabel = Label();
|
||||||
|
context.MarkLabel(spinLabel);
|
||||||
|
|
||||||
|
// Old value must be 0 to continue (we gained the write lock)
|
||||||
|
context.BranchIfTrue(spinLabel, context.CompareAndSwap(writeLockPtr, Const(0), Const(1)));
|
||||||
|
|
||||||
|
// Increment reader count.
|
||||||
|
EmitAtomicAddI32(context, Const((ulong)IntPtr.Add(nativeReaderLockPtr, NativeReaderWriterLock.ReaderCountOffset)), Const(1));
|
||||||
|
|
||||||
|
// Release write lock.
|
||||||
|
context.CompareAndSwap(writeLockPtr, Const(1), Const(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EmitNativeReaderLockRelease(EmitterContext context, IntPtr nativeReaderLockPtr)
|
||||||
|
{
|
||||||
|
// Decrement reader count.
|
||||||
|
EmitAtomicAddI32(context, Const((ulong)IntPtr.Add(nativeReaderLockPtr, NativeReaderWriterLock.ReaderCountOffset)), Const(-1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace ARMeilleure.Signal
|
namespace ARMeilleure.Signal
|
||||||
{
|
{
|
||||||
class WindowsSignalHandlerRegistration
|
unsafe class WindowsSignalHandlerRegistration
|
||||||
{
|
{
|
||||||
[DllImport("kernel32.dll")]
|
[DllImport("kernel32.dll")]
|
||||||
private static extern IntPtr AddVectoredExceptionHandler(uint first, IntPtr handler);
|
private static extern IntPtr AddVectoredExceptionHandler(uint first, IntPtr handler);
|
||||||
@ -11,6 +11,14 @@ namespace ARMeilleure.Signal
|
|||||||
[DllImport("kernel32.dll")]
|
[DllImport("kernel32.dll")]
|
||||||
private static extern ulong RemoveVectoredExceptionHandler(IntPtr handle);
|
private static extern ulong RemoveVectoredExceptionHandler(IntPtr handle);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)]
|
||||||
|
static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
|
||||||
|
private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
|
||||||
|
|
||||||
|
private static IntPtr _getCurrentThreadIdPtr;
|
||||||
|
|
||||||
public static IntPtr RegisterExceptionHandler(IntPtr action)
|
public static IntPtr RegisterExceptionHandler(IntPtr action)
|
||||||
{
|
{
|
||||||
return AddVectoredExceptionHandler(1, action);
|
return AddVectoredExceptionHandler(1, action);
|
||||||
@ -20,5 +28,17 @@ namespace ARMeilleure.Signal
|
|||||||
{
|
{
|
||||||
return RemoveVectoredExceptionHandler(handle) != 0;
|
return RemoveVectoredExceptionHandler(handle) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IntPtr GetCurrentThreadIdFunc()
|
||||||
|
{
|
||||||
|
if (_getCurrentThreadIdPtr == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
IntPtr handle = LoadLibrary("kernel32.dll");
|
||||||
|
|
||||||
|
_getCurrentThreadIdPtr = GetProcAddress(handle, "GetCurrentThreadId");
|
||||||
|
}
|
||||||
|
|
||||||
|
return _getCurrentThreadIdPtr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ namespace ARMeilleure.Translation
|
|||||||
public BasicBlock Entry { get; }
|
public BasicBlock Entry { get; }
|
||||||
public IntrusiveList<BasicBlock> Blocks { get; }
|
public IntrusiveList<BasicBlock> Blocks { get; }
|
||||||
public BasicBlock[] PostOrderBlocks => _postOrderBlocks;
|
public BasicBlock[] PostOrderBlocks => _postOrderBlocks;
|
||||||
public int[] PostOrderMap => _postOrderMap;
|
public int[] PostOrderMap => _postOrderMap;
|
||||||
|
|
||||||
public ControlFlowGraph(BasicBlock entry, IntrusiveList<BasicBlock> blocks, int localsCount)
|
public ControlFlowGraph(BasicBlock entry, IntrusiveList<BasicBlock> blocks, int localsCount)
|
||||||
{
|
{
|
||||||
|
@ -19,8 +19,6 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
public int Count => _count;
|
public int Count => _count;
|
||||||
|
|
||||||
public IntervalTree() { }
|
|
||||||
|
|
||||||
#region Public Methods
|
#region Public Methods
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -344,7 +342,7 @@ namespace ARMeilleure.Translation
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes the value from the dictionary after searching for it with <paramref name="key">.
|
/// Removes the value from the dictionary after searching for it with <paramref name="key"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key">Key to search for</param>
|
/// <param name="key">Key to search for</param>
|
||||||
/// <returns>Number of deleted values</returns>
|
/// <returns>Number of deleted values</returns>
|
||||||
|
@ -27,7 +27,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
||||||
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
||||||
|
|
||||||
private const uint InternalVersion = 3439; //! To be incremented manually for each change to the ARMeilleure project.
|
private const uint InternalVersion = 3585; //! To be incremented manually for each change to the ARMeilleure project.
|
||||||
|
|
||||||
private const string ActualDir = "0";
|
private const string ActualDir = "0";
|
||||||
private const string BackupDir = "1";
|
private const string BackupDir = "1";
|
||||||
@ -946,9 +946,12 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
return BitConverter.IsLittleEndian;
|
return BitConverter.IsLittleEndian;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ulong GetFeatureInfo()
|
private static FeatureInfo GetFeatureInfo()
|
||||||
{
|
{
|
||||||
return (ulong)HardwareCapabilities.FeatureInfoEdx << 32 | (uint)HardwareCapabilities.FeatureInfoEcx;
|
return new FeatureInfo(
|
||||||
|
(uint)HardwareCapabilities.FeatureInfo1Ecx,
|
||||||
|
(uint)HardwareCapabilities.FeatureInfo1Edx,
|
||||||
|
(uint)HardwareCapabilities.FeatureInfo7Ebx);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte GetMemoryManagerMode()
|
private static byte GetMemoryManagerMode()
|
||||||
@ -968,7 +971,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
return osPlatform;
|
return osPlatform;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 50*/)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 54*/)]
|
||||||
private struct OuterHeader
|
private struct OuterHeader
|
||||||
{
|
{
|
||||||
public ulong Magic;
|
public ulong Magic;
|
||||||
@ -976,7 +979,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
public uint CacheFileVersion;
|
public uint CacheFileVersion;
|
||||||
|
|
||||||
public bool Endianness;
|
public bool Endianness;
|
||||||
public ulong FeatureInfo;
|
public FeatureInfo FeatureInfo;
|
||||||
public byte MemoryManagerMode;
|
public byte MemoryManagerMode;
|
||||||
public uint OSPlatform;
|
public uint OSPlatform;
|
||||||
|
|
||||||
@ -999,6 +1002,9 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 12*/)]
|
||||||
|
private record struct FeatureInfo(uint FeatureInfo0, uint FeatureInfo1, uint FeatureInfo2);
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 128*/)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 128*/)]
|
||||||
private struct InnerHeader
|
private struct InnerHeader
|
||||||
{
|
{
|
||||||
|
@ -4,7 +4,6 @@ using Ryujinx.Memory;
|
|||||||
using Ryujinx.SDL2.Common;
|
using Ryujinx.SDL2.Common;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
using static Ryujinx.Audio.Integration.IHardwareDeviceDriver;
|
using static Ryujinx.Audio.Integration.IHardwareDeviceDriver;
|
||||||
|
@ -4,7 +4,6 @@ using Ryujinx.Common.Logging;
|
|||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
using static SDL2.SDL;
|
using static SDL2.SDL;
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using System;
|
namespace SoundIOSharp
|
||||||
namespace SoundIOSharp
|
|
||||||
{
|
{
|
||||||
public struct SoundIOSampleRateRange
|
public struct SoundIOSampleRateRange
|
||||||
{
|
{
|
||||||
|
@ -129,4 +129,4 @@ namespace Ryujinx.Audio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -23,4 +23,4 @@ namespace Ryujinx.Audio.Backends.Common
|
|||||||
return bufferSize / GetSampleSize(format) / channelCount;
|
return bufferSize / GetSampleSize(format) / channelCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -163,4 +163,4 @@ namespace Ryujinx.Audio.Backends.Common
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -76,4 +76,4 @@ namespace Ryujinx.Audio.Backends.Common
|
|||||||
|
|
||||||
public virtual void UnregisterBuffer(AudioBuffer buffer) { }
|
public virtual void UnregisterBuffer(AudioBuffer buffer) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -133,4 +133,4 @@ namespace Ryujinx.Audio.Backends.CompatLayer
|
|||||||
return direction == Direction.Input || direction == Direction.Output;
|
return direction == Direction.Input || direction == Direction.Output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -81,7 +81,7 @@ namespace Ryujinx.Audio.Backends.CompatLayer
|
|||||||
{
|
{
|
||||||
BufferTag = buffer.BufferTag,
|
BufferTag = buffer.BufferTag,
|
||||||
DataPointer = buffer.DataPointer,
|
DataPointer = buffer.DataPointer,
|
||||||
DataSize = (ulong)downmixedBuffer.Length
|
DataSize = (ulong)downmixedBuffer.Length
|
||||||
};
|
};
|
||||||
|
|
||||||
bool result = _realSession.RegisterBuffer(fakeBuffer, downmixedBuffer);
|
bool result = _realSession.RegisterBuffer(fakeBuffer, downmixedBuffer);
|
||||||
@ -120,4 +120,4 @@ namespace Ryujinx.Audio.Backends.CompatLayer
|
|||||||
return _realSession.WasBufferFullyConsumed(buffer);
|
return _realSession.WasBufferFullyConsumed(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -24,11 +24,11 @@ namespace Ryujinx.Audio.Backends.CompatLayer
|
|||||||
public short Right;
|
public short Right;
|
||||||
}
|
}
|
||||||
|
|
||||||
private const int Q15Bits = 16;
|
private const int Q15Bits = 16;
|
||||||
private const int RawQ15One = 1 << Q15Bits;
|
private const int RawQ15One = 1 << Q15Bits;
|
||||||
private const int RawQ15HalfOne = (int)(0.5f * RawQ15One);
|
private const int RawQ15HalfOne = (int)(0.5f * RawQ15One);
|
||||||
private const int Minus3dBInQ15 = (int)(0.707f * RawQ15One);
|
private const int Minus3dBInQ15 = (int)(0.707f * RawQ15One);
|
||||||
private const int Minus6dBInQ15 = (int)(0.501f * RawQ15One);
|
private const int Minus6dBInQ15 = (int)(0.501f * RawQ15One);
|
||||||
private const int Minus12dBInQ15 = (int)(0.251f * RawQ15One);
|
private const int Minus12dBInQ15 = (int)(0.251f * RawQ15One);
|
||||||
|
|
||||||
private static readonly int[] DefaultSurroundToStereoCoefficients = new int[4]
|
private static readonly int[] DefaultSurroundToStereoCoefficients = new int[4]
|
||||||
@ -46,8 +46,8 @@ namespace Ryujinx.Audio.Backends.CompatLayer
|
|||||||
};
|
};
|
||||||
|
|
||||||
private const int SurroundChannelCount = 6;
|
private const int SurroundChannelCount = 6;
|
||||||
private const int StereoChannelCount = 2;
|
private const int StereoChannelCount = 2;
|
||||||
private const int MonoChannelCount = 1;
|
private const int MonoChannelCount = 1;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static ReadOnlySpan<Channel51FormatPCM16> GetSurroundBuffer(ReadOnlySpan<short> data)
|
private static ReadOnlySpan<Channel51FormatPCM16> GetSurroundBuffer(ReadOnlySpan<short> data)
|
||||||
@ -86,7 +86,7 @@ namespace Ryujinx.Audio.Backends.CompatLayer
|
|||||||
{
|
{
|
||||||
Channel51FormatPCM16 channel = channels[i];
|
Channel51FormatPCM16 channel = channels[i];
|
||||||
|
|
||||||
downmixedBuffer[i * 2] = DownMixSurroundToStereo(coefficients, channel.BackLeft, channel.LowFrequency, channel.FrontCenter, channel.FrontLeft);
|
downmixedBuffer[i * 2] = DownMixSurroundToStereo(coefficients, channel.BackLeft, channel.LowFrequency, channel.FrontCenter, channel.FrontLeft);
|
||||||
downmixedBuffer[i * 2 + 1] = DownMixSurroundToStereo(coefficients, channel.BackRight, channel.LowFrequency, channel.FrontCenter, channel.FrontRight);
|
downmixedBuffer[i * 2 + 1] = DownMixSurroundToStereo(coefficients, channel.BackRight, channel.LowFrequency, channel.FrontCenter, channel.FrontRight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,4 +122,4 @@ namespace Ryujinx.Audio.Backends.CompatLayer
|
|||||||
return DownMixSurroundToStereo(DefaultSurroundToStereoCoefficients, data);
|
return DownMixSurroundToStereo(DefaultSurroundToStereoCoefficients, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -84,4 +84,4 @@ namespace Ryujinx.Audio.Backends.Dummy
|
|||||||
return channelCount == 1 || channelCount == 2 || channelCount == 6;
|
return channelCount == 1 || channelCount == 2 || channelCount == 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -64,4 +64,4 @@ namespace Ryujinx.Audio.Backends.Dummy
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -34,4 +34,4 @@ namespace Ryujinx.Audio.Common
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public byte[] Data;
|
public byte[] Data;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -513,4 +513,4 @@ namespace Ryujinx.Audio.Common
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -15,4 +15,4 @@ namespace Ryujinx.Audio.Common
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Stopped
|
Stopped
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -26,4 +26,4 @@ namespace Ryujinx.Audio.Common
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private ushort _reserved;
|
private ushort _reserved;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -34,4 +34,4 @@ namespace Ryujinx.Audio.Common
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public AudioDeviceState AudioOutState;
|
public AudioDeviceState AudioOutState;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -33,4 +33,4 @@ namespace Ryujinx.Audio.Common
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ulong DataOffset;
|
public ulong DataOffset;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -40,4 +40,4 @@ namespace Ryujinx.Audio.Common
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Adpcm = 6
|
Adpcm = 6
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -172,4 +172,4 @@ namespace Ryujinx.Audio
|
|||||||
0.707f,
|
0.707f,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -214,9 +214,9 @@ namespace Ryujinx.Audio.Input
|
|||||||
outputDeviceName = audioIn.DeviceName;
|
outputDeviceName = audioIn.DeviceName;
|
||||||
outputConfiguration = new AudioOutputConfiguration
|
outputConfiguration = new AudioOutputConfiguration
|
||||||
{
|
{
|
||||||
ChannelCount = audioIn.ChannelCount,
|
ChannelCount = audioIn.ChannelCount,
|
||||||
SampleFormat = audioIn.SampleFormat,
|
SampleFormat = audioIn.SampleFormat,
|
||||||
SampleRate = audioIn.SampleRate,
|
SampleRate = audioIn.SampleRate,
|
||||||
AudioOutState = audioIn.GetState(),
|
AudioOutState = audioIn.GetState(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -263,4 +263,4 @@ namespace Ryujinx.Audio.Input
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -389,4 +389,4 @@ namespace Ryujinx.Audio.Input
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -32,8 +32,8 @@ namespace Ryujinx.Audio.Integration
|
|||||||
_session.QueueBuffer(new AudioBuffer
|
_session.QueueBuffer(new AudioBuffer
|
||||||
{
|
{
|
||||||
DataPointer = _currentBufferTag++,
|
DataPointer = _currentBufferTag++,
|
||||||
Data = _buffer,
|
Data = _buffer,
|
||||||
DataSize = (ulong)_buffer.Length,
|
DataSize = (ulong)_buffer.Length,
|
||||||
});
|
});
|
||||||
|
|
||||||
_currentBufferTag = _currentBufferTag % 4;
|
_currentBufferTag = _currentBufferTag % 4;
|
||||||
@ -72,4 +72,4 @@ namespace Ryujinx.Audio.Integration
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -52,4 +52,4 @@ namespace Ryujinx.Audio.Integration
|
|||||||
return channelCount != Constants.ChannelCountMax;
|
return channelCount != Constants.ChannelCountMax;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -31,4 +31,4 @@ namespace Ryujinx.Audio.Integration
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -25,4 +25,4 @@ namespace Ryujinx.Audio.Integration
|
|||||||
|
|
||||||
void PrepareToClose();
|
void PrepareToClose();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -15,4 +15,4 @@ namespace Ryujinx.Audio.Integration
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
void Clear();
|
void Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -209,9 +209,9 @@ namespace Ryujinx.Audio.Output
|
|||||||
outputDeviceName = audioOut.DeviceName;
|
outputDeviceName = audioOut.DeviceName;
|
||||||
outputConfiguration = new AudioOutputConfiguration
|
outputConfiguration = new AudioOutputConfiguration
|
||||||
{
|
{
|
||||||
ChannelCount = audioOut.ChannelCount,
|
ChannelCount = audioOut.ChannelCount,
|
||||||
SampleFormat = audioOut.SampleFormat,
|
SampleFormat = audioOut.SampleFormat,
|
||||||
SampleRate = audioOut.SampleRate,
|
SampleRate = audioOut.SampleRate,
|
||||||
AudioOutState = audioOut.GetState(),
|
AudioOutState = audioOut.GetState(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -293,4 +293,4 @@ namespace Ryujinx.Audio.Output
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -169,7 +169,7 @@ namespace Ryujinx.Audio.Output
|
|||||||
}
|
}
|
||||||
|
|
||||||
SampleFormat = sampleFormat;
|
SampleFormat = sampleFormat;
|
||||||
SampleRate = Constants.TargetSampleRate;
|
SampleRate = Constants.TargetSampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -187,9 +187,9 @@ namespace Ryujinx.Audio.Output
|
|||||||
{
|
{
|
||||||
AudioBuffer buffer = new AudioBuffer
|
AudioBuffer buffer = new AudioBuffer
|
||||||
{
|
{
|
||||||
BufferTag = bufferTag,
|
BufferTag = bufferTag,
|
||||||
DataPointer = userBuffer.Data,
|
DataPointer = userBuffer.Data,
|
||||||
DataSize = userBuffer.DataSize
|
DataSize = userBuffer.DataSize
|
||||||
};
|
};
|
||||||
|
|
||||||
if (_session.AppendBuffer(buffer))
|
if (_session.AppendBuffer(buffer))
|
||||||
@ -291,7 +291,7 @@ namespace Ryujinx.Audio.Output
|
|||||||
{
|
{
|
||||||
lock (_parentLock)
|
lock (_parentLock)
|
||||||
{
|
{
|
||||||
_session.SetVolume(volume);
|
_session.SetVolume(volume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,4 +362,4 @@ namespace Ryujinx.Audio.Output
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,4 +10,4 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
public ulong ReturnBufferInfo;
|
public ulong ReturnBufferInfo;
|
||||||
public ulong ReturnBufferInfoBase;
|
public ulong ReturnBufferInfoBase;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -47,4 +47,4 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
public ulong ExtraErrorInfo;
|
public ulong ExtraErrorInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -147,4 +147,4 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
return _nodeCount;
|
return _nodeCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -50,4 +50,4 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
CaptureBuffer
|
CaptureBuffer
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -40,4 +40,4 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Released = 6
|
Released = 6
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -25,4 +25,4 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
return (nodeId >> 16) & 0xFFF;
|
return (nodeId >> 16) & 0xFFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -30,4 +30,4 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Performance = 15
|
Performance = 15
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -226,4 +226,4 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -16,4 +16,4 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
Limiter,
|
Limiter,
|
||||||
CaptureBuffer
|
CaptureBuffer
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,4 +8,4 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
FinalMix,
|
FinalMix,
|
||||||
Sink
|
Sink
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,4 +20,4 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Pause
|
Pause
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -30,4 +30,4 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Disabled
|
Disabled
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -35,4 +35,4 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Limit = NoDelay
|
Limit = NoDelay
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,4 +20,4 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
CircularBuffer
|
CircularBuffer
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -30,4 +30,4 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
TotalSize = (uint)Unsafe.SizeOf<UpdateDataHeader>();
|
TotalSize = (uint)Unsafe.SizeOf<UpdateDataHeader>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -101,4 +101,4 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -79,4 +79,4 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private ushort _padding;
|
private ushort _padding;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -41,7 +41,7 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
return Memory<byte>.Empty;
|
return Memory<byte>.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Memory<T> Allocate<T>(ulong count, int align) where T: unmanaged
|
public Memory<T> Allocate<T>(ulong count, int align) where T : unmanaged
|
||||||
{
|
{
|
||||||
Memory<byte> allocatedMemory = Allocate((ulong)Unsafe.SizeOf<T>() * count, align);
|
Memory<byte> allocatedMemory = Allocate((ulong)Unsafe.SizeOf<T>() * count, align);
|
||||||
|
|
||||||
@ -53,9 +53,9 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
return SpanMemoryManager<T>.Cast(allocatedMemory);
|
return SpanMemoryManager<T>.Cast(allocatedMemory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ulong GetTargetSize<T>(ulong currentSize, ulong count, int align) where T: unmanaged
|
public static ulong GetTargetSize<T>(ulong currentSize, ulong count, int align) where T : unmanaged
|
||||||
{
|
{
|
||||||
return BitUtils.AlignUp(currentSize, align) + (ulong)Unsafe.SizeOf<T>() * count;
|
return BitUtils.AlignUp(currentSize, align) + (ulong)Unsafe.SizeOf<T>() * count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -86,4 +86,4 @@ namespace Ryujinx.Audio.Renderer.Device
|
|||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -24,4 +24,4 @@ namespace Ryujinx.Audio.Renderer.Device
|
|||||||
Device = virtualDevice;
|
Device = virtualDevice;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -59,4 +59,4 @@ namespace Ryujinx.Audio.Renderer.Device
|
|||||||
return virtualDeviceSession;
|
return virtualDeviceSession;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -199,4 +199,4 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
return decodedCount;
|
return decodedCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -268,4 +268,4 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -80,4 +80,4 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -72,4 +72,4 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
DataSourceHelper.ProcessWaveBuffers(context.MemoryManager, outputBuffer, ref info, WaveBuffers, ref State.Span[0], context.SampleRate, (int)context.SampleCount);
|
DataSourceHelper.ProcessWaveBuffers(context.MemoryManager, outputBuffer, ref info, WaveBuffers, ref State.Span[0], context.SampleRate, (int)context.SampleCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -170,4 +170,4 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,6 @@
|
|||||||
using Ryujinx.Audio.Renderer.Dsp.State;
|
using Ryujinx.Audio.Renderer.Dsp.State;
|
||||||
using Ryujinx.Audio.Renderer.Parameter;
|
using Ryujinx.Audio.Renderer.Parameter;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Renderer.Dsp.Command
|
namespace Ryujinx.Audio.Renderer.Dsp.Command
|
||||||
{
|
{
|
||||||
@ -49,4 +48,4 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
BiquadFilterHelper.ProcessBiquadFilter(ref _parameter, ref state, outputBuffer, inputBuffer, context.SampleCount);
|
BiquadFilterHelper.ProcessBiquadFilter(ref _parameter, ref state, outputBuffer, inputBuffer, context.SampleCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,4 @@
|
|||||||
using Ryujinx.Audio.Renderer.Dsp.State;
|
using Ryujinx.Audio.Renderer.Dsp.State;
|
||||||
using Ryujinx.Audio.Renderer.Parameter;
|
|
||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
@ -134,4 +133,4 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user