aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/Instruction/AInstEmitSimdCvt.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-09-26 23:30:21 -0300
committerGitHub <noreply@github.com>2018-09-26 23:30:21 -0300
commit0b52ee66272b673cecebcf9ae9baaf03899e0ee3 (patch)
treea004a0f7215e4c371ee99c187c291a0e11a0365e /ChocolArm64/Instruction/AInstEmitSimdCvt.cs
parent40282da93a45c90b3d5a696199ee353a1ae8c730 (diff)
Optimize BIC, BSL, BIT, BIF, XTN, ZIP, DUP (Gp), FMADD (Scalar) and FCVT (Scalar) using SSE intrinsics (#405)
* Optimize BIC, BSL, BIT, BIF, XTN, ZIP, DUP (Gp), FMADD (Scalar) and FCVT (Scalar) using SSE intrinsics, some CQ improvements * Remove useless space * Address PR feedback * Revert EmitVectorZero32_128 changes
Diffstat (limited to 'ChocolArm64/Instruction/AInstEmitSimdCvt.cs')
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdCvt.cs45
1 files changed, 42 insertions, 3 deletions
diff --git a/ChocolArm64/Instruction/AInstEmitSimdCvt.cs b/ChocolArm64/Instruction/AInstEmitSimdCvt.cs
index 231de0af..76d984a2 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdCvt.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdCvt.cs
@@ -3,6 +3,8 @@ using ChocolArm64.State;
using ChocolArm64.Translation;
using System;
using System.Reflection.Emit;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
using static ChocolArm64.Instruction.AInstEmitSimdHelper;
@@ -14,11 +16,48 @@ namespace ChocolArm64.Instruction
{
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
- EmitVectorExtractF(Context, Op.Rn, 0, Op.Size);
+ if (AOptimizations.UseSse2)
+ {
+ if (Op.Size == 1 && Op.Opc == 0)
+ {
+ //Double -> Single.
+ AVectorHelper.EmitCall(Context, nameof(AVectorHelper.VectorSingleZero));
+
+ EmitLdvecWithCastToDouble(Context, Op.Rn);
+
+ Type[] Types = new Type[] { typeof(Vector128<float>), typeof(Vector128<double>) };
+
+ Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertScalarToVector128Single), Types));
+
+ Context.EmitStvec(Op.Rd);
+ }
+ else if (Op.Size == 0 && Op.Opc == 1)
+ {
+ //Single -> Double.
+ AVectorHelper.EmitCall(Context, nameof(AVectorHelper.VectorDoubleZero));
+
+ Context.EmitLdvec(Op.Rn);
+
+ Type[] Types = new Type[] { typeof(Vector128<double>), typeof(Vector128<float>) };
- EmitFloatCast(Context, Op.Opc);
+ Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertScalarToVector128Double), Types));
- EmitScalarSetF(Context, Op.Rd, Op.Opc);
+ EmitStvecWithCastFromDouble(Context, Op.Rd);
+ }
+ else
+ {
+ //Invalid encoding.
+ throw new InvalidOperationException();
+ }
+ }
+ else
+ {
+ EmitVectorExtractF(Context, Op.Rn, 0, Op.Size);
+
+ EmitFloatCast(Context, Op.Opc);
+
+ EmitScalarSetF(Context, Op.Rd, Op.Opc);
+ }
}
public static void Fcvtas_Gp(AILEmitterCtx Context)