public static void Sli_V(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)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 == ARegisterSize.SIMD64) { EmitVectorZeroUpper(Context, Op.Rd); } }
private static void EmitVectorImmBinaryOp(AILEmitterCtx Context, Action Emit, long Imm, bool Signed) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; int Bytes = Context.CurrOp.GetBitsCount() >> 3; for (int Index = 0; Index < (Bytes >> Op.Size); Index++) { Context.EmitLdvec(Op.Rd); Context.EmitLdc_I4(Index); Context.EmitLdc_I4(Op.Size); EmitVectorExtract(Context, Op.Rn, Index, Op.Size, Signed); Context.EmitLdc_I8(Imm); Emit(); ASoftFallback.EmitCall(Context, nameof(ASoftFallback.InsertVec)); Context.EmitStvec(Op.Rd); } if (Op.RegisterSize == ARegisterSize.SIMD64) { EmitVectorZeroUpper(Context, Op.Rd); } }
public static void Shl_V(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; if (AOptimizations.UseSse2 && Op.Size > 0) { Type[] TypesSll = new Type[] { VectorUIntTypesPerSizeLog2[Op.Size], typeof(byte) }; EmitLdvecWithUnsignedCast(Context, Op.Rn, Op.Size); Context.EmitLdc_I4(GetImmShl(Op)); Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), TypesSll)); EmitStvecWithUnsignedCast(Context, Op.Rd, Op.Size); if (Op.RegisterSize == ARegisterSize.SIMD64) { EmitVectorZeroUpper(Context, Op.Rd); } } else { EmitVectorUnaryOpZx(Context, () => { Context.EmitLdc_I4(GetImmShl(Op)); Context.Emit(OpCodes.Shl); }); } }
public static void Sshr_V(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; if (AOptimizations.UseSse2 && Op.Size > 0 && Op.Size < 3) { Type[] TypesSra = new Type[] { VectorIntTypesPerSizeLog2[Op.Size], typeof(byte) }; EmitLdvecWithSignedCast(Context, Op.Rn, Op.Size); Context.EmitLdc_I4(GetImmShr(Op)); Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), TypesSra)); EmitStvecWithSignedCast(Context, Op.Rd, Op.Size); if (Op.RegisterSize == ARegisterSize.SIMD64) { EmitVectorZeroUpper(Context, Op.Rd); } } else { EmitShrImmOp(Context, ShrImmFlags.VectorSx); } }
public static void Usra_V(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; if (AOptimizations.UseSse2 && Op.Size > 0) { Type[] TypesSrl = new Type[] { VectorUIntTypesPerSizeLog2[Op.Size], typeof(byte) }; Type[] TypesAdd = new Type[] { VectorUIntTypesPerSizeLog2[Op.Size], VectorUIntTypesPerSizeLog2[Op.Size] }; EmitLdvecWithUnsignedCast(Context, Op.Rd, Op.Size); EmitLdvecWithUnsignedCast(Context, Op.Rn, Op.Size); Context.EmitLdc_I4(GetImmShr(Op)); Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), TypesSrl)); Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), TypesAdd)); EmitStvecWithUnsignedCast(Context, Op.Rd, Op.Size); if (Op.RegisterSize == ARegisterSize.SIMD64) { EmitVectorZeroUpper(Context, Op.Rd); } } else { EmitVectorShrImmOpZx(Context, ShrImmFlags.Accumulate); } }
private static void EmitVectorShr(AILEmitterCtx Context, ShrFlags Flags) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; int Shift = (8 << (Op.Size + 1)) - Op.Imm; if (Flags.HasFlag(ShrFlags.Accumulate)) { Action Emit = () => { Context.EmitLdc_I4(Shift); Context.Emit(OpCodes.Shr_Un); Context.Emit(OpCodes.Add); }; EmitVectorOp(Context, Emit, OperFlags.RdRn, Signed: false); } else { EmitVectorUnaryZx(Context, () => { Context.EmitLdc_I4(Shift); Context.Emit(OpCodes.Shr_Un); }); } }
public static void Ushll_V(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; int Shift = Op.Imm - (8 << Op.Size); EmitVectorShImmWidenBinaryZx(Context, () => Context.Emit(OpCodes.Shl), Shift); }
public static void Sshr_V(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; int Shift = (8 << (Op.Size + 1)) - Op.Imm; EmitVectorShImmBinarySx(Context, () => Context.Emit(OpCodes.Shr), Shift); }
private static void EmitShrImmOp(AILEmitterCtx Context, ShrImmFlags Flags) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)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) */ { EmitShrImm_64(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 == ARegisterSize.SIMD64) || Scalar) { EmitVectorZeroUpper(Context, Op.Rd); } }
public static void Srshr_V(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; int Shift = GetImmShr(Op); long RoundConst = 1L << (Shift - 1); EmitVectorRoundShImmBinarySx(Context, () => Context.Emit(OpCodes.Shr), Shift, RoundConst); }
public static void Shl_S(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; Context.EmitLdvecsi(Op.Rn); Context.EmitLdc_I4(Op.Imm - (8 << Op.Size)); Context.Emit(OpCodes.Shl); Context.EmitStvecsi(Op.Rd); }
public static void Sshr_S(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; Context.EmitLdvecsi(Op.Rn); Context.EmitLdc_I4((8 << (Op.Size + 1)) - Op.Imm); Context.Emit(OpCodes.Shr); Context.EmitStvecsi(Op.Rd); }
public static void Shl_V(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; EmitVectorUnaryOpZx(Context, () => { Context.EmitLdc_I4(GetImmShl(Op)); Context.Emit(OpCodes.Shl); }); }
public static void Ushr_S(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; EmitScalarUnaryOpZx(Context, () => { Context.EmitLdc_I4(GetImmShr(Op)); Context.Emit(OpCodes.Shr_Un); }); }
public static void Sshr_S(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; EmitVectorExtractSx(Context, Op.Rn, 0, Op.Size); Context.EmitLdc_I4(GetImmShr(Op)); Context.Emit(OpCodes.Shr); EmitScalarSet(Context, Op.Rd, Op.Size); }
public static void Ssra_V(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; Action Emit = () => { Context.Emit(OpCodes.Shr); Context.Emit(OpCodes.Add); }; EmitVectorShImmTernarySx(Context, Emit, GetImmShr(Op)); }
public static void Ushll_V(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; Context.EmitLdvec(Op.Rn); Context.EmitLdc_I4(Op.Imm - (8 << Op.Size)); Context.EmitLdc_I4(Op.Size); ASoftFallback.EmitCall(Context, nameof(ASoftFallback.Ushll), nameof(ASoftFallback.Ushll2)); Context.EmitStvec(Op.Rd); }
public static void Ssra_V(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; int Shift = (8 << (Op.Size + 1)) - Op.Imm; Action Emit = () => { Context.Emit(OpCodes.Shr); Context.Emit(OpCodes.Add); }; EmitVectorShImmTernarySx(Context, Emit, Shift); }
public static void Usra_V(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; Action Emit = () => { Context.EmitLdc_I4(GetImmShr(Op)); Context.Emit(OpCodes.Shr_Un); Context.Emit(OpCodes.Add); }; EmitVectorOp(Context, Emit, OperFlags.RdRn, Signed: false); }
public static void Fcvtzu_V_Fix(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; Context.EmitLdvec(Op.Rn); Context.EmitLdc_I4((8 << (Op.Size + 1)) - Op.Imm); Context.EmitLdc_I4(Op.Size - 2); ASoftFallback.EmitCall(Context, nameof(ASoftFallback.Fcvtzu_V_64), nameof(ASoftFallback.Fcvtzu_V_128)); Context.EmitStvec(Op.Rd); }
public static void Ushr_V(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; Context.EmitLdvec(Op.Rn); Context.EmitLdc_I4((8 << (Op.Size + 1)) - Op.Imm); Context.EmitLdc_I4(Op.Size); ASoftFallback.EmitCall(Context, nameof(ASoftFallback.Ushr64), nameof(ASoftFallback.Ushr128)); Context.EmitStvec(Op.Rd); }
public static void Srsra_V(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; if (AOptimizations.UseSse2 && Op.Size > 0 && Op.Size < 3) { Type[] TypesShs = new Type[] { VectorIntTypesPerSizeLog2[Op.Size], typeof(byte) }; Type[] TypesAdd = new Type[] { VectorIntTypesPerSizeLog2[Op.Size], VectorIntTypesPerSizeLog2[Op.Size] }; int Shift = GetImmShr(Op); int ESize = 8 << Op.Size; EmitLdvecWithSignedCast(Context, Op.Rd, Op.Size); EmitLdvecWithSignedCast(Context, Op.Rn, Op.Size); Context.Emit(OpCodes.Dup); Context.EmitStvectmp(); Context.EmitLdc_I4(ESize - Shift); Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), TypesShs)); Context.EmitLdc_I4(ESize - 1); Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), TypesShs)); Context.EmitLdvectmp(); Context.EmitLdc_I4(Shift); Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), TypesShs)); Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), TypesAdd)); Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), TypesAdd)); EmitStvecWithSignedCast(Context, Op.Rd, Op.Size); if (Op.RegisterSize == ARegisterSize.SIMD64) { EmitVectorZeroUpper(Context, Op.Rd); } } else { EmitVectorShrImmOpSx(Context, ShrImmFlags.Round | ShrImmFlags.Accumulate); } }
private static void EmitVectorShrImmNarrowOpZx(AILEmitterCtx Context, bool Round) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; int Shift = GetImmShr(Op); long RoundConst = 1L << (Shift - 1); int Elems = 8 >> Op.Size; int Part = Op.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0; if (Part != 0) { Context.EmitLdvec(Op.Rd); Context.EmitStvectmp(); } for (int Index = 0; Index < Elems; Index++) { EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size + 1); if (Round) { Context.EmitLdc_I8(RoundConst); Context.Emit(OpCodes.Add); } Context.EmitLdc_I4(Shift); Context.Emit(OpCodes.Shr_Un); EmitVectorInsertTmp(Context, Part + Index, Op.Size); } Context.EmitLdvectmp(); Context.EmitStvec(Op.Rd); if (Part == 0) { EmitVectorZeroUpper(Context, Op.Rd); } }
public static void Sqrshrn_V(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; int Shift = GetImmShr(Op); long RoundConst = 1L << (Shift - 1); Action Emit = () => { Context.EmitLdc_I8(RoundConst); Context.Emit(OpCodes.Add); Context.EmitLdc_I4(Shift); Context.Emit(OpCodes.Shr); }; EmitVectorSaturatingNarrowOpSxSx(Context, Emit); }
private static void EmitVectorShImmBinaryOp(AILEmitterCtx Context, Action Emit, int Imm, bool Signed) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; int Bytes = Context.CurrOp.GetBitsCount() >> 3; for (int Index = 0; Index < (Bytes >> Op.Size); Index++) { EmitVectorExtract(Context, Op.Rn, Index, Op.Size, Signed); Context.EmitLdc_I4(Imm); Emit(); EmitVectorInsert(Context, Op.Rd, Index, Op.Size); } if (Op.RegisterSize == ARegisterSize.SIMD64) { EmitVectorZeroUpper(Context, Op.Rd); } }
private static void EmitVectorShImmWidenBinaryOp(AILEmitterCtx Context, Action Emit, int Imm, bool Signed) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; int Elems = 8 >> Op.Size; int Part = Op.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0; for (int Index = 0; Index < Elems; Index++) { EmitVectorExtract(Context, Op.Rn, Part + Index, Op.Size, Signed); Context.EmitLdc_I4(Imm); Emit(); EmitVectorInsertTmp(Context, Index, Op.Size + 1); } Context.EmitLdvectmp(); Context.EmitStvec(Op.Rd); }
private static void EmitVectorShImmNarrowBinaryOp(AILEmitterCtx Context, Action Emit, int Imm, bool Signed) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; int Elems = 8 >> Op.Size; int Part = Op.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0; for (int Index = 0; Index < Elems; Index++) { EmitVectorExtract(Context, Op.Rn, Index, Op.Size + 1, Signed); Context.EmitLdc_I4(Imm); Emit(); EmitVectorInsert(Context, Op.Rd, Part + Index, Op.Size); } if (Part == 0) { EmitVectorZeroUpper(Context, Op.Rd); } }
private static void EmitShrImmSaturatingNarrowOp(AILEmitterCtx Context, ShrImmSaturatingNarrowFlags Flags) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; bool Scalar = (Flags & ShrImmSaturatingNarrowFlags.Scalar) != 0; bool SignedSrc = (Flags & ShrImmSaturatingNarrowFlags.SignedSrc) != 0; bool SignedDst = (Flags & ShrImmSaturatingNarrowFlags.SignedDst) != 0; bool Round = (Flags & ShrImmSaturatingNarrowFlags.Round) != 0; int Shift = GetImmShr(Op); long RoundConst = 1L << (Shift - 1); int Elems = !Scalar ? 8 >> Op.Size : 1; int Part = !Scalar && (Op.RegisterSize == ARegisterSize.SIMD128) ? Elems : 0; if (Scalar) { EmitVectorZeroLowerTmp(Context); } if (Part != 0) { Context.EmitLdvec(Op.Rd); Context.EmitStvectmp(); } for (int Index = 0; Index < Elems; Index++) { EmitVectorExtract(Context, Op.Rn, Index, Op.Size + 1, SignedSrc); if (Op.Size <= 1 || !Round) { if (Round) { Context.EmitLdc_I8(RoundConst); Context.Emit(OpCodes.Add); } Context.EmitLdc_I4(Shift); Context.Emit(SignedSrc ? OpCodes.Shr : OpCodes.Shr_Un); } else /* if (Op.Size == 2 && Round) */ { EmitShrImm_64(Context, SignedSrc, RoundConst, Shift); // Shift <= 32 } EmitSatQ(Context, Op.Size, SignedSrc, SignedDst); EmitVectorInsertTmp(Context, Part + Index, Op.Size); } Context.EmitLdvectmp(); Context.EmitStvec(Op.Rd); if (Part == 0) { EmitVectorZeroUpper(Context, Op.Rd); } }
public static void Ushll_V(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; EmitVectorShImmWidenBinaryZx(Context, () => Context.Emit(OpCodes.Shl), GetImmShl(Op)); }
public static int GetImmShr(AOpCodeSimdShImm Op) { return((8 << (Op.Size + 1)) - Op.Imm); }