Add Sqxtn_S, Sqxtn_V, Uqxtn_S, Uqxtn_V instructions and Tests (6). (#110)
* Update ILGeneratorEx.cs * Update AOpCodeTable.cs * Update AInstEmitSimdArithmetic.cs * Update CpuTestSimd.cs * Update CpuTestSimdReg.cs * Update CpuTest.cs * Update Pseudocode.cs * Update Instructions.cs * Update AInstEmitSimdArithmetic.cs * Update AInstEmitSimdArithmetic.cs * Update AInstEmitSimdArithmetic.cs
This commit is contained in:
parent
3f3844583f
commit
f9b17f86c1
3 changed files with 104 additions and 2 deletions
|
@ -337,6 +337,8 @@ namespace ChocolArm64
|
||||||
Set("0x001110<<1xxxxx011011xxxxxxxxxx", AInstEmit.Smin_V, typeof(AOpCodeSimdReg));
|
Set("0x001110<<1xxxxx011011xxxxxxxxxx", AInstEmit.Smin_V, typeof(AOpCodeSimdReg));
|
||||||
Set("0x001110<<1xxxxx100000xxxxxxxxxx", AInstEmit.Smlal_V, typeof(AOpCodeSimdReg));
|
Set("0x001110<<1xxxxx100000xxxxxxxxxx", AInstEmit.Smlal_V, typeof(AOpCodeSimdReg));
|
||||||
Set("0x001110<<1xxxxx110000xxxxxxxxxx", AInstEmit.Smull_V, typeof(AOpCodeSimdReg));
|
Set("0x001110<<1xxxxx110000xxxxxxxxxx", AInstEmit.Smull_V, typeof(AOpCodeSimdReg));
|
||||||
|
Set("01011110<<100001010010xxxxxxxxxx", AInstEmit.Sqxtn_S, typeof(AOpCodeSimd));
|
||||||
|
Set("0x001110<<100001010010xxxxxxxxxx", AInstEmit.Sqxtn_V, typeof(AOpCodeSimd));
|
||||||
Set("0>001110<<1xxxxx010001xxxxxxxxxx", AInstEmit.Sshl_V, typeof(AOpCodeSimdReg));
|
Set("0>001110<<1xxxxx010001xxxxxxxxxx", AInstEmit.Sshl_V, typeof(AOpCodeSimdReg));
|
||||||
Set("0x00111100>>>xxx101001xxxxxxxxxx", AInstEmit.Sshll_V, typeof(AOpCodeSimdShImm));
|
Set("0x00111100>>>xxx101001xxxxxxxxxx", AInstEmit.Sshll_V, typeof(AOpCodeSimdShImm));
|
||||||
Set("010111110>>>>xxx000001xxxxxxxxxx", AInstEmit.Sshr_S, typeof(AOpCodeSimdShImm));
|
Set("010111110>>>>xxx000001xxxxxxxxxx", AInstEmit.Sshr_S, typeof(AOpCodeSimdShImm));
|
||||||
|
@ -370,6 +372,8 @@ namespace ChocolArm64
|
||||||
Set("0x101110<<1xxxxx000001xxxxxxxxxx", AInstEmit.Uhadd_V, typeof(AOpCodeSimdReg));
|
Set("0x101110<<1xxxxx000001xxxxxxxxxx", AInstEmit.Uhadd_V, typeof(AOpCodeSimdReg));
|
||||||
Set("0x001110000xxxxx001111xxxxxxxxxx", AInstEmit.Umov_S, typeof(AOpCodeSimdIns));
|
Set("0x001110000xxxxx001111xxxxxxxxxx", AInstEmit.Umov_S, typeof(AOpCodeSimdIns));
|
||||||
Set("0x101110<<1xxxxx110000xxxxxxxxxx", AInstEmit.Umull_V, typeof(AOpCodeSimdReg));
|
Set("0x101110<<1xxxxx110000xxxxxxxxxx", AInstEmit.Umull_V, typeof(AOpCodeSimdReg));
|
||||||
|
Set("01111110<<100001010010xxxxxxxxxx", AInstEmit.Uqxtn_S, typeof(AOpCodeSimd));
|
||||||
|
Set("0x101110<<100001010010xxxxxxxxxx", AInstEmit.Uqxtn_V, typeof(AOpCodeSimd));
|
||||||
Set("0>101110<<1xxxxx010001xxxxxxxxxx", AInstEmit.Ushl_V, typeof(AOpCodeSimdReg));
|
Set("0>101110<<1xxxxx010001xxxxxxxxxx", AInstEmit.Ushl_V, typeof(AOpCodeSimdReg));
|
||||||
Set("0x10111100>>>xxx101001xxxxxxxxxx", AInstEmit.Ushll_V, typeof(AOpCodeSimdShImm));
|
Set("0x10111100>>>xxx101001xxxxxxxxxx", AInstEmit.Ushll_V, typeof(AOpCodeSimdShImm));
|
||||||
Set("011111110>>>>xxx000001xxxxxxxxxx", AInstEmit.Ushr_S, typeof(AOpCodeSimdShImm));
|
Set("011111110>>>>xxx000001xxxxxxxxxx", AInstEmit.Ushr_S, typeof(AOpCodeSimdShImm));
|
||||||
|
|
|
@ -205,6 +205,84 @@ namespace ChocolArm64.Instruction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void EmitQxtn(AILEmitterCtx Context, bool Signed, bool Scalar)
|
||||||
|
{
|
||||||
|
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
|
||||||
|
|
||||||
|
int Elems = (!Scalar ? 8 >> Op.Size : 1);
|
||||||
|
int ESize = 8 << Op.Size;
|
||||||
|
|
||||||
|
int TMaxValue = (Signed ? (1 << (ESize - 1)) - 1 : (int)((1L << ESize) - 1L));
|
||||||
|
int TMinValue = (Signed ? -((1 << (ESize - 1))) : 0);
|
||||||
|
|
||||||
|
int Part = (!Scalar & (Op.RegisterSize == ARegisterSize.SIMD128) ? Elems : 0);
|
||||||
|
|
||||||
|
Context.EmitLdc_I8(0L);
|
||||||
|
Context.EmitSttmp();
|
||||||
|
|
||||||
|
for (int Index = 0; Index < Elems; Index++)
|
||||||
|
{
|
||||||
|
AILLabel LblLe = new AILLabel();
|
||||||
|
AILLabel LblGeEnd = new AILLabel();
|
||||||
|
|
||||||
|
EmitVectorExtract(Context, Op.Rn, Index, Op.Size + 1, Signed);
|
||||||
|
|
||||||
|
Context.Emit(OpCodes.Dup);
|
||||||
|
|
||||||
|
Context.EmitLdc_I4(TMaxValue);
|
||||||
|
Context.Emit(OpCodes.Conv_U8);
|
||||||
|
|
||||||
|
Context.Emit(Signed ? OpCodes.Ble_S : OpCodes.Ble_Un_S, LblLe);
|
||||||
|
|
||||||
|
Context.Emit(OpCodes.Pop);
|
||||||
|
|
||||||
|
Context.EmitLdc_I4(TMaxValue);
|
||||||
|
|
||||||
|
Context.EmitLdc_I8(0x8000000L);
|
||||||
|
Context.EmitSttmp();
|
||||||
|
|
||||||
|
Context.Emit(OpCodes.Br_S, LblGeEnd);
|
||||||
|
|
||||||
|
Context.MarkLabel(LblLe);
|
||||||
|
|
||||||
|
Context.Emit(OpCodes.Dup);
|
||||||
|
|
||||||
|
Context.EmitLdc_I4(TMinValue);
|
||||||
|
Context.Emit(OpCodes.Conv_I8);
|
||||||
|
|
||||||
|
Context.Emit(Signed ? OpCodes.Bge_S : OpCodes.Bge_Un_S, LblGeEnd);
|
||||||
|
|
||||||
|
Context.Emit(OpCodes.Pop);
|
||||||
|
|
||||||
|
Context.EmitLdc_I4(TMinValue);
|
||||||
|
|
||||||
|
Context.EmitLdc_I8(0x8000000L);
|
||||||
|
Context.EmitSttmp();
|
||||||
|
|
||||||
|
Context.MarkLabel(LblGeEnd);
|
||||||
|
|
||||||
|
if (Scalar)
|
||||||
|
{
|
||||||
|
EmitVectorZeroLower(Context, Op.Rd);
|
||||||
|
}
|
||||||
|
|
||||||
|
EmitVectorInsert(Context, Op.Rd, Part + Index, Op.Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Part == 0)
|
||||||
|
{
|
||||||
|
EmitVectorZeroUpper(Context, Op.Rd);
|
||||||
|
}
|
||||||
|
|
||||||
|
Context.EmitLdarg(ATranslatedSub.StateArgIdx);
|
||||||
|
Context.EmitLdarg(ATranslatedSub.StateArgIdx);
|
||||||
|
Context.EmitCallPropGet(typeof(AThreadState), nameof(AThreadState.Fpsr));
|
||||||
|
Context.EmitLdtmp();
|
||||||
|
Context.Emit(OpCodes.Conv_I4);
|
||||||
|
Context.Emit(OpCodes.Or);
|
||||||
|
Context.EmitCallPropSet(typeof(AThreadState), nameof(AThreadState.Fpsr));
|
||||||
|
}
|
||||||
|
|
||||||
public static void Fabd_S(AILEmitterCtx Context)
|
public static void Fabd_S(AILEmitterCtx Context)
|
||||||
{
|
{
|
||||||
EmitScalarBinaryOpF(Context, () =>
|
EmitScalarBinaryOpF(Context, () =>
|
||||||
|
@ -971,6 +1049,16 @@ namespace ChocolArm64.Instruction
|
||||||
EmitVectorWidenRnRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Mul));
|
EmitVectorWidenRnRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Mul));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Sqxtn_S(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitQxtn(Context, Signed: true, Scalar: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Sqxtn_V(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitQxtn(Context, Signed: true, Scalar: false);
|
||||||
|
}
|
||||||
|
|
||||||
public static void Sub_S(AILEmitterCtx Context)
|
public static void Sub_S(AILEmitterCtx Context)
|
||||||
{
|
{
|
||||||
EmitScalarBinaryOpZx(Context, () => Context.Emit(OpCodes.Sub));
|
EmitScalarBinaryOpZx(Context, () => Context.Emit(OpCodes.Sub));
|
||||||
|
@ -1049,5 +1137,15 @@ namespace ChocolArm64.Instruction
|
||||||
{
|
{
|
||||||
EmitVectorWidenRnRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Mul));
|
EmitVectorWidenRnRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Mul));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Uqxtn_S(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitQxtn(Context, Signed: false, Scalar: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Uqxtn_V(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitQxtn(Context, Signed: false, Scalar: false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace ChocolArm64
|
||||||
|
|
||||||
static class ILGeneratorEx
|
static class ILGeneratorEx
|
||||||
{
|
{
|
||||||
public static void EmitLdc_I4(this ILGenerator Generator,int Value)
|
public static void EmitLdc_I4(this ILGenerator Generator, int Value)
|
||||||
{
|
{
|
||||||
switch (Value)
|
switch (Value)
|
||||||
{
|
{
|
||||||
|
@ -126,4 +126,4 @@ namespace ChocolArm64
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue