aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/Instructions/InstEmitSimdLogical.cs
diff options
context:
space:
mode:
Diffstat (limited to 'ARMeilleure/Instructions/InstEmitSimdLogical.cs')
-rw-r--r--ARMeilleure/Instructions/InstEmitSimdLogical.cs59
1 files changed, 55 insertions, 4 deletions
diff --git a/ARMeilleure/Instructions/InstEmitSimdLogical.cs b/ARMeilleure/Instructions/InstEmitSimdLogical.cs
index 362296f7..52a9a576 100644
--- a/ARMeilleure/Instructions/InstEmitSimdLogical.cs
+++ b/ARMeilleure/Instructions/InstEmitSimdLogical.cs
@@ -1,6 +1,7 @@
using ARMeilleure.Decoders;
using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation;
+using System;
using System.Diagnostics;
using static ARMeilleure.Instructions.InstEmitHelper;
@@ -64,10 +65,35 @@ namespace ARMeilleure.Instructions
public static void Bic_Vi(ArmEmitterContext context)
{
- EmitVectorImmBinaryOp(context, (op1, op2) =>
+ if (Optimizations.UseSse2)
+ {
+ OpCodeSimdImm op = (OpCodeSimdImm)context.CurrOp;
+
+ int eSize = 8 << op.Size;
+
+ Operand d = GetVec(op.Rd);
+ Operand imm = eSize switch {
+ 16 => X86GetAllElements(context, (short)~op.Immediate),
+ 32 => X86GetAllElements(context, (int)~op.Immediate),
+ _ => throw new InvalidOperationException($"Invalid element size {eSize}.")
+ };
+
+ Operand res = context.AddIntrinsic(Intrinsic.X86Pand, d, imm);
+
+ if (op.RegisterSize == RegisterSize.Simd64)
+ {
+ res = context.VectorZeroUpper64(res);
+ }
+
+ context.Copy(GetVec(op.Rd), res);
+ }
+ else
{
- return context.BitwiseAnd(op1, context.BitwiseNot(op2));
- });
+ EmitVectorImmBinaryOp(context, (op1, op2) =>
+ {
+ return context.BitwiseAnd(op1, context.BitwiseNot(op2));
+ });
+ }
}
public static void Bif_V(ArmEmitterContext context)
@@ -278,7 +304,32 @@ namespace ARMeilleure.Instructions
public static void Orr_Vi(ArmEmitterContext context)
{
- EmitVectorImmBinaryOp(context, (op1, op2) => context.BitwiseOr(op1, op2));
+ if (Optimizations.UseSse2)
+ {
+ OpCodeSimdImm op = (OpCodeSimdImm)context.CurrOp;
+
+ int eSize = 8 << op.Size;
+
+ Operand d = GetVec(op.Rd);
+ Operand imm = eSize switch {
+ 16 => X86GetAllElements(context, (short)op.Immediate),
+ 32 => X86GetAllElements(context, (int)op.Immediate),
+ _ => throw new InvalidOperationException($"Invalid element size {eSize}.")
+ };
+
+ Operand res = context.AddIntrinsic(Intrinsic.X86Por, d, imm);
+
+ if (op.RegisterSize == RegisterSize.Simd64)
+ {
+ res = context.VectorZeroUpper64(res);
+ }
+
+ context.Copy(GetVec(op.Rd), res);
+ }
+ else
+ {
+ EmitVectorImmBinaryOp(context, (op1, op2) => context.BitwiseOr(op1, op2));
+ }
}
public static void Rbit_V(ArmEmitterContext context)