Пример #1
0
 public static void EmitScalarSaturatingBinaryOpSx(ILEmitterCtx context, SaturatingFlags flags)
 {
     EmitSaturatingBinaryOp(context, () => { }, SaturatingFlags.ScalarSx | flags);
 }
Пример #2
0
        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);
            }
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
 public static void EmitVectorSaturatingBinaryOpZx(ILEmitterCtx context, SaturatingFlags flags)
 {
     EmitSaturatingBinaryOp(context, () => { }, SaturatingFlags.VectorZx | flags);
 }
Пример #5
0
 public static void EmitScalarSaturatingBinaryOpZx(AILEmitterCtx Context, SaturatingFlags Flags)
 {
     EmitSaturatingBinaryOp(Context, () => { }, SaturatingFlags.ScalarZx | Flags);
 }
Пример #6
0
        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);
            }
        }
Пример #7
0
        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);
            }
        }
Пример #8
0
 public static void EmitVectorSaturatingBinaryOpSx(AILEmitterCtx Context, SaturatingFlags Flags)
 {
     EmitSaturatingBinaryOp(Context, () => { }, SaturatingFlags.VectorSx | Flags);
 }