aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-07-14 13:13:02 -0300
committerGitHub <noreply@github.com>2018-07-14 13:13:02 -0300
commit514218ab98acc1f0ace2e2cc0b8c1091ffccc6ce (patch)
treece7c44f11aa1dad7143678b2444bc297b98e5bff /ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
parent2f37583ab3b49aa5064a72c8d3b4e8245ebb6b5b (diff)
Add SMLSL, SQRSHRN and SRSHR (Vector) cpu instructions, nits (#225)
* Add SMLSL, SQRSHRN and SRSHR (Vector) cpu instructions * Address PR feedback * Address PR feedback * Remove another useless temp var * nit: Alignment * Replace Context.CurrOp.GetBitsCount() with Op.GetBitsCount() * Fix encodings and move flag bit test out of the loop
Diffstat (limited to 'ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs')
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs118
1 files changed, 26 insertions, 92 deletions
diff --git a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
index 39331f96..2fc8f178 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
@@ -65,11 +65,12 @@ namespace ChocolArm64.Instruction
{
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
- int Bytes = Context.CurrOp.GetBitsCount() >> 3;
+ int Bytes = Op.GetBitsCount() >> 3;
+ int Elems = Bytes >> Op.Size;
EmitVectorExtractZx(Context, Op.Rn, 0, Op.Size);
- for (int Index = 1; Index < (Bytes >> Op.Size); Index++)
+ for (int Index = 1; Index < Elems; Index++)
{
EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size);
@@ -97,9 +98,10 @@ namespace ChocolArm64.Instruction
{
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
- int Bytes = Context.CurrOp.GetBitsCount() >> 3;
+ int Bytes = Op.GetBitsCount() >> 3;
+ int Elems = Bytes >> Op.Size;
- for (int Index = 0; Index < (Bytes >> Op.Size); Index++)
+ for (int Index = 0; Index < Elems; Index++)
{
EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size);
@@ -190,84 +192,6 @@ namespace ChocolArm64.Instruction
}
}
- private static void EmitSaturatingExtNarrow(AILEmitterCtx Context, bool SignedSrc, bool SignedDst, bool Scalar)
- {
- AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
-
- int Elems = (!Scalar ? 8 >> Op.Size : 1);
- int ESize = 8 << Op.Size;
-
- int Part = (!Scalar & (Op.RegisterSize == ARegisterSize.SIMD128) ? Elems : 0);
-
- int TMaxValue = (SignedDst ? (1 << (ESize - 1)) - 1 : (int)((1L << ESize) - 1L));
- int TMinValue = (SignedDst ? -((1 << (ESize - 1))) : 0);
-
- Context.EmitLdc_I8(0L);
- Context.EmitSttmp();
-
- for (int Index = 0; Index < Elems; Index++)
- {
- AILLabel LblLe = new AILLabel();
- AILLabel LblGeEnd = new AILLabel();
-
- EmitVectorExtract(Context, Op.Rn, Index, Op.Size + 1, SignedSrc);
-
- Context.Emit(OpCodes.Dup);
-
- Context.EmitLdc_I4(TMaxValue);
- Context.Emit(OpCodes.Conv_U8);
-
- Context.Emit(SignedSrc ? OpCodes.Ble_S : OpCodes.Ble_Un_S, LblLe);
-
- Context.Emit(OpCodes.Pop);
-
- Context.EmitLdc_I4(TMaxValue);
-
- Context.EmitLdc_I8(0x8000000L);
- Context.EmitSttmp();
-
- Context.Emit(OpCodes.Br_S, LblGeEnd);
-
- Context.MarkLabel(LblLe);
-
- Context.Emit(OpCodes.Dup);
-
- Context.EmitLdc_I4(TMinValue);
- Context.Emit(OpCodes.Conv_I8);
-
- Context.Emit(SignedSrc ? OpCodes.Bge_S : OpCodes.Bge_Un_S, LblGeEnd);
-
- Context.Emit(OpCodes.Pop);
-
- Context.EmitLdc_I4(TMinValue);
-
- Context.EmitLdc_I8(0x8000000L);
- Context.EmitSttmp();
-
- Context.MarkLabel(LblGeEnd);
-
- if (Scalar)
- {
- EmitVectorZeroLower(Context, Op.Rd);
- }
-
- EmitVectorInsert(Context, Op.Rd, Part + Index, Op.Size);
- }
-
- if (Part == 0)
- {
- EmitVectorZeroUpper(Context, Op.Rd);
- }
-
- Context.EmitLdarg(ATranslatedSub.StateArgIdx);
- Context.EmitLdarg(ATranslatedSub.StateArgIdx);
- Context.EmitCallPropGet(typeof(AThreadState), nameof(AThreadState.Fpsr));
- Context.EmitLdtmp();
- Context.Emit(OpCodes.Conv_I4);
- Context.Emit(OpCodes.Or);
- Context.EmitCallPropSet(typeof(AThreadState), nameof(AThreadState.Fpsr));
- }
-
public static void Fabd_S(AILEmitterCtx Context)
{
EmitScalarBinaryOpF(Context, () =>
@@ -338,7 +262,7 @@ namespace ChocolArm64.Instruction
int SizeF = Op.Size & 1;
- int Bytes = Context.CurrOp.GetBitsCount() >> 3;
+ int Bytes = Op.GetBitsCount() >> 3;
int Elems = Bytes >> SizeF + 2;
int Half = Elems >> 1;
@@ -870,7 +794,7 @@ namespace ChocolArm64.Instruction
int SizeF = Op.Size & 1;
- int Bytes = Context.CurrOp.GetBitsCount() >> 3;
+ int Bytes = Op.GetBitsCount() >> 3;
for (int Index = 0; Index < Bytes >> SizeF + 2; Index++)
{
@@ -1102,6 +1026,15 @@ namespace ChocolArm64.Instruction
});
}
+ public static void Smlsl_V(AILEmitterCtx Context)
+ {
+ EmitVectorWidenRnRmTernaryOpSx(Context, () =>
+ {
+ Context.Emit(OpCodes.Mul);
+ Context.Emit(OpCodes.Sub);
+ });
+ }
+
public static void Smull_V(AILEmitterCtx Context)
{
EmitVectorWidenRnRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Mul));
@@ -1109,22 +1042,22 @@ namespace ChocolArm64.Instruction
public static void Sqxtn_S(AILEmitterCtx Context)
{
- EmitSaturatingExtNarrow(Context, SignedSrc: true, SignedDst: true, Scalar: true);
+ EmitScalarSaturatingNarrowOpSxSx(Context, () => { });
}
public static void Sqxtn_V(AILEmitterCtx Context)
{
- EmitSaturatingExtNarrow(Context, SignedSrc: true, SignedDst: true, Scalar: false);
+ EmitVectorSaturatingNarrowOpSxSx(Context, () => { });
}
public static void Sqxtun_S(AILEmitterCtx Context)
{
- EmitSaturatingExtNarrow(Context, SignedSrc: true, SignedDst: false, Scalar: true);
+ EmitScalarSaturatingNarrowOpSxZx(Context, () => { });
}
public static void Sqxtun_V(AILEmitterCtx Context)
{
- EmitSaturatingExtNarrow(Context, SignedSrc: true, SignedDst: false, Scalar: false);
+ EmitVectorSaturatingNarrowOpSxZx(Context, () => { });
}
public static void Sub_S(AILEmitterCtx Context)
@@ -1198,11 +1131,12 @@ namespace ChocolArm64.Instruction
{
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
- int Bytes = Context.CurrOp.GetBitsCount() >> 3;
+ int Bytes = Op.GetBitsCount() >> 3;
+ int Elems = Bytes >> Op.Size;
EmitVectorExtractZx(Context, Op.Rn, 0, Op.Size);
- for (int Index = 1; Index < (Bytes >> Op.Size); Index++)
+ for (int Index = 1; Index < Elems; Index++)
{
EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size);
@@ -1272,12 +1206,12 @@ namespace ChocolArm64.Instruction
public static void Uqxtn_S(AILEmitterCtx Context)
{
- EmitSaturatingExtNarrow(Context, SignedSrc: false, SignedDst: false, Scalar: true);
+ EmitScalarSaturatingNarrowOpZxZx(Context, () => { });
}
public static void Uqxtn_V(AILEmitterCtx Context)
{
- EmitSaturatingExtNarrow(Context, SignedSrc: false, SignedDst: false, Scalar: false);
+ EmitVectorSaturatingNarrowOpZxZx(Context, () => { });
}
}
}