Optimize MOVI/MVNI instructions using intrinsics (#606)

This commit is contained in:
gdkchan 2019-02-26 09:50:36 -03:00 committed by jduncanator
parent fca693a696
commit f2d37d52f7

View file

@ -317,14 +317,28 @@ namespace ChocolArm64.Instructions
} }
public static void Movi_V(ILEmitterCtx context) public static void Movi_V(ILEmitterCtx context)
{
if (Optimizations.UseSse2)
{
EmitMoviMvni(context, not: false);
}
else
{ {
EmitVectorImmUnaryOp(context, () => { }); EmitVectorImmUnaryOp(context, () => { });
} }
}
public static void Mvni_V(ILEmitterCtx context) public static void Mvni_V(ILEmitterCtx context)
{
if (Optimizations.UseSse2)
{
EmitMoviMvni(context, not: true);
}
else
{ {
EmitVectorImmUnaryOp(context, () => context.Emit(OpCodes.Not)); EmitVectorImmUnaryOp(context, () => context.Emit(OpCodes.Not));
} }
}
public static void Smov_S(ILEmitterCtx context) public static void Smov_S(ILEmitterCtx context)
{ {
@ -480,6 +494,38 @@ namespace ChocolArm64.Instructions
} }
} }
private static void EmitMoviMvni(ILEmitterCtx context, bool not)
{
OpCodeSimdImm64 op = (OpCodeSimdImm64)context.CurrOp;
Type[] typesSav = new Type[] { UIntTypesPerSizeLog2[op.Size] };
long imm = op.Imm;
if (not)
{
imm = ~imm;
}
if (op.Size < 3)
{
context.EmitLdc_I4((int)imm);
}
else
{
context.EmitLdc_I8(imm);
}
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64)
{
EmitVectorZeroUpper(context, op.Rd);
}
}
private static void EmitVectorTranspose(ILEmitterCtx context, int part) private static void EmitVectorTranspose(ILEmitterCtx context, int part)
{ {
OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp; OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;