diff options
Diffstat (limited to 'src/ARMeilleure/Instructions/InstEmitSimdHelper.cs')
-rw-r--r-- | src/ARMeilleure/Instructions/InstEmitSimdHelper.cs | 174 |
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; |