Add Sqdmulh_S, Sqdmulh_V, Sqrdmulh_S, Sqrdmulh_V instructions; add 6 Tests. Now all saturating methods are on ASoftFallback. (#334)
* Update Instructions.cs * Update CpuTestSimd.cs * Update CpuTestSimdReg.cs * Update AOpCodeTable.cs * Update AInstEmitSimdArithmetic.cs * Update AInstEmitSimdHelper.cs * Update ASoftFallback.cs * Update CpuTestAlu.cs * Update CpuTestAluImm.cs * Update CpuTestAluRs.cs * Update CpuTestAluRx.cs * Update CpuTestBfm.cs * Update CpuTestCcmpImm.cs * Update CpuTestCcmpReg.cs * Update CpuTestCsel.cs * Update CpuTestMov.cs * Update CpuTestMul.cs * Update Ryujinx.Tests.csproj * Update Ryujinx.csproj * Update Luea.csproj * Update Ryujinx.ShaderTools.csproj * Address PR feedback (further tested). * Address PR feedback.
This commit is contained in:
parent
267af1f0f7
commit
02a6fdcd13
21 changed files with 834 additions and 314 deletions
|
@ -804,7 +804,7 @@ namespace ChocolArm64.Instruction
|
|||
ScalarZx = Scalar,
|
||||
|
||||
VectorSx = Signed,
|
||||
VectorZx = 0,
|
||||
VectorZx = 0
|
||||
}
|
||||
|
||||
public static void EmitScalarSaturatingUnaryOpSx(AILEmitterCtx Context, Action Emit)
|
||||
|
@ -837,7 +837,14 @@ namespace ChocolArm64.Instruction
|
|||
|
||||
Emit();
|
||||
|
||||
EmitUnarySignedSatQAbsOrNeg(Context, Op.Size);
|
||||
if (Op.Size <= 2)
|
||||
{
|
||||
EmitSatQ(Context, Op.Size, true, true);
|
||||
}
|
||||
else /* if (Op.Size == 3) */
|
||||
{
|
||||
EmitUnarySignedSatQAbsOrNeg(Context);
|
||||
}
|
||||
|
||||
EmitVectorInsertTmp(Context, Index, Op.Size);
|
||||
}
|
||||
|
@ -853,25 +860,25 @@ namespace ChocolArm64.Instruction
|
|||
|
||||
public static void EmitScalarSaturatingBinaryOpSx(AILEmitterCtx Context, SaturatingFlags Flags)
|
||||
{
|
||||
EmitSaturatingBinaryOp(Context, SaturatingFlags.ScalarSx | Flags);
|
||||
EmitSaturatingBinaryOp(Context, () => { }, SaturatingFlags.ScalarSx | Flags);
|
||||
}
|
||||
|
||||
public static void EmitScalarSaturatingBinaryOpZx(AILEmitterCtx Context, SaturatingFlags Flags)
|
||||
{
|
||||
EmitSaturatingBinaryOp(Context, SaturatingFlags.ScalarZx | Flags);
|
||||
EmitSaturatingBinaryOp(Context, () => { }, SaturatingFlags.ScalarZx | Flags);
|
||||
}
|
||||
|
||||
public static void EmitVectorSaturatingBinaryOpSx(AILEmitterCtx Context, SaturatingFlags Flags)
|
||||
{
|
||||
EmitSaturatingBinaryOp(Context, SaturatingFlags.VectorSx | Flags);
|
||||
EmitSaturatingBinaryOp(Context, () => { }, SaturatingFlags.VectorSx | Flags);
|
||||
}
|
||||
|
||||
public static void EmitVectorSaturatingBinaryOpZx(AILEmitterCtx Context, SaturatingFlags Flags)
|
||||
{
|
||||
EmitSaturatingBinaryOp(Context, SaturatingFlags.VectorZx | Flags);
|
||||
EmitSaturatingBinaryOp(Context, () => { }, SaturatingFlags.VectorZx | Flags);
|
||||
}
|
||||
|
||||
public static void EmitSaturatingBinaryOp(AILEmitterCtx Context, SaturatingFlags Flags)
|
||||
public static void EmitSaturatingBinaryOp(AILEmitterCtx Context, Action Emit, SaturatingFlags Flags)
|
||||
{
|
||||
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
|
||||
|
||||
|
@ -940,6 +947,20 @@ namespace ChocolArm64.Instruction
|
|||
EmitVectorInsertTmp(Context, Index, Op.Size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int Index = 0; Index < Elems; Index++)
|
||||
{
|
||||
EmitVectorExtract(Context, Op.Rn, Index, Op.Size, Signed);
|
||||
EmitVectorExtract(Context, ((AOpCodeSimdReg)Op).Rm, Index, Op.Size, Signed);
|
||||
|
||||
Emit();
|
||||
|
||||
EmitSatQ(Context, Op.Size, true, Signed);
|
||||
|
||||
EmitVectorInsertTmp(Context, Index, Op.Size);
|
||||
}
|
||||
}
|
||||
|
||||
Context.EmitLdvectmp();
|
||||
Context.EmitStvec(Op.Rd);
|
||||
|
@ -1080,29 +1101,17 @@ namespace ChocolArm64.Instruction
|
|||
}
|
||||
}
|
||||
|
||||
// TSrc (8bit, 16bit, 32bit, 64bit) == TDst (8bit, 16bit, 32bit, 64bit); signed.
|
||||
public static void EmitUnarySignedSatQAbsOrNeg(AILEmitterCtx Context, int Size)
|
||||
// TSrc (64bit) == TDst (64bit); signed.
|
||||
public static void EmitUnarySignedSatQAbsOrNeg(AILEmitterCtx Context)
|
||||
{
|
||||
int ESize = 8 << Size;
|
||||
if (((AOpCodeSimd)Context.CurrOp).Size < 3)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
long TMaxValue = (1L << (ESize - 1)) - 1L;
|
||||
long TMinValue = -(1L << (ESize - 1));
|
||||
Context.EmitLdarg(ATranslatedSub.StateArgIdx);
|
||||
|
||||
AILLabel LblFalse = new AILLabel();
|
||||
|
||||
Context.Emit(OpCodes.Dup);
|
||||
Context.Emit(OpCodes.Neg);
|
||||
Context.EmitLdc_I8(TMinValue);
|
||||
Context.Emit(OpCodes.Ceq);
|
||||
Context.Emit(OpCodes.Brfalse_S, LblFalse);
|
||||
|
||||
Context.Emit(OpCodes.Pop);
|
||||
|
||||
EmitSetFpsrQCFlag(Context);
|
||||
|
||||
Context.EmitLdc_I8(TMaxValue);
|
||||
|
||||
Context.MarkLabel(LblFalse);
|
||||
ASoftFallback.EmitCall(Context, nameof(ASoftFallback.UnarySignedSatQAbsOrNeg));
|
||||
}
|
||||
|
||||
// TSrcs (64bit) == TDst (64bit); signed, unsigned.
|
||||
|
@ -1150,22 +1159,6 @@ namespace ChocolArm64.Instruction
|
|||
: nameof(ASoftFallback.BinaryUnsignedSatQAcc));
|
||||
}
|
||||
|
||||
public static void EmitSetFpsrQCFlag(AILEmitterCtx Context)
|
||||
{
|
||||
const int QCFlagBit = 27;
|
||||
|
||||
Context.EmitLdarg(ATranslatedSub.StateArgIdx);
|
||||
|
||||
Context.EmitLdarg(ATranslatedSub.StateArgIdx);
|
||||
Context.EmitCallPropGet(typeof(AThreadState), nameof(AThreadState.Fpsr));
|
||||
|
||||
Context.EmitLdc_I4(1 << QCFlagBit);
|
||||
|
||||
Context.Emit(OpCodes.Or);
|
||||
|
||||
Context.EmitCallPropSet(typeof(AThreadState), nameof(AThreadState.Fpsr));
|
||||
}
|
||||
|
||||
public static void EmitScalarSet(AILEmitterCtx Context, int Reg, int Size)
|
||||
{
|
||||
EmitVectorZeroAll(Context, Reg);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue