From 0a2456628febc1245c37541debff3e42189eb00f Mon Sep 17 00:00:00 2001 From: LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com> Date: Tue, 27 Nov 2018 02:51:58 +0100 Subject: [PATCH] Update InstEmitSimdShift.cs --- ChocolArm64/Instructions/InstEmitSimdShift.cs | 273 +++++++++++++----- 1 file changed, 208 insertions(+), 65 deletions(-) diff --git a/ChocolArm64/Instructions/InstEmitSimdShift.cs b/ChocolArm64/Instructions/InstEmitSimdShift.cs index b183e8aa66..5b6061671a 100644 --- a/ChocolArm64/Instructions/InstEmitSimdShift.cs +++ b/ChocolArm64/Instructions/InstEmitSimdShift.cs @@ -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) { EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarSxSx); @@ -130,6 +158,34 @@ namespace ChocolArm64.Instructions 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) { EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarSxSx); @@ -150,6 +206,32 @@ namespace ChocolArm64.Instructions 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) { EmitScalarShrImmOpSx(context, ShrImmFlags.Round); @@ -252,7 +334,28 @@ namespace ChocolArm64.Instructions 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) @@ -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) { EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarZxZx); @@ -340,6 +471,34 @@ namespace ChocolArm64.Instructions 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) { EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarZxZx); @@ -350,6 +509,32 @@ namespace ChocolArm64.Instructions 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) { EmitScalarShrImmOpZx(context, ShrImmFlags.Round); @@ -450,7 +635,28 @@ namespace ChocolArm64.Instructions 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) @@ -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] private enum ShrImmFlags {