public static void EmitScalarSaturatingBinaryOpSx(ILEmitterCtx context, SaturatingFlags flags) { EmitSaturatingBinaryOp(context, () => { }, SaturatingFlags.ScalarSx | flags); }
public static void EmitSaturatingBinaryOp(ILEmitterCtx context, Action emit, SaturatingFlags flags) { OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp; bool scalar = (flags & SaturatingFlags.Scalar) != 0; bool signed = (flags & SaturatingFlags.Signed) != 0; bool add = (flags & SaturatingFlags.Add) != 0; bool sub = (flags & SaturatingFlags.Sub) != 0; bool accumulate = (flags & SaturatingFlags.Accumulate) != 0; int bytes = op.GetBitsCount() >> 3; int elems = !scalar ? bytes >> op.Size : 1; if (add || sub) { for (int index = 0; index < elems; index++) { EmitVectorExtract(context, op.Rn, index, op.Size, signed); EmitVectorExtract(context, ((OpCodeSimdReg64)op).Rm, index, op.Size, signed); if (op.Size <= 2) { context.Emit(add ? OpCodes.Add : OpCodes.Sub); EmitSatQ(context, op.Size, true, signed); } else /* if (op.Size == 3) */ { if (add) { EmitBinarySatQAdd(context, signed); } else /* if (sub) */ { EmitBinarySatQSub(context, signed); } } if (scalar) { EmitVectorZeroAll(context, op.Rd); } EmitVectorInsert(context, op.Rd, index, op.Size); } } else if (accumulate) { for (int index = 0; index < elems; index++) { EmitVectorExtract(context, op.Rn, index, op.Size, !signed); EmitVectorExtract(context, op.Rd, index, op.Size, signed); if (op.Size <= 2) { context.Emit(OpCodes.Add); EmitSatQ(context, op.Size, true, signed); } else /* if (op.Size == 3) */ { EmitBinarySatQAccumulate(context, signed); } if (scalar) { EmitVectorZeroAll(context, op.Rd); } EmitVectorInsert(context, op.Rd, index, op.Size); } } else { for (int index = 0; index < elems; index++) { EmitVectorExtract(context, op.Rn, index, op.Size, signed); EmitVectorExtract(context, ((OpCodeSimdReg64)op).Rm, index, op.Size, signed); emit(); EmitSatQ(context, op.Size, true, signed); if (scalar) { EmitVectorZeroAll(context, op.Rd); } EmitVectorInsert(context, op.Rd, index, op.Size); } } if (op.RegisterSize == RegisterSize.Simd64) { EmitVectorZeroUpper(context, op.Rd); } }
public static void EmitSaturatingUnaryOpSx(ILEmitterCtx context, Action emit, SaturatingFlags flags) { OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp; bool scalar = (flags & SaturatingFlags.Scalar) != 0; int bytes = op.GetBitsCount() >> 3; int elems = !scalar ? bytes >> op.Size : 1; for (int index = 0; index < elems; index++) { EmitVectorExtractSx(context, op.Rn, index, op.Size); emit(); if (op.Size <= 2) { EmitSatQ(context, op.Size, true, true); } else /* if (op.Size == 3) */ { EmitUnarySignedSatQAbsOrNeg(context); } if (scalar) { EmitVectorZeroAll(context, op.Rd); } EmitVectorInsert(context, op.Rd, index, op.Size); } if (op.RegisterSize == RegisterSize.Simd64) { EmitVectorZeroUpper(context, op.Rd); } }
public static void EmitVectorSaturatingBinaryOpZx(ILEmitterCtx context, SaturatingFlags flags) { EmitSaturatingBinaryOp(context, () => { }, SaturatingFlags.VectorZx | flags); }
public static void EmitScalarSaturatingBinaryOpZx(AILEmitterCtx Context, SaturatingFlags Flags) { EmitSaturatingBinaryOp(Context, () => { }, SaturatingFlags.ScalarZx | Flags); }
public static void EmitSaturatingUnaryOpSx(AILEmitterCtx Context, Action Emit, SaturatingFlags Flags) { AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp; bool Scalar = (Flags & SaturatingFlags.Scalar) != 0; int Bytes = Op.GetBitsCount() >> 3; int Elems = !Scalar ? Bytes >> Op.Size : 1; if (Scalar) { EmitVectorZeroLowerTmp(Context); } for (int Index = 0; Index < Elems; Index++) { EmitVectorExtractSx(Context, Op.Rn, Index, Op.Size); Emit(); if (Op.Size <= 2) { EmitSatQ(Context, Op.Size, true, true); } else /* if (Op.Size == 3) */ { EmitUnarySignedSatQAbsOrNeg(Context); } EmitVectorInsertTmp(Context, Index, Op.Size); } Context.EmitLdvectmp(); Context.EmitStvec(Op.Rd); if ((Op.RegisterSize == ARegisterSize.SIMD64) || Scalar) { EmitVectorZeroUpper(Context, Op.Rd); } }
public static void EmitSaturatingBinaryOp(AILEmitterCtx Context, Action Emit, SaturatingFlags Flags) { AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp; bool Scalar = (Flags & SaturatingFlags.Scalar) != 0; bool Signed = (Flags & SaturatingFlags.Signed) != 0; bool Add = (Flags & SaturatingFlags.Add) != 0; bool Sub = (Flags & SaturatingFlags.Sub) != 0; bool Accumulate = (Flags & SaturatingFlags.Accumulate) != 0; int Bytes = Op.GetBitsCount() >> 3; int Elems = !Scalar ? Bytes >> Op.Size : 1; if (Scalar) { EmitVectorZeroLowerTmp(Context); } if (Add || Sub) { for (int Index = 0; Index < Elems; Index++) { EmitVectorExtract(Context, Op.Rn, Index, Op.Size, Signed); EmitVectorExtract(Context, ((AOpCodeSimdReg)Op).Rm, Index, Op.Size, Signed); if (Op.Size <= 2) { Context.Emit(Add ? OpCodes.Add : OpCodes.Sub); EmitSatQ(Context, Op.Size, true, Signed); } else /* if (Op.Size == 3) */ { if (Add) { EmitBinarySatQAdd(Context, Signed); } else /* if (Sub) */ { EmitBinarySatQSub(Context, Signed); } } EmitVectorInsertTmp(Context, Index, Op.Size); } } else if (Accumulate) { for (int Index = 0; Index < Elems; Index++) { EmitVectorExtract(Context, Op.Rn, Index, Op.Size, !Signed); EmitVectorExtract(Context, Op.Rd, Index, Op.Size, Signed); if (Op.Size <= 2) { Context.Emit(OpCodes.Add); EmitSatQ(Context, Op.Size, true, Signed); } else /* if (Op.Size == 3) */ { EmitBinarySatQAccumulate(Context, Signed); } EmitVectorInsertTmp(Context, Index, Op.Size); } } else { for (int Index = 0; Index < Elems; Index++) { EmitVectorExtract(Context, Op.Rn, Index, Op.Size, Signed); EmitVectorExtract(Context, ((AOpCodeSimdReg)Op).Rm, Index, Op.Size, Signed); Emit(); EmitSatQ(Context, Op.Size, true, Signed); EmitVectorInsertTmp(Context, Index, Op.Size); } } Context.EmitLdvectmp(); Context.EmitStvec(Op.Rd); if ((Op.RegisterSize == ARegisterSize.SIMD64) || Scalar) { EmitVectorZeroUpper(Context, Op.Rd); } }
public static void EmitVectorSaturatingBinaryOpSx(AILEmitterCtx Context, SaturatingFlags Flags) { EmitSaturatingBinaryOp(Context, () => { }, SaturatingFlags.VectorSx | Flags); }