diff options
| author | LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com> | 2019-03-23 19:50:19 +0100 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2019-03-23 15:50:19 -0300 |
| commit | c106ae994425e384a9ad8d6d00747af71e8475a6 (patch) | |
| tree | a40b30d78cff602f68597493f71118ff7fe47826 /ChocolArm64/Instructions/InstEmitSimdMove.cs | |
| parent | 1b2e430e887fc2eac372c46255c18ecceb032fd1 (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.cs | 101 |
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) |
