SQADD/UQADD instructions
This commit is contained in:
parent
5d698a7d8d
commit
980d30325b
3 changed files with 133 additions and 0 deletions
|
@ -373,6 +373,8 @@ namespace ChocolArm64
|
||||||
SetA64("0x001110<<1xxxxx100000xxxxxxxxxx", AInstEmit.Smlal_V, typeof(AOpCodeSimdReg));
|
SetA64("0x001110<<1xxxxx100000xxxxxxxxxx", AInstEmit.Smlal_V, typeof(AOpCodeSimdReg));
|
||||||
SetA64("0x001110<<1xxxxx101000xxxxxxxxxx", AInstEmit.Smlsl_V, typeof(AOpCodeSimdReg));
|
SetA64("0x001110<<1xxxxx101000xxxxxxxxxx", AInstEmit.Smlsl_V, typeof(AOpCodeSimdReg));
|
||||||
SetA64("0x001110<<1xxxxx110000xxxxxxxxxx", AInstEmit.Smull_V, typeof(AOpCodeSimdReg));
|
SetA64("0x001110<<1xxxxx110000xxxxxxxxxx", AInstEmit.Smull_V, typeof(AOpCodeSimdReg));
|
||||||
|
SetA64("01011110xx1xxxxx000011xxxxxxxxxx", AInstEmit.Sqadd_S, typeof(AOpCodeSimdReg));
|
||||||
|
SetA64("0x001110xx1xxxxx000011xxxxxxxxxx", AInstEmit.Sqadd_V, typeof(AOpCodeSimdReg));
|
||||||
SetA64("0x00111100>>>xxx100111xxxxxxxxxx", AInstEmit.Sqrshrn_V, typeof(AOpCodeSimdShImm));
|
SetA64("0x00111100>>>xxx100111xxxxxxxxxx", AInstEmit.Sqrshrn_V, typeof(AOpCodeSimdShImm));
|
||||||
SetA64("01011110<<100001010010xxxxxxxxxx", AInstEmit.Sqxtn_S, typeof(AOpCodeSimd));
|
SetA64("01011110<<100001010010xxxxxxxxxx", AInstEmit.Sqxtn_S, typeof(AOpCodeSimd));
|
||||||
SetA64("0x001110<<100001010010xxxxxxxxxx", AInstEmit.Sqxtn_V, typeof(AOpCodeSimd));
|
SetA64("0x001110<<100001010010xxxxxxxxxx", AInstEmit.Sqxtn_V, typeof(AOpCodeSimd));
|
||||||
|
@ -421,6 +423,8 @@ namespace ChocolArm64
|
||||||
SetA64("0x101110<<1xxxxx101011xxxxxxxxxx", AInstEmit.Uminp_V, typeof(AOpCodeSimdReg));
|
SetA64("0x101110<<1xxxxx101011xxxxxxxxxx", AInstEmit.Uminp_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("0x101110xx1xxxxx000011xxxxxxxxxx", AInstEmit.Uqadd_V, typeof(AOpCodeSimdReg));
|
||||||
SetA64("01111110<<100001010010xxxxxxxxxx", AInstEmit.Uqxtn_S, typeof(AOpCodeSimd));
|
SetA64("01111110<<100001010010xxxxxxxxxx", AInstEmit.Uqxtn_S, typeof(AOpCodeSimd));
|
||||||
SetA64("0x101110<<100001010010xxxxxxxxxx", AInstEmit.Uqxtn_V, typeof(AOpCodeSimd));
|
SetA64("0x101110<<100001010010xxxxxxxxxx", AInstEmit.Uqxtn_V, typeof(AOpCodeSimd));
|
||||||
SetA64("0>101110<<1xxxxx010001xxxxxxxxxx", AInstEmit.Ushl_V, typeof(AOpCodeSimdReg));
|
SetA64("0>101110<<1xxxxx010001xxxxxxxxxx", AInstEmit.Ushl_V, typeof(AOpCodeSimdReg));
|
||||||
|
|
|
@ -1052,6 +1052,16 @@ namespace ChocolArm64.Instruction
|
||||||
EmitVectorWidenRnRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Mul));
|
EmitVectorWidenRnRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Mul));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Sqadd_S(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitScalarSaturatingOpSxSx(Context, () => Context.Emit(OpCodes.Add));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Sqadd_V(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitVectorSaturatingOpSxSx(Context, () => Context.Emit(OpCodes.Add));
|
||||||
|
}
|
||||||
|
|
||||||
public static void Sqxtn_S(AILEmitterCtx Context)
|
public static void Sqxtn_S(AILEmitterCtx Context)
|
||||||
{
|
{
|
||||||
EmitScalarSaturatingNarrowOpSxSx(Context, () => { });
|
EmitScalarSaturatingNarrowOpSxSx(Context, () => { });
|
||||||
|
@ -1216,6 +1226,16 @@ namespace ChocolArm64.Instruction
|
||||||
EmitVectorWidenRnRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Mul));
|
EmitVectorWidenRnRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Mul));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Uqadd_S(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitScalarSaturatingOpZxZx(Context, () => Context.Emit(OpCodes.Add));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Uqadd_V(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitVectorSaturatingOpZxZx(Context, () => Context.Emit(OpCodes.Add));
|
||||||
|
}
|
||||||
|
|
||||||
public static void Uqxtn_S(AILEmitterCtx Context)
|
public static void Uqxtn_S(AILEmitterCtx Context)
|
||||||
{
|
{
|
||||||
EmitScalarSaturatingNarrowOpZxZx(Context, () => { });
|
EmitScalarSaturatingNarrowOpZxZx(Context, () => { });
|
||||||
|
|
|
@ -773,6 +773,115 @@ namespace ChocolArm64.Instruction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void EmitScalarSaturatingOpSxSx(AILEmitterCtx Context, Action Emit)
|
||||||
|
{
|
||||||
|
EmitSaturatingOp(Context, Emit, true, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EmitScalarSaturatingOpSxZx(AILEmitterCtx Context, Action Emit)
|
||||||
|
{
|
||||||
|
EmitSaturatingOp(Context, Emit, true, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EmitScalarSaturatingOpZxZx(AILEmitterCtx Context, Action Emit)
|
||||||
|
{
|
||||||
|
EmitSaturatingOp(Context, Emit, false, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EmitVectorSaturatingOpSxSx(AILEmitterCtx Context, Action Emit)
|
||||||
|
{
|
||||||
|
EmitSaturatingOp(Context, Emit, true, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EmitVectorSaturatingOpSxZx(AILEmitterCtx Context, Action Emit)
|
||||||
|
{
|
||||||
|
EmitSaturatingOp(Context, Emit, true, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EmitVectorSaturatingOpZxZx(AILEmitterCtx Context, Action Emit)
|
||||||
|
{
|
||||||
|
EmitSaturatingOp(Context, Emit, false, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EmitSaturatingOp(
|
||||||
|
AILEmitterCtx Context,
|
||||||
|
Action Emit,
|
||||||
|
bool SignedSrc,
|
||||||
|
bool SignedDst,
|
||||||
|
bool Scalar)
|
||||||
|
{
|
||||||
|
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
|
||||||
|
|
||||||
|
int Elems = !Scalar ? 8 >> Op.Size : 1;
|
||||||
|
|
||||||
|
int ESize = 8 << Op.Size;
|
||||||
|
|
||||||
|
long TMaxValue = SignedDst ? (1 << (ESize - 1)) - 1 : (1L << ESize) - 1L;
|
||||||
|
long TMinValue = SignedDst ? -((1 << (ESize - 1))) : 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, SignedSrc);
|
||||||
|
EmitVectorExtract(Context, Op.Rm, Index, Op.Size + 1, SignedSrc);
|
||||||
|
|
||||||
|
Emit();
|
||||||
|
|
||||||
|
Context.Emit(OpCodes.Dup);
|
||||||
|
|
||||||
|
Context.EmitLdc_I8(TMaxValue);
|
||||||
|
|
||||||
|
Context.Emit(SignedSrc ? OpCodes.Ble_S : OpCodes.Ble_Un_S, LblLe);
|
||||||
|
|
||||||
|
Context.Emit(OpCodes.Pop);
|
||||||
|
|
||||||
|
Context.EmitLdc_I8(TMaxValue);
|
||||||
|
Context.EmitLdc_I8(0x8000000L);
|
||||||
|
Context.EmitSttmp();
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
Context.EmitLdc_I8(TMinValue);
|
||||||
|
Context.EmitLdc_I8(0x8000000L);
|
||||||
|
Context.EmitSttmp();
|
||||||
|
|
||||||
|
Context.MarkLabel(LblGeEnd);
|
||||||
|
|
||||||
|
if (Scalar)
|
||||||
|
{
|
||||||
|
EmitVectorZeroLower(Context, Op.Rd);
|
||||||
|
}
|
||||||
|
|
||||||
|
EmitVectorInsertTmp(Context, Index, Op.Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Context.EmitLdvectmp();
|
||||||
|
Context.EmitStvec(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 EmitScalarSaturatingNarrowOpSxSx(AILEmitterCtx Context, Action Emit)
|
public static void EmitScalarSaturatingNarrowOpSxSx(AILEmitterCtx Context, Action Emit)
|
||||||
{
|
{
|
||||||
EmitSaturatingNarrowOp(Context, Emit, true, true, true);
|
EmitSaturatingNarrowOp(Context, Emit, true, true, true);
|
||||||
|
|
Loading…
Reference in a new issue