public static void Sli_V(ILEmitterCtx context) { OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp; int bytes = op.GetBitsCount() >> 3; int elems = bytes >> op.Size; int shift = GetImmShl(op); ulong mask = shift != 0 ? ulong.MaxValue >> (64 - shift) : 0; for (int index = 0; index < elems; index++) { EmitVectorExtractZx(context, op.Rn, index, op.Size); context.EmitLdc_I4(shift); context.Emit(OpCodes.Shl); EmitVectorExtractZx(context, op.Rd, index, op.Size); context.EmitLdc_I8((long)mask); context.Emit(OpCodes.And); context.Emit(OpCodes.Or); EmitVectorInsert(context, op.Rd, index, op.Size); } if (op.RegisterSize == RegisterSize.Simd64) { EmitVectorZeroUpper(context, op.Rd); } }
private static void EmitShrImmOp(ILEmitterCtx context, ShrImmFlags flags) { OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp; bool scalar = (flags & ShrImmFlags.Scalar) != 0; bool signed = (flags & ShrImmFlags.Signed) != 0; bool round = (flags & ShrImmFlags.Round) != 0; bool accumulate = (flags & ShrImmFlags.Accumulate) != 0; int shift = GetImmShr(op); long roundConst = 1L << (shift - 1); int bytes = op.GetBitsCount() >> 3; int elems = !scalar ? bytes >> op.Size : 1; for (int index = 0; index < elems; index++) { EmitVectorExtract(context, op.Rn, index, op.Size, signed); if (op.Size <= 2) { if (round) { context.EmitLdc_I8(roundConst); context.Emit(OpCodes.Add); } context.EmitLdc_I4(shift); context.Emit(signed ? OpCodes.Shr : OpCodes.Shr_Un); } else /* if (op.Size == 3) */ { EmitShrImm64(context, signed, round ? roundConst : 0L, shift); } if (accumulate) { EmitVectorExtract(context, op.Rd, index, op.Size, signed); context.Emit(OpCodes.Add); } EmitVectorInsertTmp(context, index, op.Size); } context.EmitLdvectmp(); context.EmitStvec(op.Rd); if ((op.RegisterSize == RegisterSize.Simd64) || scalar) { EmitVectorZeroUpper(context, op.Rd); } }