Add BIC/ORR Vd.T, #imm fast path (#2279)

* Add fast path for BIC Vd.T, #imm

* Add fast path for ORR Vd.T, #imm

* Set PTC version

* Fixup Exception to InvalidOperationException
This commit is contained in:
FICTURE7 2021-05-20 16:09:17 +04:00 committed by GitHub
parent 49745cfa37
commit 0181068016
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 65 additions and 5 deletions

View file

@ -190,6 +190,15 @@ namespace ARMeilleure.Instructions
return X86GetAllElements(context, BitConverter.DoubleToInt64Bits(value)); return X86GetAllElements(context, BitConverter.DoubleToInt64Bits(value));
} }
public static Operand X86GetAllElements(ArmEmitterContext context, short value)
{
ulong value1 = (ushort)value;
ulong value2 = value1 << 16 | value1;
ulong value4 = value2 << 32 | value2;
return X86GetAllElements(context, (long)value4);
}
public static Operand X86GetAllElements(ArmEmitterContext context, int value) public static Operand X86GetAllElements(ArmEmitterContext context, int value)
{ {
Operand vector = context.VectorCreateScalar(Const(value)); Operand vector = context.VectorCreateScalar(Const(value));

View file

@ -1,6 +1,7 @@
using ARMeilleure.Decoders; using ARMeilleure.Decoders;
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation; using ARMeilleure.Translation;
using System;
using System.Diagnostics; using System.Diagnostics;
using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitHelper;
@ -63,12 +64,37 @@ namespace ARMeilleure.Instructions
} }
public static void Bic_Vi(ArmEmitterContext context) public static void Bic_Vi(ArmEmitterContext context)
{
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
{ {
EmitVectorImmBinaryOp(context, (op1, op2) => EmitVectorImmBinaryOp(context, (op1, op2) =>
{ {
return context.BitwiseAnd(op1, context.BitwiseNot(op2)); return context.BitwiseAnd(op1, context.BitwiseNot(op2));
}); });
} }
}
public static void Bif_V(ArmEmitterContext context) public static void Bif_V(ArmEmitterContext context)
{ {
@ -277,9 +303,34 @@ namespace ARMeilleure.Instructions
} }
public static void Orr_Vi(ArmEmitterContext context) public static void Orr_Vi(ArmEmitterContext context)
{
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)); EmitVectorImmBinaryOp(context, (op1, op2) => context.BitwiseOr(op1, op2));
} }
}
public static void Rbit_V(ArmEmitterContext context) public static void Rbit_V(ArmEmitterContext context)
{ {

View file

@ -28,7 +28,7 @@ namespace ARMeilleure.Translation.PTC
private const string OuterHeaderMagicString = "PTCohd\0\0"; private const string OuterHeaderMagicString = "PTCohd\0\0";
private const string InnerHeaderMagicString = "PTCihd\0\0"; private const string InnerHeaderMagicString = "PTCihd\0\0";
private const uint InternalVersion = 2285; //! To be incremented manually for each change to the ARMeilleure project. private const uint InternalVersion = 2279; //! To be incremented manually for each change to the ARMeilleure project.
private const string ActualDir = "0"; private const string ActualDir = "0";
private const string BackupDir = "1"; private const string BackupDir = "1";