Update AInstEmitSimdHelper.cs
This commit is contained in:
parent
db02095f37
commit
1fbe32a7bb
1 changed files with 36 additions and 43 deletions
|
@ -804,7 +804,7 @@ namespace ChocolArm64.Instruction
|
||||||
ScalarZx = Scalar,
|
ScalarZx = Scalar,
|
||||||
|
|
||||||
VectorSx = Signed,
|
VectorSx = Signed,
|
||||||
VectorZx = 0,
|
VectorZx = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void EmitScalarSaturatingUnaryOpSx(AILEmitterCtx Context, Action Emit)
|
public static void EmitScalarSaturatingUnaryOpSx(AILEmitterCtx Context, Action Emit)
|
||||||
|
@ -837,7 +837,14 @@ namespace ChocolArm64.Instruction
|
||||||
|
|
||||||
Emit();
|
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);
|
EmitVectorInsertTmp(Context, Index, Op.Size);
|
||||||
}
|
}
|
||||||
|
@ -853,25 +860,25 @@ namespace ChocolArm64.Instruction
|
||||||
|
|
||||||
public static void EmitScalarSaturatingBinaryOpSx(AILEmitterCtx Context, SaturatingFlags Flags)
|
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)
|
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)
|
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)
|
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;
|
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
|
||||||
|
|
||||||
|
@ -940,6 +947,20 @@ namespace ChocolArm64.Instruction
|
||||||
EmitVectorInsertTmp(Context, Index, Op.Size);
|
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.EmitLdvectmp();
|
||||||
Context.EmitStvec(Op.Rd);
|
Context.EmitStvec(Op.Rd);
|
||||||
|
@ -1080,29 +1101,17 @@ namespace ChocolArm64.Instruction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TSrc (8bit, 16bit, 32bit, 64bit) == TDst (8bit, 16bit, 32bit, 64bit); signed.
|
// TSrc (64bit) == TDst (64bit); signed.
|
||||||
public static void EmitUnarySignedSatQAbsOrNeg(AILEmitterCtx Context, int Size)
|
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;
|
Context.EmitLdarg(ATranslatedSub.StateArgIdx);
|
||||||
long TMinValue = -(1L << (ESize - 1));
|
|
||||||
|
|
||||||
AILLabel LblFalse = new AILLabel();
|
ASoftFallback.EmitCall(Context, nameof(ASoftFallback.UnarySignedSatQAbsOrNeg));
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TSrcs (64bit) == TDst (64bit); signed, unsigned.
|
// TSrcs (64bit) == TDst (64bit); signed, unsigned.
|
||||||
|
@ -1150,22 +1159,6 @@ namespace ChocolArm64.Instruction
|
||||||
: nameof(ASoftFallback.BinaryUnsignedSatQAcc));
|
: 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)
|
public static void EmitScalarSet(AILEmitterCtx Context, int Reg, int Size)
|
||||||
{
|
{
|
||||||
EmitVectorZeroAll(Context, Reg);
|
EmitVectorZeroAll(Context, Reg);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue