Fix VMVN (immediate), Add VPMIN, VPMAX, VMVN (register) (#1303)
* Add Vmvn (register), tests for both Vmvn variants. * Add Vpmin, Vpmax, improve Non-FastFp accuracy for Vpadd * Rebase on top of PTC. * Add Nopcode * Increment PTC version. * Fix nits.
This commit is contained in:
parent
4472196b48
commit
9a49f8aec9
7 changed files with 243 additions and 23 deletions
|
@ -817,7 +817,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
EmitVectorPairwiseOpF32(context, (op1, op2) => context.Add(op1, op2));
|
||||
EmitVectorPairwiseOpF32(context, (op1, op2) => EmitSoftFloatCallDefaultFpscr(context, nameof(SoftFloat32.FPAddFpscr), op1, op2));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -835,6 +835,66 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Vpmax_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||
{
|
||||
EmitSse2VectorPairwiseOpF32(context, Intrinsic.X86Maxps);
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitVectorPairwiseOpF32(context, (op1, op2) => EmitSoftFloatCallDefaultFpscr(context, nameof(SoftFloat64.FPMaxFpscr), op1, op2));
|
||||
}
|
||||
}
|
||||
|
||||
public static void Vpmax_I(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;
|
||||
|
||||
if (Optimizations.UseSsse3)
|
||||
{
|
||||
EmitSsse3VectorPairwiseOp32(context, op.U ? X86PmaxuInstruction : X86PmaxsInstruction);
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitVectorPairwiseOpI32(context, (op1, op2) =>
|
||||
{
|
||||
Operand greater = op.U ? context.ICompareGreaterUI(op1, op2) : context.ICompareGreater(op1, op2);
|
||||
return context.ConditionalSelect(greater, op1, op2);
|
||||
}, !op.U);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Vpmin_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||
{
|
||||
EmitSse2VectorPairwiseOpF32(context, Intrinsic.X86Minps);
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitVectorPairwiseOpF32(context, (op1, op2) => EmitSoftFloatCallDefaultFpscr(context, nameof(SoftFloat32.FPMinFpscr), op1, op2));
|
||||
}
|
||||
}
|
||||
|
||||
public static void Vpmin_I(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;
|
||||
|
||||
if (Optimizations.UseSsse3)
|
||||
{
|
||||
EmitSsse3VectorPairwiseOp32(context, op.U ? X86PminuInstruction : X86PminsInstruction);
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitVectorPairwiseOpI32(context, (op1, op2) =>
|
||||
{
|
||||
Operand greater = op.U ? context.ICompareLessUI(op1, op2) : context.ICompareLess(op1, op2);
|
||||
return context.ConditionalSelect(greater, op1, op2);
|
||||
}, !op.U);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Vrev(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32SimdRev op = (OpCode32SimdRev)context.CurrOp;
|
||||
|
|
|
@ -34,7 +34,23 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
public static void Vmvn_I(ArmEmitterContext context)
|
||||
{
|
||||
EmitVectorImmUnaryOp32(context, (op1) => context.BitwiseExclusiveOr(op1, op1));
|
||||
if (Optimizations.UseSse2)
|
||||
{
|
||||
EmitVectorUnaryOpSimd32(context, (op1) =>
|
||||
{
|
||||
Operand mask = X86GetAllElements(context, -1L);
|
||||
return context.AddIntrinsic(Intrinsic.X86Pandn, op1, mask);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitVectorUnaryOpZx32(context, (op1) => context.BitwiseNot(op1));
|
||||
}
|
||||
}
|
||||
|
||||
public static void Vmvn_II(ArmEmitterContext context)
|
||||
{
|
||||
EmitVectorImmUnaryOp32(context, (op1) => context.BitwiseNot(op1));
|
||||
}
|
||||
|
||||
public static void Vmov_GS(ArmEmitterContext context)
|
||||
|
|
|
@ -582,6 +582,8 @@ namespace ARMeilleure.Instructions
|
|||
Vnmls,
|
||||
Vorr,
|
||||
Vpadd,
|
||||
Vpmax,
|
||||
Vpmin,
|
||||
Vqrshrn,
|
||||
Vqrshrun,
|
||||
Vrev,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue