Update AInstEmitSimdHelper.cs

This commit is contained in:
LDj3SNuD 2018-08-04 14:10:45 +02:00 committed by GitHub
parent 8ae609dbf1
commit 1e952e641e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -826,8 +826,6 @@ namespace ChocolArm64.Instruction
int Bytes = Op.GetBitsCount() >> 3;
int Elems = !Scalar ? Bytes >> Op.Size : 1;
EmitResetSaturatedFlag(Context);
if (Scalar)
{
EmitVectorZeroLowerTmp(Context);
@ -851,8 +849,6 @@ namespace ChocolArm64.Instruction
{
EmitVectorZeroUpper(Context, Op.Rd);
}
EmitUpdateFpsrQCFlag(Context);
}
public static void EmitScalarSaturatingBinaryOpSx(AILEmitterCtx Context, SaturatingFlags Flags)
@ -890,8 +886,6 @@ namespace ChocolArm64.Instruction
int Bytes = Op.GetBitsCount() >> 3;
int Elems = !Scalar ? Bytes >> Op.Size : 1;
EmitResetSaturatedFlag(Context);
if (Scalar)
{
EmitVectorZeroLowerTmp(Context);
@ -901,11 +895,11 @@ namespace ChocolArm64.Instruction
{
if (Add || Sub)
{
EmitVectorExtract(Context, Op.Rn, Index, Op.Size, Signed);
EmitVectorExtract(Context, ((AOpCodeSimdReg)Op).Rm, Index, Op.Size, Signed);
if (Op.Size <= 2)
{
EmitVectorExtract(Context, Op.Rn, Index, Op.Size, Signed);
EmitVectorExtract(Context, ((AOpCodeSimdReg)Op).Rm, Index, Op.Size, Signed);
Context.Emit(Add ? OpCodes.Add : OpCodes.Sub);
EmitSatQ(Context, Op.Size, true, Signed);
@ -914,29 +908,29 @@ namespace ChocolArm64.Instruction
{
if (Add)
{
EmitBinarySatQAdd(Context, Index, Signed);
EmitBinarySatQAdd(Context, Signed);
}
else /* if (Sub) */
{
EmitBinarySatQSub(Context, Index, Signed);
EmitBinarySatQSub(Context, Signed);
}
}
}
if (Accumulate)
{
EmitVectorExtract(Context, Op.Rn, Index, Op.Size, !Signed);
EmitVectorExtract(Context, Op.Rd, Index, Op.Size, Signed);
if (Op.Size <= 2)
{
EmitVectorExtract(Context, Op.Rn, Index, Op.Size, !Signed);
EmitVectorExtract(Context, Op.Rd, Index, Op.Size, Signed);
Context.Emit(OpCodes.Add);
EmitSatQ(Context, Op.Size, true, Signed);
}
else /* if (Op.Size == 3) */
{
EmitBinarySatQAccumulate(Context, Index, Signed);
EmitBinarySatQAccumulate(Context, Signed);
}
}
@ -950,8 +944,6 @@ namespace ChocolArm64.Instruction
{
EmitVectorZeroUpper(Context, Op.Rd);
}
EmitUpdateFpsrQCFlag(Context);
}
[Flags]
@ -963,10 +955,12 @@ namespace ChocolArm64.Instruction
ScalarSxSx = Scalar | SignedSrc | SignedDst,
ScalarSxZx = Scalar | SignedSrc,
ScalarZxSx = Scalar | SignedDst,
ScalarZxZx = Scalar,
VectorSxSx = SignedSrc | SignedDst,
VectorSxZx = SignedSrc,
VectorZxSx = SignedDst,
VectorZxZx = 0
}
@ -980,6 +974,11 @@ namespace ChocolArm64.Instruction
EmitSaturatingNarrowOp(Context, Emit, SaturatingNarrowFlags.ScalarSxZx);
}
public static void EmitScalarSaturatingNarrowOpZxSx(AILEmitterCtx Context, Action Emit)
{
EmitSaturatingNarrowOp(Context, Emit, SaturatingNarrowFlags.ScalarZxSx);
}
public static void EmitScalarSaturatingNarrowOpZxZx(AILEmitterCtx Context, Action Emit)
{
EmitSaturatingNarrowOp(Context, Emit, SaturatingNarrowFlags.ScalarZxZx);
@ -995,6 +994,11 @@ namespace ChocolArm64.Instruction
EmitSaturatingNarrowOp(Context, Emit, SaturatingNarrowFlags.VectorSxZx);
}
public static void EmitVectorSaturatingNarrowOpZxSx(AILEmitterCtx Context, Action Emit)
{
EmitSaturatingNarrowOp(Context, Emit, SaturatingNarrowFlags.VectorZxSx);
}
public static void EmitVectorSaturatingNarrowOpZxZx(AILEmitterCtx Context, Action Emit)
{
EmitSaturatingNarrowOp(Context, Emit, SaturatingNarrowFlags.VectorZxZx);
@ -1012,8 +1016,6 @@ namespace ChocolArm64.Instruction
int Part = !Scalar && (Op.RegisterSize == ARegisterSize.SIMD128) ? Elems : 0;
EmitResetSaturatedFlag(Context);
if (Scalar)
{
EmitVectorZeroLowerTmp(Context);
@ -1043,11 +1045,9 @@ namespace ChocolArm64.Instruction
{
EmitVectorZeroUpper(Context, Op.Rd);
}
EmitUpdateFpsrQCFlag(Context);
}
// TSrc (16bit, 32bit, 64bit) > TDst (8bit, 16bit, 32bit); signed, unsigned.
// TSrc (16bit, 32bit, 64bit; signed, unsigned) > TDst (8bit, 16bit, 32bit; signed, unsigned).
public static void EmitSatQ(
AILEmitterCtx Context,
int SizeDst,
@ -1059,39 +1059,21 @@ namespace ChocolArm64.Instruction
throw new ArgumentOutOfRangeException(nameof(SizeDst));
}
int ESize = 8 << SizeDst;
Context.EmitLdc_I4(SizeDst);
Context.EmitLdarg(ATranslatedSub.StateArgIdx);
long TMaxValue = SignedDst ? (1 << (ESize - 1)) - 1 : (1L << ESize) - 1L;
long TMinValue = SignedDst ? -(1 << (ESize - 1)) : 0L;
AILLabel LblLe = new AILLabel();
AILLabel LblGeEnd = new AILLabel();
Context.Emit(OpCodes.Dup);
Context.EmitLdc_I8(TMaxValue);
Context.Emit(SignedSrc ? OpCodes.Ble_S : OpCodes.Ble_Un_S, LblLe);
Context.Emit(OpCodes.Pop);
EmitSetSaturatedFlag(Context);
Context.EmitLdc_I8(TMaxValue);
Context.Emit(OpCodes.Br_S, LblGeEnd);
Context.MarkLabel(LblLe);
Context.Emit(OpCodes.Dup);
Context.EmitLdc_I8(TMinValue);
Context.Emit(SignedSrc ? OpCodes.Bge_S : OpCodes.Bge_Un_S, LblGeEnd);
Context.Emit(OpCodes.Pop);
EmitSetSaturatedFlag(Context);
Context.EmitLdc_I8(TMinValue);
Context.MarkLabel(LblGeEnd);
if (SignedSrc)
{
ASoftFallback.EmitCall(Context, SignedDst
? nameof(ASoftFallback.SignedSrcSignedDstSatQ)
: nameof(ASoftFallback.SignedSrcUnsignedDstSatQ));
}
else
{
ASoftFallback.EmitCall(Context, SignedDst
? nameof(ASoftFallback.UnsignedSrcSignedDstSatQ)
: nameof(ASoftFallback.UnsignedSrcUnsignedDstSatQ));
}
}
// TSrc (8bit, 16bit, 32bit, 64bit) == TDst (8bit, 16bit, 32bit, 64bit); signed.
@ -1112,7 +1094,7 @@ namespace ChocolArm64.Instruction
Context.Emit(OpCodes.Pop);
EmitSetSaturatedFlag(Context);
EmitSetFpsrQCFlag(Context);
Context.EmitLdc_I8(TMaxValue);
@ -1120,17 +1102,13 @@ namespace ChocolArm64.Instruction
}
// TSrcs (64bit) == TDst (64bit); signed, unsigned.
public static void EmitBinarySatQAdd(AILEmitterCtx Context, int Index, bool Signed)
public static void EmitBinarySatQAdd(AILEmitterCtx Context, bool Signed)
{
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
if (Op.Size < 3)
if (((AOpCodeSimdReg)Context.CurrOp).Size < 3)
{
throw new InvalidOperationException();
}
EmitVectorExtract(Context, Op.Rn, Index, 3, Signed);
EmitVectorExtract(Context, Op.Rm, Index, 3, Signed);
Context.EmitLdarg(ATranslatedSub.StateArgIdx);
ASoftFallback.EmitCall(Context, Signed
@ -1139,17 +1117,13 @@ namespace ChocolArm64.Instruction
}
// TSrcs (64bit) == TDst (64bit); signed, unsigned.
public static void EmitBinarySatQSub(AILEmitterCtx Context, int Index, bool Signed)
public static void EmitBinarySatQSub(AILEmitterCtx Context, bool Signed)
{
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
if (Op.Size < 3)
if (((AOpCodeSimdReg)Context.CurrOp).Size < 3)
{
throw new InvalidOperationException();
}
EmitVectorExtract(Context, Op.Rn, Index, 3, Signed);
EmitVectorExtract(Context, Op.Rm, Index, 3, Signed);
Context.EmitLdarg(ATranslatedSub.StateArgIdx);
ASoftFallback.EmitCall(Context, Signed
@ -1158,17 +1132,13 @@ namespace ChocolArm64.Instruction
}
// TSrcs (64bit) == TDst (64bit); signed, unsigned.
public static void EmitBinarySatQAccumulate(AILEmitterCtx Context, int Index, bool Signed)
public static void EmitBinarySatQAccumulate(AILEmitterCtx Context, bool Signed)
{
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
if (Op.Size < 3)
if (((AOpCodeSimd)Context.CurrOp).Size < 3)
{
throw new InvalidOperationException();
}
EmitVectorExtract(Context, Op.Rn, Index, 3, !Signed);
EmitVectorExtract(Context, Op.Rd, Index, 3, Signed);
Context.EmitLdarg(ATranslatedSub.StateArgIdx);
ASoftFallback.EmitCall(Context, Signed
@ -1176,19 +1146,7 @@ namespace ChocolArm64.Instruction
: nameof(ASoftFallback.BinaryUnsignedSatQAcc));
}
public static void EmitResetSaturatedFlag(AILEmitterCtx Context)
{
Context.EmitLdc_I8(0L);
Context.EmitSttmp(); // Saturated = 0
}
public static void EmitSetSaturatedFlag(AILEmitterCtx Context)
{
Context.EmitLdc_I8(1L);
Context.EmitSttmp(); // Saturated = 1
}
public static void EmitUpdateFpsrQCFlag(AILEmitterCtx Context)
public static void EmitSetFpsrQCFlag(AILEmitterCtx Context)
{
const int QCFlagBit = 27;
@ -1197,9 +1155,7 @@ namespace ChocolArm64.Instruction
Context.EmitLdarg(ATranslatedSub.StateArgIdx);
Context.EmitCallPropGet(typeof(AThreadState), nameof(AThreadState.Fpsr));
Context.EmitLdtmp(); // Saturated == 0 || Saturated == 1
Context.Emit(OpCodes.Conv_I4);
Context.EmitLsl(QCFlagBit);
Context.EmitLdc_I4(1 << QCFlagBit);
Context.Emit(OpCodes.Or);