aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/Instruction/AInstEmitSimdLogical.cs
diff options
context:
space:
mode:
Diffstat (limited to 'ChocolArm64/Instruction/AInstEmitSimdLogical.cs')
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdLogical.cs156
1 files changed, 123 insertions, 33 deletions
diff --git a/ChocolArm64/Instruction/AInstEmitSimdLogical.cs b/ChocolArm64/Instruction/AInstEmitSimdLogical.cs
index 9f5af96c..1aa8981f 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdLogical.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdLogical.cs
@@ -15,7 +15,7 @@ namespace ChocolArm64.Instruction
{
if (AOptimizations.UseSse2)
{
- EmitSse2Call(Context, nameof(Sse2.And));
+ EmitSse2Op(Context, nameof(Sse2.And));
}
else
{
@@ -25,11 +25,36 @@ namespace ChocolArm64.Instruction
public static void Bic_V(AILEmitterCtx Context)
{
- EmitVectorBinaryOpZx(Context, () =>
+ if (AOptimizations.UseSse2)
{
- Context.Emit(OpCodes.Not);
- Context.Emit(OpCodes.And);
- });
+ AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
+
+ EmitLdvecWithUnsignedCast(Context, Op.Rm, Op.Size);
+ EmitLdvecWithUnsignedCast(Context, Op.Rn, Op.Size);
+
+ Type[] Types = new Type[]
+ {
+ VectorUIntTypesPerSizeLog2[Op.Size],
+ VectorUIntTypesPerSizeLog2[Op.Size]
+ };
+
+ Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), Types));
+
+ EmitStvecWithUnsignedCast(Context, Op.Rd, Op.Size);
+
+ if (Op.RegisterSize == ARegisterSize.SIMD64)
+ {
+ EmitVectorZeroUpper(Context, Op.Rd);
+ }
+ }
+ else
+ {
+ EmitVectorBinaryOpZx(Context, () =>
+ {
+ Context.Emit(OpCodes.Not);
+ Context.Emit(OpCodes.And);
+ });
+ }
}
public static void Bic_Vi(AILEmitterCtx Context)
@@ -55,59 +80,124 @@ namespace ChocolArm64.Instruction
{
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
- int Bytes = Op.GetBitsCount() >> 3;
- int Elems = Bytes >> Op.Size;
-
- for (int Index = 0; Index < Elems; Index++)
+ if (AOptimizations.UseSse2)
{
- EmitVectorExtractZx(Context, Op.Rd, Index, Op.Size);
- EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size);
+ Type[] Types = new Type[]
+ {
+ VectorUIntTypesPerSizeLog2[Op.Size],
+ VectorUIntTypesPerSizeLog2[Op.Size]
+ };
+
+ EmitLdvecWithUnsignedCast(Context, Op.Rm, Op.Size);
+ EmitLdvecWithUnsignedCast(Context, Op.Rd, Op.Size);
+ EmitLdvecWithUnsignedCast(Context, Op.Rn, Op.Size);
- Context.Emit(OpCodes.Xor);
+ Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), Types));
- EmitVectorExtractZx(Context, Op.Rm, Index, Op.Size);
+ string Name = NotRm ? nameof(Sse2.AndNot) : nameof(Sse2.And);
- if (NotRm)
+ Context.EmitCall(typeof(Sse2).GetMethod(Name, Types));
+
+ EmitLdvecWithUnsignedCast(Context, Op.Rd, Op.Size);
+
+ Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), Types));
+
+ EmitStvecWithUnsignedCast(Context, Op.Rd, Op.Size);
+
+ if (Op.RegisterSize == ARegisterSize.SIMD64)
{
- Context.Emit(OpCodes.Not);
+ EmitVectorZeroUpper(Context, Op.Rd);
}
+ }
+ else
+ {
+ int Bytes = Op.GetBitsCount() >> 3;
+ int Elems = Bytes >> Op.Size;
- Context.Emit(OpCodes.And);
+ for (int Index = 0; Index < Elems; Index++)
+ {
+ EmitVectorExtractZx(Context, Op.Rd, Index, Op.Size);
+ EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size);
- EmitVectorExtractZx(Context, Op.Rd, Index, Op.Size);
+ Context.Emit(OpCodes.Xor);
- Context.Emit(OpCodes.Xor);
+ EmitVectorExtractZx(Context, Op.Rm, Index, Op.Size);
- EmitVectorInsert(Context, Op.Rd, Index, Op.Size);
- }
+ if (NotRm)
+ {
+ Context.Emit(OpCodes.Not);
+ }
- if (Op.RegisterSize == ARegisterSize.SIMD64)
- {
- EmitVectorZeroUpper(Context, Op.Rd);
+ Context.Emit(OpCodes.And);
+
+ EmitVectorExtractZx(Context, Op.Rd, Index, Op.Size);
+
+ Context.Emit(OpCodes.Xor);
+
+ EmitVectorInsert(Context, Op.Rd, Index, Op.Size);
+ }
+
+ if (Op.RegisterSize == ARegisterSize.SIMD64)
+ {
+ EmitVectorZeroUpper(Context, Op.Rd);
+ }
}
}
public static void Bsl_V(AILEmitterCtx Context)
{
- EmitVectorTernaryOpZx(Context, () =>
+ if (AOptimizations.UseSse2)
{
- Context.EmitSttmp();
- Context.EmitLdtmp();
+ AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
- Context.Emit(OpCodes.Xor);
- Context.Emit(OpCodes.And);
+ Type[] Types = new Type[]
+ {
+ VectorUIntTypesPerSizeLog2[Op.Size],
+ VectorUIntTypesPerSizeLog2[Op.Size]
+ };
- Context.EmitLdtmp();
+ EmitLdvecWithUnsignedCast(Context, Op.Rn, Op.Size);
+ EmitLdvecWithUnsignedCast(Context, Op.Rm, Op.Size);
- Context.Emit(OpCodes.Xor);
- });
+ Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), Types));
+
+ EmitLdvecWithUnsignedCast(Context, Op.Rd, Op.Size);
+
+ Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.And), Types));
+
+ EmitLdvecWithUnsignedCast(Context, Op.Rm, Op.Size);
+
+ Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), Types));
+
+ EmitStvecWithUnsignedCast(Context, Op.Rd, Op.Size);
+
+ if (Op.RegisterSize == ARegisterSize.SIMD64)
+ {
+ EmitVectorZeroUpper(Context, Op.Rd);
+ }
+ }
+ else
+ {
+ EmitVectorTernaryOpZx(Context, () =>
+ {
+ Context.EmitSttmp();
+ Context.EmitLdtmp();
+
+ Context.Emit(OpCodes.Xor);
+ Context.Emit(OpCodes.And);
+
+ Context.EmitLdtmp();
+
+ Context.Emit(OpCodes.Xor);
+ });
+ }
}
public static void Eor_V(AILEmitterCtx Context)
{
if (AOptimizations.UseSse2)
{
- EmitSse2Call(Context, nameof(Sse2.Xor));
+ EmitSse2Op(Context, nameof(Sse2.Xor));
}
else
{
@@ -133,7 +223,7 @@ namespace ChocolArm64.Instruction
{
if (AOptimizations.UseSse2)
{
- EmitSse2Call(Context, nameof(Sse2.Or));
+ EmitSse2Op(Context, nameof(Sse2.Or));
}
else
{