Add Fcvtns_S, Fcvtns_V, Fcvtnu_S, Fcvtnu_V (AOpCodeSimd) FP & Umlal_V, Umlsl_V, Saddl_V, Ssubl_V, Usubl_V instructions; add 8 FP & 16 S/Umlal_V, S/Umlsl_V, S/Uaddl_V, S/Usubl_V Tests. (#390)
* Update AOpCodeTable.cs * Update AInstEmitSimdCvt.cs * Update Pseudocode.cs * Update Instructions.cs * Update CpuTestSimd.cs * Update AOpCodeTable.cs * Update AInstEmitSimdArithmetic.cs * Update Instructions.cs * Update CpuTestSimdReg.cs * Update CpuTestSimd.cs * Update AOpCodeTable.cs * Update AInstEmitSimdArithmetic.cs * Update Instructions.cs * Update CpuTestSimdReg.cs * Add QCFlagBit. * Add QCFlagBit.
This commit is contained in:
parent
d567d15ff3
commit
1be39f720f
3 changed files with 111 additions and 1 deletions
|
@ -255,6 +255,10 @@ namespace ChocolArm64
|
||||||
SetA64("x00111100x110000000000xxxxxxxxxx", AInstEmit.Fcvtms_Gp, typeof(AOpCodeSimdCvt));
|
SetA64("x00111100x110000000000xxxxxxxxxx", AInstEmit.Fcvtms_Gp, typeof(AOpCodeSimdCvt));
|
||||||
SetA64("x00111100x110001000000xxxxxxxxxx", AInstEmit.Fcvtmu_Gp, typeof(AOpCodeSimdCvt));
|
SetA64("x00111100x110001000000xxxxxxxxxx", AInstEmit.Fcvtmu_Gp, typeof(AOpCodeSimdCvt));
|
||||||
SetA64("0x0011100x100001011010xxxxxxxxxx", AInstEmit.Fcvtn_V, typeof(AOpCodeSimd));
|
SetA64("0x0011100x100001011010xxxxxxxxxx", AInstEmit.Fcvtn_V, typeof(AOpCodeSimd));
|
||||||
|
SetA64("010111100x100001101010xxxxxxxxxx", AInstEmit.Fcvtns_S, typeof(AOpCodeSimd));
|
||||||
|
SetA64("0>0011100<100001101010xxxxxxxxxx", AInstEmit.Fcvtns_V, typeof(AOpCodeSimd));
|
||||||
|
SetA64("011111100x100001101010xxxxxxxxxx", AInstEmit.Fcvtnu_S, typeof(AOpCodeSimd));
|
||||||
|
SetA64("0>1011100<100001101010xxxxxxxxxx", AInstEmit.Fcvtnu_V, typeof(AOpCodeSimd));
|
||||||
SetA64("x00111100x101000000000xxxxxxxxxx", AInstEmit.Fcvtps_Gp, typeof(AOpCodeSimdCvt));
|
SetA64("x00111100x101000000000xxxxxxxxxx", AInstEmit.Fcvtps_Gp, typeof(AOpCodeSimdCvt));
|
||||||
SetA64("x00111100x101001000000xxxxxxxxxx", AInstEmit.Fcvtpu_Gp, typeof(AOpCodeSimdCvt));
|
SetA64("x00111100x101001000000xxxxxxxxxx", AInstEmit.Fcvtpu_Gp, typeof(AOpCodeSimdCvt));
|
||||||
SetA64("x00111100x111000000000xxxxxxxxxx", AInstEmit.Fcvtzs_Gp, typeof(AOpCodeSimdCvt));
|
SetA64("x00111100x111000000000xxxxxxxxxx", AInstEmit.Fcvtzs_Gp, typeof(AOpCodeSimdCvt));
|
||||||
|
@ -365,6 +369,7 @@ namespace ChocolArm64
|
||||||
SetA64("0x001110<<1xxxxx011101xxxxxxxxxx", AInstEmit.Sabd_V, typeof(AOpCodeSimdReg));
|
SetA64("0x001110<<1xxxxx011101xxxxxxxxxx", AInstEmit.Sabd_V, typeof(AOpCodeSimdReg));
|
||||||
SetA64("0x001110<<1xxxxx011100xxxxxxxxxx", AInstEmit.Sabdl_V, typeof(AOpCodeSimdReg));
|
SetA64("0x001110<<1xxxxx011100xxxxxxxxxx", AInstEmit.Sabdl_V, typeof(AOpCodeSimdReg));
|
||||||
SetA64("0x001110<<100000011010xxxxxxxxxx", AInstEmit.Sadalp_V, typeof(AOpCodeSimd));
|
SetA64("0x001110<<100000011010xxxxxxxxxx", AInstEmit.Sadalp_V, typeof(AOpCodeSimd));
|
||||||
|
SetA64("0x001110<<1xxxxx000000xxxxxxxxxx", AInstEmit.Saddl_V, typeof(AOpCodeSimdReg));
|
||||||
SetA64("0x001110<<100000001010xxxxxxxxxx", AInstEmit.Saddlp_V, typeof(AOpCodeSimd));
|
SetA64("0x001110<<100000001010xxxxxxxxxx", AInstEmit.Saddlp_V, typeof(AOpCodeSimd));
|
||||||
SetA64("0x001110<<1xxxxx000100xxxxxxxxxx", AInstEmit.Saddw_V, typeof(AOpCodeSimdReg));
|
SetA64("0x001110<<1xxxxx000100xxxxxxxxxx", AInstEmit.Saddw_V, typeof(AOpCodeSimdReg));
|
||||||
SetA64("x0011110xx100010000000xxxxxxxxxx", AInstEmit.Scvtf_Gp, typeof(AOpCodeSimdCvt));
|
SetA64("x0011110xx100010000000xxxxxxxxxx", AInstEmit.Scvtf_Gp, typeof(AOpCodeSimdCvt));
|
||||||
|
@ -419,6 +424,7 @@ namespace ChocolArm64
|
||||||
SetA64("0100111101xxxxxx000001xxxxxxxxxx", AInstEmit.Sshr_V, typeof(AOpCodeSimdShImm));
|
SetA64("0100111101xxxxxx000001xxxxxxxxxx", AInstEmit.Sshr_V, typeof(AOpCodeSimdShImm));
|
||||||
SetA64("0x00111100>>>xxx000101xxxxxxxxxx", AInstEmit.Ssra_V, typeof(AOpCodeSimdShImm));
|
SetA64("0x00111100>>>xxx000101xxxxxxxxxx", AInstEmit.Ssra_V, typeof(AOpCodeSimdShImm));
|
||||||
SetA64("0100111101xxxxxx000101xxxxxxxxxx", AInstEmit.Ssra_V, typeof(AOpCodeSimdShImm));
|
SetA64("0100111101xxxxxx000101xxxxxxxxxx", AInstEmit.Ssra_V, typeof(AOpCodeSimdShImm));
|
||||||
|
SetA64("0x001110<<1xxxxx001000xxxxxxxxxx", AInstEmit.Ssubl_V, typeof(AOpCodeSimdReg));
|
||||||
SetA64("0x001110<<1xxxxx001100xxxxxxxxxx", AInstEmit.Ssubw_V, typeof(AOpCodeSimdReg));
|
SetA64("0x001110<<1xxxxx001100xxxxxxxxxx", AInstEmit.Ssubw_V, typeof(AOpCodeSimdReg));
|
||||||
SetA64("0x00110000000000xxxxxxxxxxxxxxxx", AInstEmit.St__Vms, typeof(AOpCodeSimdMemMs));
|
SetA64("0x00110000000000xxxxxxxxxxxxxxxx", AInstEmit.St__Vms, typeof(AOpCodeSimdMemMs));
|
||||||
SetA64("0x001100100xxxxxxxxxxxxxxxxxxxxx", AInstEmit.St__Vms, typeof(AOpCodeSimdMemMs));
|
SetA64("0x001100100xxxxxxxxxxxxxxxxxxxxx", AInstEmit.St__Vms, typeof(AOpCodeSimdMemMs));
|
||||||
|
@ -457,6 +463,8 @@ namespace ChocolArm64
|
||||||
SetA64("0x101110<<1xxxxx101001xxxxxxxxxx", AInstEmit.Umaxp_V, typeof(AOpCodeSimdReg));
|
SetA64("0x101110<<1xxxxx101001xxxxxxxxxx", AInstEmit.Umaxp_V, typeof(AOpCodeSimdReg));
|
||||||
SetA64("0x101110<<1xxxxx011011xxxxxxxxxx", AInstEmit.Umin_V, typeof(AOpCodeSimdReg));
|
SetA64("0x101110<<1xxxxx011011xxxxxxxxxx", AInstEmit.Umin_V, typeof(AOpCodeSimdReg));
|
||||||
SetA64("0x101110<<1xxxxx101011xxxxxxxxxx", AInstEmit.Uminp_V, typeof(AOpCodeSimdReg));
|
SetA64("0x101110<<1xxxxx101011xxxxxxxxxx", AInstEmit.Uminp_V, typeof(AOpCodeSimdReg));
|
||||||
|
SetA64("0x101110<<1xxxxx100000xxxxxxxxxx", AInstEmit.Umlal_V, typeof(AOpCodeSimdReg));
|
||||||
|
SetA64("0x101110<<1xxxxx101000xxxxxxxxxx", AInstEmit.Umlsl_V, typeof(AOpCodeSimdReg));
|
||||||
SetA64("0x001110000xxxxx001111xxxxxxxxxx", AInstEmit.Umov_S, typeof(AOpCodeSimdIns));
|
SetA64("0x001110000xxxxx001111xxxxxxxxxx", AInstEmit.Umov_S, typeof(AOpCodeSimdIns));
|
||||||
SetA64("0x101110<<1xxxxx110000xxxxxxxxxx", AInstEmit.Umull_V, typeof(AOpCodeSimdReg));
|
SetA64("0x101110<<1xxxxx110000xxxxxxxxxx", AInstEmit.Umull_V, typeof(AOpCodeSimdReg));
|
||||||
SetA64("01111110xx1xxxxx000011xxxxxxxxxx", AInstEmit.Uqadd_S, typeof(AOpCodeSimdReg));
|
SetA64("01111110xx1xxxxx000011xxxxxxxxxx", AInstEmit.Uqadd_S, typeof(AOpCodeSimdReg));
|
||||||
|
@ -475,6 +483,7 @@ namespace ChocolArm64
|
||||||
SetA64("0>101110<<100000001110xxxxxxxxxx", AInstEmit.Usqadd_V, typeof(AOpCodeSimd));
|
SetA64("0>101110<<100000001110xxxxxxxxxx", AInstEmit.Usqadd_V, typeof(AOpCodeSimd));
|
||||||
SetA64("0x10111100>>>xxx000101xxxxxxxxxx", AInstEmit.Usra_V, typeof(AOpCodeSimdShImm));
|
SetA64("0x10111100>>>xxx000101xxxxxxxxxx", AInstEmit.Usra_V, typeof(AOpCodeSimdShImm));
|
||||||
SetA64("0110111101xxxxxx000101xxxxxxxxxx", AInstEmit.Usra_V, typeof(AOpCodeSimdShImm));
|
SetA64("0110111101xxxxxx000101xxxxxxxxxx", AInstEmit.Usra_V, typeof(AOpCodeSimdShImm));
|
||||||
|
SetA64("0x101110<<1xxxxx001000xxxxxxxxxx", AInstEmit.Usubl_V, typeof(AOpCodeSimdReg));
|
||||||
SetA64("0x101110<<1xxxxx001100xxxxxxxxxx", AInstEmit.Usubw_V, typeof(AOpCodeSimdReg));
|
SetA64("0x101110<<1xxxxx001100xxxxxxxxxx", AInstEmit.Usubw_V, typeof(AOpCodeSimdReg));
|
||||||
SetA64("0>001110<<0xxxxx000110xxxxxxxxxx", AInstEmit.Uzp1_V, typeof(AOpCodeSimdReg));
|
SetA64("0>001110<<0xxxxx000110xxxxxxxxxx", AInstEmit.Uzp1_V, typeof(AOpCodeSimdReg));
|
||||||
SetA64("0>001110<<0xxxxx010110xxxxxxxxxx", AInstEmit.Uzp2_V, typeof(AOpCodeSimdReg));
|
SetA64("0>001110<<0xxxxx010110xxxxxxxxxx", AInstEmit.Uzp2_V, typeof(AOpCodeSimdReg));
|
||||||
|
|
|
@ -1032,6 +1032,11 @@ namespace ChocolArm64.Instruction
|
||||||
EmitAddLongPairwise(Context, Signed: true, Accumulate: true);
|
EmitAddLongPairwise(Context, Signed: true, Accumulate: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Saddl_V(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitVectorWidenRnRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Add));
|
||||||
|
}
|
||||||
|
|
||||||
public static void Saddlp_V(AILEmitterCtx Context)
|
public static void Saddlp_V(AILEmitterCtx Context)
|
||||||
{
|
{
|
||||||
EmitAddLongPairwise(Context, Signed: true, Accumulate: false);
|
EmitAddLongPairwise(Context, Signed: true, Accumulate: false);
|
||||||
|
@ -1217,6 +1222,11 @@ namespace ChocolArm64.Instruction
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Ssubl_V(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitVectorWidenRnRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Sub));
|
||||||
|
}
|
||||||
|
|
||||||
public static void Ssubw_V(AILEmitterCtx Context)
|
public static void Ssubw_V(AILEmitterCtx Context)
|
||||||
{
|
{
|
||||||
EmitVectorWidenRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Sub));
|
EmitVectorWidenRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Sub));
|
||||||
|
@ -1391,6 +1401,24 @@ namespace ChocolArm64.Instruction
|
||||||
EmitVectorPairwiseOpZx(Context, () => Context.EmitCall(MthdInfo));
|
EmitVectorPairwiseOpZx(Context, () => Context.EmitCall(MthdInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Umlal_V(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitVectorWidenRnRmTernaryOpZx(Context, () =>
|
||||||
|
{
|
||||||
|
Context.Emit(OpCodes.Mul);
|
||||||
|
Context.Emit(OpCodes.Add);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Umlsl_V(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitVectorWidenRnRmTernaryOpZx(Context, () =>
|
||||||
|
{
|
||||||
|
Context.Emit(OpCodes.Mul);
|
||||||
|
Context.Emit(OpCodes.Sub);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public static void Umull_V(AILEmitterCtx Context)
|
public static void Umull_V(AILEmitterCtx Context)
|
||||||
{
|
{
|
||||||
EmitVectorWidenRnRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Mul));
|
EmitVectorWidenRnRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Mul));
|
||||||
|
@ -1450,6 +1478,11 @@ namespace ChocolArm64.Instruction
|
||||||
EmitVectorSaturatingBinaryOpZx(Context, SaturatingFlags.Accumulate);
|
EmitVectorSaturatingBinaryOpZx(Context, SaturatingFlags.Accumulate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Usubl_V(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitVectorWidenRnRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Sub));
|
||||||
|
}
|
||||||
|
|
||||||
public static void Usubw_V(AILEmitterCtx Context)
|
public static void Usubw_V(AILEmitterCtx Context)
|
||||||
{
|
{
|
||||||
EmitVectorWidenRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Sub));
|
EmitVectorWidenRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Sub));
|
||||||
|
|
|
@ -106,6 +106,26 @@ namespace ChocolArm64.Instruction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Fcvtns_S(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitFcvtn(Context, Signed: true, Scalar: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Fcvtns_V(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitFcvtn(Context, Signed: true, Scalar: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Fcvtnu_S(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitFcvtn(Context, Signed: false, Scalar: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Fcvtnu_V(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitFcvtn(Context, Signed: false, Scalar: false);
|
||||||
|
}
|
||||||
|
|
||||||
public static void Fcvtps_Gp(AILEmitterCtx Context)
|
public static void Fcvtps_Gp(AILEmitterCtx Context)
|
||||||
{
|
{
|
||||||
EmitFcvt_s_Gp(Context, () => EmitUnaryMathCall(Context, nameof(Math.Ceiling)));
|
EmitFcvt_s_Gp(Context, () => EmitUnaryMathCall(Context, nameof(Math.Ceiling)));
|
||||||
|
@ -250,6 +270,54 @@ namespace ChocolArm64.Instruction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void EmitFcvtn(AILEmitterCtx Context, bool Signed, bool Scalar)
|
||||||
|
{
|
||||||
|
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
|
||||||
|
|
||||||
|
int SizeF = Op.Size & 1;
|
||||||
|
int SizeI = SizeF + 2;
|
||||||
|
|
||||||
|
int Bytes = Op.GetBitsCount() >> 3;
|
||||||
|
int Elems = !Scalar ? Bytes >> SizeI : 1;
|
||||||
|
|
||||||
|
if (Scalar && (SizeF == 0))
|
||||||
|
{
|
||||||
|
EmitVectorZeroLowerTmp(Context);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int Index = 0; Index < Elems; Index++)
|
||||||
|
{
|
||||||
|
EmitVectorExtractF(Context, Op.Rn, Index, SizeF);
|
||||||
|
|
||||||
|
EmitRoundMathCall(Context, MidpointRounding.ToEven);
|
||||||
|
|
||||||
|
if (SizeF == 0)
|
||||||
|
{
|
||||||
|
AVectorHelper.EmitCall(Context, Signed
|
||||||
|
? nameof(AVectorHelper.SatF32ToS32)
|
||||||
|
: nameof(AVectorHelper.SatF32ToU32));
|
||||||
|
|
||||||
|
Context.Emit(OpCodes.Conv_U8);
|
||||||
|
}
|
||||||
|
else /* if (SizeF == 1) */
|
||||||
|
{
|
||||||
|
AVectorHelper.EmitCall(Context, Signed
|
||||||
|
? nameof(AVectorHelper.SatF64ToS64)
|
||||||
|
: nameof(AVectorHelper.SatF64ToU64));
|
||||||
|
}
|
||||||
|
|
||||||
|
EmitVectorInsertTmp(Context, Index, SizeI);
|
||||||
|
}
|
||||||
|
|
||||||
|
Context.EmitLdvectmp();
|
||||||
|
Context.EmitStvec(Op.Rd);
|
||||||
|
|
||||||
|
if ((Op.RegisterSize == ARegisterSize.SIMD64) || Scalar)
|
||||||
|
{
|
||||||
|
EmitVectorZeroUpper(Context, Op.Rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void EmitFcvt_s_Gp(AILEmitterCtx Context, Action Emit)
|
private static void EmitFcvt_s_Gp(AILEmitterCtx Context, Action Emit)
|
||||||
{
|
{
|
||||||
EmitFcvt___Gp(Context, Emit, true);
|
EmitFcvt___Gp(Context, Emit, true);
|
||||||
|
|
Loading…
Reference in a new issue