Update AInstEmitSimdHelper.cs

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