diff options
| author | LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com> | 2018-12-26 18:11:36 +0100 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-12-26 15:11:36 -0200 |
| commit | 0f5b6dfbe8d4bcc4df3f670e366a967d8ea103db (patch) | |
| tree | 89fe781d39e9e02534fd455a26008db8a3a14341 /ChocolArm64/Instructions/InstEmitSimdMove.cs | |
| parent | d8f2497f155046402cd15c65eca0326faf3aefd6 (diff) | |
Fix Frecpe_S/V and Frsqrte_S/V (full FP emu.). Add Sse Opt. & SoftFloat Impl. for Fcmeq/ge/gt/le/lt_S/V (Reg & Zero), Faddp_S/V, Fmaxp_V, Fminp_V Inst.; add Sse Opt. for Shll_V, S/Ushll_V Inst.; improve Sse Opt. for Xtn_V Inst.. Add Tests. (#543)
* Update Optimizations.cs
* Update InstEmitSimdShift.cs
* Update InstEmitSimdHelper.cs
* Update InstEmitSimdArithmetic.cs
* Update InstEmitSimdMove.cs
* Update SoftFloat.cs
* Update InstEmitSimdCmp.cs
* Update CpuTestSimdShImm.cs
* Update CpuTestSimd.cs
* Update CpuTestSimdReg.cs
* Nit.
* Update SoftFloat.cs
* Update InstEmitSimdArithmetic.cs
* Update InstEmitSimdHelper.cs
* Update CpuTestSimd.cs
* Explicit some implicit casts.
* Simplify some powers; nits.
* Update OpCodeTable.cs
* Update InstEmitSimdArithmetic.cs
* Update CpuTestSimdReg.cs
* Update InstEmitSimdArithmetic.cs
Diffstat (limited to 'ChocolArm64/Instructions/InstEmitSimdMove.cs')
| -rw-r--r-- | ChocolArm64/Instructions/InstEmitSimdMove.cs | 80 |
1 files changed, 26 insertions, 54 deletions
diff --git a/ChocolArm64/Instructions/InstEmitSimdMove.cs b/ChocolArm64/Instructions/InstEmitSimdMove.cs index 0d9aa312..d40ccff9 100644 --- a/ChocolArm64/Instructions/InstEmitSimdMove.cs +++ b/ChocolArm64/Instructions/InstEmitSimdMove.cs @@ -377,75 +377,47 @@ namespace ChocolArm64.Instructions { OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp; - int elems = 8 >> op.Size; - - int part = op.RegisterSize == RegisterSize.Simd128 ? elems : 0; - - if (Optimizations.UseSse41 && op.Size < 2) + if (Optimizations.UseSsse3) { - void EmitZeroVector() - { - switch (op.Size) - { - case 0: VectorHelper.EmitCall(context, nameof(VectorHelper.VectorInt16Zero)); break; - case 1: VectorHelper.EmitCall(context, nameof(VectorHelper.VectorInt32Zero)); break; - } - } - - //For XTN, first operand is source, second operand is 0. - //For XTN2, first operand is 0, second operand is source. - if (part != 0) + long[] masks = new long[] { - EmitZeroVector(); - } - - EmitLdvecWithSignedCast(context, op.Rn, op.Size + 1); - - //Set mask to discard the upper half of the wide elements. - switch (op.Size) - { - case 0: context.EmitLdc_I4(0x00ff); break; - case 1: context.EmitLdc_I4(0x0000ffff); break; - } - - Type wideType = IntTypesPerSizeLog2[op.Size + 1]; + 14L << 56 | 12L << 48 | 10L << 40 | 08L << 32 | 06L << 24 | 04L << 16 | 02L << 8 | 00L << 0, + 13L << 56 | 12L << 48 | 09L << 40 | 08L << 32 | 05L << 24 | 04L << 16 | 01L << 8 | 00L << 0, + 11L << 56 | 10L << 48 | 09L << 40 | 08L << 32 | 03L << 24 | 02L << 16 | 01L << 8 | 00L << 0 + }; - context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), new Type[] { wideType })); + Type[] typesMov = new Type[] { typeof(Vector128<float>), typeof(Vector128<float>) }; + Type[] typesSfl = new Type[] { typeof(Vector128<sbyte>), typeof(Vector128<sbyte>) }; + Type[] typesSve = new Type[] { typeof(long), typeof(long) }; - wideType = VectorIntTypesPerSizeLog2[op.Size + 1]; + string nameMov = op.RegisterSize == RegisterSize.Simd128 + ? nameof(Sse.MoveLowToHigh) + : nameof(Sse.MoveHighToLow); - Type[] wideTypes = new Type[] { wideType, wideType }; + context.EmitLdvec(op.Rd); + VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero)); - context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.And), wideTypes)); + context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveLowToHigh), typesMov)); - if (part == 0) - { - EmitZeroVector(); - } + EmitLdvecWithSignedCast(context, op.Rn, 0); - //Pack values with signed saturation, the signed saturation shouldn't - //saturate anything since the upper bits were masked off. - Type sseType = op.Size == 0 ? typeof(Sse2) : typeof(Sse41); - - context.EmitCall(sseType.GetMethod(nameof(Sse2.PackUnsignedSaturate), wideTypes)); - - if (part != 0) - { - //For XTN2, we additionally need to discard the upper bits - //of the target register and OR the result with it. - EmitVectorZeroUpper(context, op.Rd); + context.EmitLdc_I8(masks[op.Size]); + context.Emit(OpCodes.Dup); - EmitLdvecWithUnsignedCast(context, op.Rd, op.Size); + context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetVector128), typesSve)); - Type narrowType = VectorUIntTypesPerSizeLog2[op.Size]; + context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), typesSfl)); - context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { narrowType, narrowType })); - } + context.EmitCall(typeof(Sse).GetMethod(nameMov, typesMov)); - EmitStvecWithUnsignedCast(context, op.Rd, op.Size); + context.EmitStvec(op.Rd); } else { + int elems = 8 >> op.Size; + + int part = op.RegisterSize == RegisterSize.Simd128 ? elems : 0; + if (part != 0) { context.EmitLdvec(op.Rd); |
