aboutsummaryrefslogtreecommitdiff
path: root/src/ARMeilleure/Instructions/InstEmitSimdHelper.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/ARMeilleure/Instructions/InstEmitSimdHelper.cs')
-rw-r--r--src/ARMeilleure/Instructions/InstEmitSimdHelper.cs174
1 files changed, 97 insertions, 77 deletions
diff --git a/src/ARMeilleure/Instructions/InstEmitSimdHelper.cs b/src/ARMeilleure/Instructions/InstEmitSimdHelper.cs
index c44c9b4d..35052ad1 100644
--- a/src/ARMeilleure/Instructions/InstEmitSimdHelper.cs
+++ b/src/ARMeilleure/Instructions/InstEmitSimdHelper.cs
@@ -6,7 +6,6 @@ using ARMeilleure.Translation;
using System;
using System.Diagnostics;
using System.Reflection;
-
using static ARMeilleure.Instructions.InstEmitHelper;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
@@ -18,19 +17,19 @@ namespace ARMeilleure.Instructions
static class InstEmitSimdHelper
{
-#region "Masks"
+ #region "Masks"
public static readonly long[] EvenMasks = new long[]
{
14L << 56 | 12L << 48 | 10L << 40 | 08L << 32 | 06L << 24 | 04L << 16 | 02L << 8 | 00L << 0, // B
13L << 56 | 12L << 48 | 09L << 40 | 08L << 32 | 05L << 24 | 04L << 16 | 01L << 8 | 00L << 0, // H
- 11L << 56 | 10L << 48 | 09L << 40 | 08L << 32 | 03L << 24 | 02L << 16 | 01L << 8 | 00L << 0 // S
+ 11L << 56 | 10L << 48 | 09L << 40 | 08L << 32 | 03L << 24 | 02L << 16 | 01L << 8 | 00L << 0, // S
};
public static readonly long[] OddMasks = new long[]
{
15L << 56 | 13L << 48 | 11L << 40 | 09L << 32 | 07L << 24 | 05L << 16 | 03L << 8 | 01L << 0, // B
15L << 56 | 14L << 48 | 11L << 40 | 10L << 32 | 07L << 24 | 06L << 16 | 03L << 8 | 02L << 0, // H
- 15L << 56 | 14L << 48 | 13L << 40 | 12L << 32 | 07L << 24 | 06L << 16 | 05L << 8 | 04L << 0 // S
+ 15L << 56 | 14L << 48 | 13L << 40 | 12L << 32 | 07L << 24 | 06L << 16 | 05L << 8 | 04L << 0, // S
};
public static readonly long ZeroMask = 128L << 56 | 128L << 48 | 128L << 40 | 128L << 32 | 128L << 24 | 128L << 16 | 128L << 8 | 128L << 0;
@@ -38,19 +37,19 @@ namespace ARMeilleure.Instructions
public static ulong X86GetGf2p8LogicalShiftLeft(int shift)
{
ulong identity = (0b00000001UL << 56) | (0b00000010UL << 48) | (0b00000100UL << 40) | (0b00001000UL << 32) |
- (0b00010000UL << 24) | (0b00100000UL << 16) | (0b01000000UL << 8) | (0b10000000UL << 0);
+ (0b00010000UL << 24) | (0b00100000UL << 16) | (0b01000000UL << 8) | (0b10000000UL << 0);
return shift >= 0 ? identity >> (shift * 8) : identity << (-shift * 8);
}
-#endregion
+ #endregion
-#region "X86 SSE Intrinsics"
+ #region "X86 SSE Intrinsics"
public static readonly Intrinsic[] X86PaddInstruction = new Intrinsic[]
{
Intrinsic.X86Paddb,
Intrinsic.X86Paddw,
Intrinsic.X86Paddd,
- Intrinsic.X86Paddq
+ Intrinsic.X86Paddq,
};
public static readonly Intrinsic[] X86PcmpeqInstruction = new Intrinsic[]
@@ -58,7 +57,7 @@ namespace ARMeilleure.Instructions
Intrinsic.X86Pcmpeqb,
Intrinsic.X86Pcmpeqw,
Intrinsic.X86Pcmpeqd,
- Intrinsic.X86Pcmpeqq
+ Intrinsic.X86Pcmpeqq,
};
public static readonly Intrinsic[] X86PcmpgtInstruction = new Intrinsic[]
@@ -66,49 +65,49 @@ namespace ARMeilleure.Instructions
Intrinsic.X86Pcmpgtb,
Intrinsic.X86Pcmpgtw,
Intrinsic.X86Pcmpgtd,
- Intrinsic.X86Pcmpgtq
+ Intrinsic.X86Pcmpgtq,
};
public static readonly Intrinsic[] X86PmaxsInstruction = new Intrinsic[]
{
Intrinsic.X86Pmaxsb,
Intrinsic.X86Pmaxsw,
- Intrinsic.X86Pmaxsd
+ Intrinsic.X86Pmaxsd,
};
public static readonly Intrinsic[] X86PmaxuInstruction = new Intrinsic[]
{
Intrinsic.X86Pmaxub,
Intrinsic.X86Pmaxuw,
- Intrinsic.X86Pmaxud
+ Intrinsic.X86Pmaxud,
};
public static readonly Intrinsic[] X86PminsInstruction = new Intrinsic[]
{
Intrinsic.X86Pminsb,
Intrinsic.X86Pminsw,
- Intrinsic.X86Pminsd
+ Intrinsic.X86Pminsd,
};
public static readonly Intrinsic[] X86PminuInstruction = new Intrinsic[]
{
Intrinsic.X86Pminub,
Intrinsic.X86Pminuw,
- Intrinsic.X86Pminud
+ Intrinsic.X86Pminud,
};
public static readonly Intrinsic[] X86PmovsxInstruction = new Intrinsic[]
{
Intrinsic.X86Pmovsxbw,
Intrinsic.X86Pmovsxwd,
- Intrinsic.X86Pmovsxdq
+ Intrinsic.X86Pmovsxdq,
};
public static readonly Intrinsic[] X86PmovzxInstruction = new Intrinsic[]
{
Intrinsic.X86Pmovzxbw,
Intrinsic.X86Pmovzxwd,
- Intrinsic.X86Pmovzxdq
+ Intrinsic.X86Pmovzxdq,
};
public static readonly Intrinsic[] X86PsllInstruction = new Intrinsic[]
@@ -116,14 +115,14 @@ namespace ARMeilleure.Instructions
0,
Intrinsic.X86Psllw,
Intrinsic.X86Pslld,
- Intrinsic.X86Psllq
+ Intrinsic.X86Psllq,
};
public static readonly Intrinsic[] X86PsraInstruction = new Intrinsic[]
{
0,
Intrinsic.X86Psraw,
- Intrinsic.X86Psrad
+ Intrinsic.X86Psrad,
};
public static readonly Intrinsic[] X86PsrlInstruction = new Intrinsic[]
@@ -131,7 +130,7 @@ namespace ARMeilleure.Instructions
0,
Intrinsic.X86Psrlw,
Intrinsic.X86Psrld,
- Intrinsic.X86Psrlq
+ Intrinsic.X86Psrlq,
};
public static readonly Intrinsic[] X86PsubInstruction = new Intrinsic[]
@@ -139,7 +138,7 @@ namespace ARMeilleure.Instructions
Intrinsic.X86Psubb,
Intrinsic.X86Psubw,
Intrinsic.X86Psubd,
- Intrinsic.X86Psubq
+ Intrinsic.X86Psubq,
};
public static readonly Intrinsic[] X86PunpckhInstruction = new Intrinsic[]
@@ -147,7 +146,7 @@ namespace ARMeilleure.Instructions
Intrinsic.X86Punpckhbw,
Intrinsic.X86Punpckhwd,
Intrinsic.X86Punpckhdq,
- Intrinsic.X86Punpckhqdq
+ Intrinsic.X86Punpckhqdq,
};
public static readonly Intrinsic[] X86PunpcklInstruction = new Intrinsic[]
@@ -155,9 +154,9 @@ namespace ARMeilleure.Instructions
Intrinsic.X86Punpcklbw,
Intrinsic.X86Punpcklwd,
Intrinsic.X86Punpckldq,
- Intrinsic.X86Punpcklqdq
+ Intrinsic.X86Punpcklqdq,
};
-#endregion
+ #endregion
public static void EnterArmFpMode(EmitterContext context, Func<FPState, Operand> getFpFlag)
{
@@ -310,15 +309,16 @@ namespace ARMeilleure.Instructions
public static int X86GetRoundControl(FPRoundingMode roundMode)
{
- switch (roundMode)
+ return roundMode switch
{
- case FPRoundingMode.ToNearest: return 8 | 0; // even
- case FPRoundingMode.TowardsPlusInfinity: return 8 | 2;
- case FPRoundingMode.TowardsMinusInfinity: return 8 | 1;
- case FPRoundingMode.TowardsZero: return 8 | 3;
- }
-
- throw new ArgumentException($"Invalid rounding mode \"{roundMode}\".");
+#pragma warning disable IDE0055 // Disable formatting
+ FPRoundingMode.ToNearest => 8 | 0, // even
+ FPRoundingMode.TowardsPlusInfinity => 8 | 2,
+ FPRoundingMode.TowardsMinusInfinity => 8 | 1,
+ FPRoundingMode.TowardsZero => 8 | 3,
+ _ => throw new ArgumentException($"Invalid rounding mode \"{roundMode}\"."),
+#pragma warning restore IDE0055
+ };
}
public static Operand EmitSse41RoundToNearestWithTiesToAwayOpF(ArmEmitterContext context, Operand n, bool scalar)
@@ -334,11 +334,11 @@ namespace ARMeilleure.Instructions
if ((op.Size & 1) == 0)
{
Operand signMask = scalar ? X86GetScalar(context, int.MinValue) : X86GetAllElements(context, int.MinValue);
- signMask = context.AddIntrinsic(Intrinsic.X86Pand, signMask, nCopy);
+ signMask = context.AddIntrinsic(Intrinsic.X86Pand, signMask, nCopy);
// 0x3EFFFFFF == BitConverter.SingleToInt32Bits(0.5f) - 1
Operand valueMask = scalar ? X86GetScalar(context, 0x3EFFFFFF) : X86GetAllElements(context, 0x3EFFFFFF);
- valueMask = context.AddIntrinsic(Intrinsic.X86Por, valueMask, signMask);
+ valueMask = context.AddIntrinsic(Intrinsic.X86Por, valueMask, signMask);
nCopy = context.AddIntrinsic(scalar ? Intrinsic.X86Addss : Intrinsic.X86Addps, nCopy, valueMask);
@@ -347,11 +347,11 @@ namespace ARMeilleure.Instructions
else
{
Operand signMask = scalar ? X86GetScalar(context, long.MinValue) : X86GetAllElements(context, long.MinValue);
- signMask = context.AddIntrinsic(Intrinsic.X86Pand, signMask, nCopy);
+ signMask = context.AddIntrinsic(Intrinsic.X86Pand, signMask, nCopy);
// 0x3FDFFFFFFFFFFFFFL == BitConverter.DoubleToInt64Bits(0.5d) - 1L
Operand valueMask = scalar ? X86GetScalar(context, 0x3FDFFFFFFFFFFFFFL) : X86GetAllElements(context, 0x3FDFFFFFFFFFFFFFL);
- valueMask = context.AddIntrinsic(Intrinsic.X86Por, valueMask, signMask);
+ valueMask = context.AddIntrinsic(Intrinsic.X86Por, valueMask, signMask);
nCopy = context.AddIntrinsic(scalar ? Intrinsic.X86Addsd : Intrinsic.X86Addpd, nCopy, valueMask);
@@ -461,7 +461,7 @@ namespace ARMeilleure.Instructions
MethodInfo info = (op.Size & 1) == 0
? typeof(MathF).GetMethod(name, new Type[] { typeof(float) })
- : typeof(Math). GetMethod(name, new Type[] { typeof(double) });
+ : typeof(Math).GetMethod(name, new Type[] { typeof(double) });
return context.Call(info, n);
}
@@ -473,8 +473,8 @@ namespace ARMeilleure.Instructions
string name = nameof(Math.Round);
MethodInfo info = (op.Size & 1) == 0
- ? typeof(MathF).GetMethod(name, new Type[] { typeof(float), typeof(MidpointRounding) })
- : typeof(Math). GetMethod(name, new Type[] { typeof(double), typeof(MidpointRounding) });
+ ? typeof(MathF).GetMethod(name, new Type[] { typeof(float), typeof(MidpointRounding) })
+ : typeof(Math).GetMethod(name, new Type[] { typeof(double), typeof(MidpointRounding) });
return context.Call(info, n, Const((int)roundMode));
}
@@ -482,7 +482,7 @@ namespace ARMeilleure.Instructions
public static Operand EmitGetRoundingMode(ArmEmitterContext context)
{
Operand rMode = context.ShiftLeft(GetFpFlag(FPState.RMode1Flag), Const(1));
- rMode = context.BitwiseOr(rMode, GetFpFlag(FPState.RMode0Flag));
+ rMode = context.BitwiseOr(rMode, GetFpFlag(FPState.RMode0Flag));
return rMode;
}
@@ -1015,8 +1015,8 @@ namespace ARMeilleure.Instructions
for (int index = 0; index < elems; index++)
{
- Operand ne = EmitVectorExtract(context, op.Rn, index, op.Size + 1, signed);
- Operand me = EmitVectorExtract(context, op.Rm, part + index, op.Size, signed);
+ Operand ne = EmitVectorExtract(context, op.Rn, index, op.Size + 1, signed);
+ Operand me = EmitVectorExtract(context, op.Rm, part + index, op.Size, signed);
res = EmitVectorInsert(context, res, emit(ne, me), index, op.Size + 1);
}
@@ -1077,9 +1077,9 @@ namespace ARMeilleure.Instructions
for (int index = 0; index < elems; index++)
{
- Operand de = EmitVectorExtract(context, op.Rd, index, op.Size + 1, signed);
- Operand ne = EmitVectorExtract(context, op.Rn, part + index, op.Size, signed);
- Operand me = EmitVectorExtract(context, op.Rm, part + index, op.Size, signed);
+ Operand de = EmitVectorExtract(context, op.Rd, index, op.Size + 1, signed);
+ Operand ne = EmitVectorExtract(context, op.Rn, part + index, op.Size, signed);
+ Operand me = EmitVectorExtract(context, op.Rm, part + index, op.Size, signed);
res = EmitVectorInsert(context, res, emit(de, ne, me), index, op.Size + 1);
}
@@ -1143,8 +1143,8 @@ namespace ARMeilleure.Instructions
for (int index = 0; index < elems; index++)
{
- Operand de = EmitVectorExtract(context, op.Rd, index, op.Size + 1, signed);
- Operand ne = EmitVectorExtract(context, op.Rn, part + index, op.Size, signed);
+ Operand de = EmitVectorExtract(context, op.Rd, index, op.Size + 1, signed);
+ Operand ne = EmitVectorExtract(context, op.Rn, part + index, op.Size, signed);
res = EmitVectorInsert(context, res, emit(de, ne, me), index, op.Size + 1);
}
@@ -1174,13 +1174,13 @@ namespace ARMeilleure.Instructions
{
int pairIndex = index << 1;
- Operand n0 = EmitVectorExtract(context, op.Rn, pairIndex, op.Size, signed);
+ Operand n0 = EmitVectorExtract(context, op.Rn, pairIndex, op.Size, signed);
Operand n1 = EmitVectorExtract(context, op.Rn, pairIndex + 1, op.Size, signed);
- Operand m0 = EmitVectorExtract(context, op.Rm, pairIndex, op.Size, signed);
+ Operand m0 = EmitVectorExtract(context, op.Rm, pairIndex, op.Size, signed);
Operand m1 = EmitVectorExtract(context, op.Rm, pairIndex + 1, op.Size, signed);
- res = EmitVectorInsert(context, res, emit(n0, n1), index, op.Size);
+ res = EmitVectorInsert(context, res, emit(n0, n1), index, op.Size);
res = EmitVectorInsert(context, res, emit(m0, m1), pairs + index, op.Size);
}
@@ -1197,11 +1197,11 @@ namespace ARMeilleure.Instructions
if (op.RegisterSize == RegisterSize.Simd64)
{
Operand zeroEvenMask = X86GetElements(context, ZeroMask, EvenMasks[op.Size]);
- Operand zeroOddMask = X86GetElements(context, ZeroMask, OddMasks [op.Size]);
+ Operand zeroOddMask = X86GetElements(context, ZeroMask, OddMasks[op.Size]);
Operand mN = context.AddIntrinsic(Intrinsic.X86Punpcklqdq, n, m); // m:n
- Operand left = context.AddIntrinsic(Intrinsic.X86Pshufb, mN, zeroEvenMask); // 0:even from m:n
+ Operand left = context.AddIntrinsic(Intrinsic.X86Pshufb, mN, zeroEvenMask); // 0:even from m:n
Operand right = context.AddIntrinsic(Intrinsic.X86Pshufb, mN, zeroOddMask); // 0:odd from m:n
context.Copy(GetVec(op.Rd), context.AddIntrinsic(inst[op.Size], left, right));
@@ -1213,14 +1213,14 @@ namespace ARMeilleure.Instructions
Operand oddEvenN = context.AddIntrinsic(Intrinsic.X86Pshufb, n, oddEvenMask); // odd:even from n
Operand oddEvenM = context.AddIntrinsic(Intrinsic.X86Pshufb, m, oddEvenMask); // odd:even from m
- Operand left = context.AddIntrinsic(Intrinsic.X86Punpcklqdq, oddEvenN, oddEvenM);
+ Operand left = context.AddIntrinsic(Intrinsic.X86Punpcklqdq, oddEvenN, oddEvenM);
Operand right = context.AddIntrinsic(Intrinsic.X86Punpckhqdq, oddEvenN, oddEvenM);
context.Copy(GetVec(op.Rd), context.AddIntrinsic(inst[op.Size], left, right));
}
else
{
- Operand left = context.AddIntrinsic(Intrinsic.X86Punpcklqdq, n, m);
+ Operand left = context.AddIntrinsic(Intrinsic.X86Punpcklqdq, n, m);
Operand right = context.AddIntrinsic(Intrinsic.X86Punpckhqdq, n, m);
context.Copy(GetVec(op.Rd), context.AddIntrinsic(inst[3], left, right));
@@ -1381,7 +1381,7 @@ namespace ARMeilleure.Instructions
Operand m0 = context.VectorExtract(type, GetVec(op.Rm), pairIndex);
Operand m1 = context.VectorExtract(type, GetVec(op.Rm), pairIndex + 1);
- res = context.VectorInsert(res, emit(n0, n1), index);
+ res = context.VectorInsert(res, emit(n0, n1), index);
res = context.VectorInsert(res, emit(m0, m1), pairs + index);
}
@@ -1433,18 +1433,18 @@ namespace ARMeilleure.Instructions
public enum CmpCondition
{
// Legacy Sse.
- Equal = 0, // Ordered, non-signaling.
- LessThan = 1, // Ordered, signaling.
- LessThanOrEqual = 2, // Ordered, signaling.
- UnorderedQ = 3, // Non-signaling.
- NotLessThan = 5, // Unordered, signaling.
+ Equal = 0, // Ordered, non-signaling.
+ LessThan = 1, // Ordered, signaling.
+ LessThanOrEqual = 2, // Ordered, signaling.
+ UnorderedQ = 3, // Non-signaling.
+ NotLessThan = 5, // Unordered, signaling.
NotLessThanOrEqual = 6, // Unordered, signaling.
- OrderedQ = 7, // Non-signaling.
+ OrderedQ = 7, // Non-signaling.
// Vex.
GreaterThanOrEqual = 13, // Ordered, signaling.
- GreaterThan = 14, // Ordered, signaling.
- OrderedS = 23 // Signaling.
+ GreaterThan = 14, // Ordered, signaling.
+ OrderedS = 23, // Signaling.
}
[Flags]
@@ -1459,7 +1459,7 @@ namespace ARMeilleure.Instructions
Add = 1 << 3,
Sub = 1 << 4,
- Accumulate = 1 << 5
+ Accumulate = 1 << 5,
}
public static void EmitScalarSaturatingUnaryOpSx(ArmEmitterContext context, Func1I emit)
@@ -1579,7 +1579,7 @@ namespace ARMeilleure.Instructions
{
Operand de;
Operand ne = EmitVectorExtract(context, op.Rn, index, op.Size, !signed);
- Operand me = EmitVectorExtract(context, op.Rd, index, op.Size, signed);
+ Operand me = EmitVectorExtract(context, op.Rd, index, op.Size, signed);
if (op.Size <= 2)
{
@@ -1627,7 +1627,7 @@ namespace ARMeilleure.Instructions
[Flags]
public enum SaturatingNarrowFlags
{
- Scalar = 1 << 0,
+ Scalar = 1 << 0,
SignedSrc = 1 << 1,
SignedDst = 1 << 2,
@@ -1637,14 +1637,14 @@ namespace ARMeilleure.Instructions
VectorSxSx = SignedSrc | SignedDst,
VectorSxZx = SignedSrc,
- VectorZxZx = 0
+ VectorZxZx = 0,
}
public static void EmitSaturatingNarrowOp(ArmEmitterContext context, SaturatingNarrowFlags flags)
{
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
- bool scalar = (flags & SaturatingNarrowFlags.Scalar) != 0;
+ bool scalar = (flags & SaturatingNarrowFlags.Scalar) != 0;
bool signedSrc = (flags & SaturatingNarrowFlags.SignedSrc) != 0;
bool signedDst = (flags & SaturatingNarrowFlags.SignedDst) != 0;
@@ -2034,18 +2034,30 @@ namespace ARMeilleure.Instructions
{
switch (size)
{
- case 0: res = context.SignExtend8 (OperandType.I64, res); break;
- case 1: res = context.SignExtend16(OperandType.I64, res); break;
- case 2: res = context.SignExtend32(OperandType.I64, res); break;
+ case 0:
+ res = context.SignExtend8(OperandType.I64, res);
+ break;
+ case 1:
+ res = context.SignExtend16(OperandType.I64, res);
+ break;
+ case 2:
+ res = context.SignExtend32(OperandType.I64, res);
+ break;
}
}
else
{
switch (size)
{
- case 0: res = context.ZeroExtend8 (OperandType.I64, res); break;
- case 1: res = context.ZeroExtend16(OperandType.I64, res); break;
- case 2: res = context.ZeroExtend32(OperandType.I64, res); break;
+ case 0:
+ res = context.ZeroExtend8(OperandType.I64, res);
+ break;
+ case 1:
+ res = context.ZeroExtend16(OperandType.I64, res);
+ break;
+ case 2:
+ res = context.ZeroExtend32(OperandType.I64, res);
+ break;
}
}
@@ -2063,10 +2075,18 @@ namespace ARMeilleure.Instructions
switch (size)
{
- case 0: vector = context.VectorInsert8 (vector, value, index); break;
- case 1: vector = context.VectorInsert16(vector, value, index); break;
- case 2: vector = context.VectorInsert (vector, value, index); break;
- case 3: vector = context.VectorInsert (vector, value, index); break;
+ case 0:
+ vector = context.VectorInsert8(vector, value, index);
+ break;
+ case 1:
+ vector = context.VectorInsert16(vector, value, index);
+ break;
+ case 2:
+ vector = context.VectorInsert(vector, value, index);
+ break;
+ case 3:
+ vector = context.VectorInsert(vector, value, index);
+ break;
}
return vector;