Update InstEmitSimdShift.cs
This commit is contained in:
parent
94669fffcb
commit
0a2456628f
1 changed files with 208 additions and 65 deletions
|
@ -110,6 +110,34 @@ namespace ChocolArm64.Instructions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Sqrshl_V(ILEmitterCtx context)
|
||||||
|
{
|
||||||
|
OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
|
||||||
|
|
||||||
|
int bytes = op.GetBitsCount() >> 3;
|
||||||
|
int elems = bytes >> op.Size;
|
||||||
|
|
||||||
|
for (int index = 0; index < elems; index++)
|
||||||
|
{
|
||||||
|
EmitVectorExtractSx(context, op.Rn, index, op.Size);
|
||||||
|
EmitVectorExtractSx(context, op.Rm, index, op.Size);
|
||||||
|
|
||||||
|
context.Emit(OpCodes.Ldc_I4_1);
|
||||||
|
context.EmitLdc_I4(op.Size);
|
||||||
|
|
||||||
|
context.EmitLdarg(TranslatedSub.StateArgIdx);
|
||||||
|
|
||||||
|
SoftFallback.EmitCall(context, nameof(SoftFallback.SignedShlRegSatQ));
|
||||||
|
|
||||||
|
EmitVectorInsert(context, op.Rd, index, op.Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op.RegisterSize == RegisterSize.Simd64)
|
||||||
|
{
|
||||||
|
EmitVectorZeroUpper(context, op.Rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void Sqrshrn_S(ILEmitterCtx context)
|
public static void Sqrshrn_S(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarSxSx);
|
EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarSxSx);
|
||||||
|
@ -130,6 +158,34 @@ namespace ChocolArm64.Instructions
|
||||||
EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorSxZx);
|
EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorSxZx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Sqshl_V(ILEmitterCtx context)
|
||||||
|
{
|
||||||
|
OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
|
||||||
|
|
||||||
|
int bytes = op.GetBitsCount() >> 3;
|
||||||
|
int elems = bytes >> op.Size;
|
||||||
|
|
||||||
|
for (int index = 0; index < elems; index++)
|
||||||
|
{
|
||||||
|
EmitVectorExtractSx(context, op.Rn, index, op.Size);
|
||||||
|
EmitVectorExtractSx(context, op.Rm, index, op.Size);
|
||||||
|
|
||||||
|
context.Emit(OpCodes.Ldc_I4_0);
|
||||||
|
context.EmitLdc_I4(op.Size);
|
||||||
|
|
||||||
|
context.EmitLdarg(TranslatedSub.StateArgIdx);
|
||||||
|
|
||||||
|
SoftFallback.EmitCall(context, nameof(SoftFallback.SignedShlRegSatQ));
|
||||||
|
|
||||||
|
EmitVectorInsert(context, op.Rd, index, op.Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op.RegisterSize == RegisterSize.Simd64)
|
||||||
|
{
|
||||||
|
EmitVectorZeroUpper(context, op.Rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void Sqshrn_S(ILEmitterCtx context)
|
public static void Sqshrn_S(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarSxSx);
|
EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarSxSx);
|
||||||
|
@ -150,6 +206,32 @@ namespace ChocolArm64.Instructions
|
||||||
EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorSxZx);
|
EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorSxZx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Srshl_V(ILEmitterCtx context)
|
||||||
|
{
|
||||||
|
OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
|
||||||
|
|
||||||
|
int bytes = op.GetBitsCount() >> 3;
|
||||||
|
int elems = bytes >> op.Size;
|
||||||
|
|
||||||
|
for (int index = 0; index < elems; index++)
|
||||||
|
{
|
||||||
|
EmitVectorExtractSx(context, op.Rn, index, op.Size);
|
||||||
|
EmitVectorExtractSx(context, op.Rm, index, op.Size);
|
||||||
|
|
||||||
|
context.Emit(OpCodes.Ldc_I4_1);
|
||||||
|
context.EmitLdc_I4(op.Size);
|
||||||
|
|
||||||
|
SoftFallback.EmitCall(context, nameof(SoftFallback.SignedShlReg));
|
||||||
|
|
||||||
|
EmitVectorInsert(context, op.Rd, index, op.Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op.RegisterSize == RegisterSize.Simd64)
|
||||||
|
{
|
||||||
|
EmitVectorZeroUpper(context, op.Rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void Srshr_S(ILEmitterCtx context)
|
public static void Srshr_S(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
EmitScalarShrImmOpSx(context, ShrImmFlags.Round);
|
EmitScalarShrImmOpSx(context, ShrImmFlags.Round);
|
||||||
|
@ -252,7 +334,28 @@ namespace ChocolArm64.Instructions
|
||||||
|
|
||||||
public static void Sshl_V(ILEmitterCtx context)
|
public static void Sshl_V(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
EmitVectorShl(context, signed: true);
|
OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
|
||||||
|
|
||||||
|
int bytes = op.GetBitsCount() >> 3;
|
||||||
|
int elems = bytes >> op.Size;
|
||||||
|
|
||||||
|
for (int index = 0; index < elems; index++)
|
||||||
|
{
|
||||||
|
EmitVectorExtractSx(context, op.Rn, index, op.Size);
|
||||||
|
EmitVectorExtractSx(context, op.Rm, index, op.Size);
|
||||||
|
|
||||||
|
context.Emit(OpCodes.Ldc_I4_0);
|
||||||
|
context.EmitLdc_I4(op.Size);
|
||||||
|
|
||||||
|
SoftFallback.EmitCall(context, nameof(SoftFallback.SignedShlReg));
|
||||||
|
|
||||||
|
EmitVectorInsert(context, op.Rd, index, op.Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op.RegisterSize == RegisterSize.Simd64)
|
||||||
|
{
|
||||||
|
EmitVectorZeroUpper(context, op.Rd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Sshll_V(ILEmitterCtx context)
|
public static void Sshll_V(ILEmitterCtx context)
|
||||||
|
@ -330,6 +433,34 @@ namespace ChocolArm64.Instructions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Uqrshl_V(ILEmitterCtx context)
|
||||||
|
{
|
||||||
|
OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
|
||||||
|
|
||||||
|
int bytes = op.GetBitsCount() >> 3;
|
||||||
|
int elems = bytes >> op.Size;
|
||||||
|
|
||||||
|
for (int index = 0; index < elems; index++)
|
||||||
|
{
|
||||||
|
EmitVectorExtractZx(context, op.Rn, index, op.Size);
|
||||||
|
EmitVectorExtractZx(context, op.Rm, index, op.Size);
|
||||||
|
|
||||||
|
context.Emit(OpCodes.Ldc_I4_1);
|
||||||
|
context.EmitLdc_I4(op.Size);
|
||||||
|
|
||||||
|
context.EmitLdarg(TranslatedSub.StateArgIdx);
|
||||||
|
|
||||||
|
SoftFallback.EmitCall(context, nameof(SoftFallback.UnsignedShlRegSatQ));
|
||||||
|
|
||||||
|
EmitVectorInsert(context, op.Rd, index, op.Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op.RegisterSize == RegisterSize.Simd64)
|
||||||
|
{
|
||||||
|
EmitVectorZeroUpper(context, op.Rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void Uqrshrn_S(ILEmitterCtx context)
|
public static void Uqrshrn_S(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarZxZx);
|
EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarZxZx);
|
||||||
|
@ -340,6 +471,34 @@ namespace ChocolArm64.Instructions
|
||||||
EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorZxZx);
|
EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorZxZx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Uqshl_V(ILEmitterCtx context)
|
||||||
|
{
|
||||||
|
OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
|
||||||
|
|
||||||
|
int bytes = op.GetBitsCount() >> 3;
|
||||||
|
int elems = bytes >> op.Size;
|
||||||
|
|
||||||
|
for (int index = 0; index < elems; index++)
|
||||||
|
{
|
||||||
|
EmitVectorExtractZx(context, op.Rn, index, op.Size);
|
||||||
|
EmitVectorExtractZx(context, op.Rm, index, op.Size);
|
||||||
|
|
||||||
|
context.Emit(OpCodes.Ldc_I4_0);
|
||||||
|
context.EmitLdc_I4(op.Size);
|
||||||
|
|
||||||
|
context.EmitLdarg(TranslatedSub.StateArgIdx);
|
||||||
|
|
||||||
|
SoftFallback.EmitCall(context, nameof(SoftFallback.UnsignedShlRegSatQ));
|
||||||
|
|
||||||
|
EmitVectorInsert(context, op.Rd, index, op.Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op.RegisterSize == RegisterSize.Simd64)
|
||||||
|
{
|
||||||
|
EmitVectorZeroUpper(context, op.Rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void Uqshrn_S(ILEmitterCtx context)
|
public static void Uqshrn_S(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarZxZx);
|
EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarZxZx);
|
||||||
|
@ -350,6 +509,32 @@ namespace ChocolArm64.Instructions
|
||||||
EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorZxZx);
|
EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorZxZx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Urshl_V(ILEmitterCtx context)
|
||||||
|
{
|
||||||
|
OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
|
||||||
|
|
||||||
|
int bytes = op.GetBitsCount() >> 3;
|
||||||
|
int elems = bytes >> op.Size;
|
||||||
|
|
||||||
|
for (int index = 0; index < elems; index++)
|
||||||
|
{
|
||||||
|
EmitVectorExtractZx(context, op.Rn, index, op.Size);
|
||||||
|
EmitVectorExtractZx(context, op.Rm, index, op.Size);
|
||||||
|
|
||||||
|
context.Emit(OpCodes.Ldc_I4_1);
|
||||||
|
context.EmitLdc_I4(op.Size);
|
||||||
|
|
||||||
|
SoftFallback.EmitCall(context, nameof(SoftFallback.UnsignedShlReg));
|
||||||
|
|
||||||
|
EmitVectorInsert(context, op.Rd, index, op.Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op.RegisterSize == RegisterSize.Simd64)
|
||||||
|
{
|
||||||
|
EmitVectorZeroUpper(context, op.Rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void Urshr_S(ILEmitterCtx context)
|
public static void Urshr_S(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
EmitScalarShrImmOpZx(context, ShrImmFlags.Round);
|
EmitScalarShrImmOpZx(context, ShrImmFlags.Round);
|
||||||
|
@ -450,7 +635,28 @@ namespace ChocolArm64.Instructions
|
||||||
|
|
||||||
public static void Ushl_V(ILEmitterCtx context)
|
public static void Ushl_V(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
EmitVectorShl(context, signed: false);
|
OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
|
||||||
|
|
||||||
|
int bytes = op.GetBitsCount() >> 3;
|
||||||
|
int elems = bytes >> op.Size;
|
||||||
|
|
||||||
|
for (int index = 0; index < elems; index++)
|
||||||
|
{
|
||||||
|
EmitVectorExtractZx(context, op.Rn, index, op.Size);
|
||||||
|
EmitVectorExtractZx(context, op.Rm, index, op.Size);
|
||||||
|
|
||||||
|
context.Emit(OpCodes.Ldc_I4_0);
|
||||||
|
context.EmitLdc_I4(op.Size);
|
||||||
|
|
||||||
|
SoftFallback.EmitCall(context, nameof(SoftFallback.UnsignedShlReg));
|
||||||
|
|
||||||
|
EmitVectorInsert(context, op.Rd, index, op.Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op.RegisterSize == RegisterSize.Simd64)
|
||||||
|
{
|
||||||
|
EmitVectorZeroUpper(context, op.Rd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Ushll_V(ILEmitterCtx context)
|
public static void Ushll_V(ILEmitterCtx context)
|
||||||
|
@ -526,69 +732,6 @@ namespace ChocolArm64.Instructions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void EmitVectorShl(ILEmitterCtx context, bool signed)
|
|
||||||
{
|
|
||||||
//This instruction shifts the value on vector A by the number of bits
|
|
||||||
//specified on the signed, lower 8 bits of vector B. If the shift value
|
|
||||||
//is greater or equal to the data size of each lane, then the result is zero.
|
|
||||||
//Additionally, negative shifts produces right shifts by the negated shift value.
|
|
||||||
OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
|
|
||||||
|
|
||||||
int maxShift = 8 << op.Size;
|
|
||||||
|
|
||||||
Action emit = () =>
|
|
||||||
{
|
|
||||||
ILLabel lblShl = new ILLabel();
|
|
||||||
ILLabel lblZero = new ILLabel();
|
|
||||||
ILLabel lblEnd = new ILLabel();
|
|
||||||
|
|
||||||
void EmitShift(OpCode ilOp)
|
|
||||||
{
|
|
||||||
context.Emit(OpCodes.Dup);
|
|
||||||
|
|
||||||
context.EmitLdc_I4(maxShift);
|
|
||||||
|
|
||||||
context.Emit(OpCodes.Bge_S, lblZero);
|
|
||||||
context.Emit(ilOp);
|
|
||||||
context.Emit(OpCodes.Br_S, lblEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
context.Emit(OpCodes.Conv_I1);
|
|
||||||
context.Emit(OpCodes.Dup);
|
|
||||||
|
|
||||||
context.EmitLdc_I4(0);
|
|
||||||
|
|
||||||
context.Emit(OpCodes.Bge_S, lblShl);
|
|
||||||
context.Emit(OpCodes.Neg);
|
|
||||||
|
|
||||||
EmitShift(signed
|
|
||||||
? OpCodes.Shr
|
|
||||||
: OpCodes.Shr_Un);
|
|
||||||
|
|
||||||
context.MarkLabel(lblShl);
|
|
||||||
|
|
||||||
EmitShift(OpCodes.Shl);
|
|
||||||
|
|
||||||
context.MarkLabel(lblZero);
|
|
||||||
|
|
||||||
context.Emit(OpCodes.Pop);
|
|
||||||
context.Emit(OpCodes.Pop);
|
|
||||||
|
|
||||||
context.EmitLdc_I8(0);
|
|
||||||
|
|
||||||
context.MarkLabel(lblEnd);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (signed)
|
|
||||||
{
|
|
||||||
EmitVectorBinaryOpSx(context, emit);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
EmitVectorBinaryOpZx(context, emit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
private enum ShrImmFlags
|
private enum ShrImmFlags
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue