aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/Instructions/InstEmitSimdMove.cs
diff options
context:
space:
mode:
authorLDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com>2019-03-23 19:50:19 +0100
committergdkchan <gab.dark.100@gmail.com>2019-03-23 15:50:19 -0300
commitc106ae994425e384a9ad8d6d00747af71e8475a6 (patch)
treea40b30d78cff602f68597493f71118ff7fe47826 /ChocolArm64/Instructions/InstEmitSimdMove.cs
parent1b2e430e887fc2eac372c46255c18ecceb032fd1 (diff)
Add Tbl_V Sse opt. with Tests. (#651)
* Add v4, v5, v30, v31 required for Tbl_V Tests. * Add Tests for Tbl_V. * Add Tbl_V Sse opt.. * Nit. * Small opt. on comparison constant vector. * Nit. * Add EmitLd/Stvectmp2/3. * Nit.
Diffstat (limited to 'ChocolArm64/Instructions/InstEmitSimdMove.cs')
-rw-r--r--ChocolArm64/Instructions/InstEmitSimdMove.cs101
1 files changed, 80 insertions, 21 deletions
diff --git a/ChocolArm64/Instructions/InstEmitSimdMove.cs b/ChocolArm64/Instructions/InstEmitSimdMove.cs
index 20647ce0..cdd35171 100644
--- a/ChocolArm64/Instructions/InstEmitSimdMove.cs
+++ b/ChocolArm64/Instructions/InstEmitSimdMove.cs
@@ -355,35 +355,94 @@ namespace ChocolArm64.Instructions
{
OpCodeSimdTbl64 op = (OpCodeSimdTbl64)context.CurrOp;
- context.EmitLdvec(op.Rm);
-
- for (int index = 0; index < op.Size; index++)
+ if (Optimizations.UseSsse3)
{
- context.EmitLdvec((op.Rn + index) & 0x1f);
- }
+ Type[] typesCmpSflSub = new Type[] { typeof(Vector128<sbyte>), typeof(Vector128<sbyte>) };
+ Type[] typesOr = new Type[] { typeof(Vector128<long> ), typeof(Vector128<long> ) };
+ Type[] typesSav = new Type[] { typeof(long) };
- switch (op.Size)
- {
- case 1: VectorHelper.EmitCall(context,
- nameof(VectorHelper.Tbl1_V64),
- nameof(VectorHelper.Tbl1_V128)); break;
+ context.EmitLdvec(op.Rn);
+ context.EmitLdvec(op.Rm);
- case 2: VectorHelper.EmitCall(context,
- nameof(VectorHelper.Tbl2_V64),
- nameof(VectorHelper.Tbl2_V128)); break;
+ context.EmitLdc_I8(0x0F0F0F0F0F0F0F0FL);
+ context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
- case 3: VectorHelper.EmitCall(context,
- nameof(VectorHelper.Tbl3_V64),
- nameof(VectorHelper.Tbl3_V128)); break;
+ context.EmitStvectmp2();
+ context.EmitLdvectmp2();
- case 4: VectorHelper.EmitCall(context,
- nameof(VectorHelper.Tbl4_V64),
- nameof(VectorHelper.Tbl4_V128)); break;
+ context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThan), typesCmpSflSub));
- default: throw new InvalidOperationException();
+ context.EmitLdvec(op.Rm);
+
+ context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Or), typesOr));
+
+ context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), typesCmpSflSub));
+
+ for (int index = 1; index < op.Size; index++)
+ {
+ context.EmitLdvec((op.Rn + index) & 0x1F);
+ context.EmitLdvec(op.Rm);
+
+ context.EmitLdc_I8(0x1010101010101010L * index);
+ context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
+
+ context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesCmpSflSub));
+
+ context.EmitStvectmp();
+ context.EmitLdvectmp();
+
+ context.EmitLdvectmp2();
+
+ context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThan), typesCmpSflSub));
+
+ context.EmitLdvectmp();
+
+ context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Or), typesOr));
+
+ context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), typesCmpSflSub));
+
+ context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Or), typesOr));
+ }
+
+ context.EmitStvec(op.Rd);
+
+ if (op.RegisterSize == RegisterSize.Simd64)
+ {
+ EmitVectorZeroUpper(context, op.Rd);
+ }
}
+ else
+ {
+ context.EmitLdvec(op.Rm);
- context.EmitStvec(op.Rd);
+ for (int index = 0; index < op.Size; index++)
+ {
+ context.EmitLdvec((op.Rn + index) & 0x1F);
+ }
+
+ switch (op.Size)
+ {
+ case 1: VectorHelper.EmitCall(context,
+ nameof(VectorHelper.Tbl1_V64),
+ nameof(VectorHelper.Tbl1_V128)); break;
+
+ case 2: VectorHelper.EmitCall(context,
+ nameof(VectorHelper.Tbl2_V64),
+ nameof(VectorHelper.Tbl2_V128)); break;
+
+ case 3: VectorHelper.EmitCall(context,
+ nameof(VectorHelper.Tbl3_V64),
+ nameof(VectorHelper.Tbl3_V128)); break;
+
+ case 4: VectorHelper.EmitCall(context,
+ nameof(VectorHelper.Tbl4_V64),
+ nameof(VectorHelper.Tbl4_V128)); break;
+
+ default: throw new InvalidOperationException();
+ }
+
+ context.EmitStvec(op.Rd);
+ }
}
public static void Trn1_V(ILEmitterCtx context)