示例#1
0
        public static void Umov_S(ArmEmitterContext context)
        {
            OpCodeSimdIns op = (OpCodeSimdIns)context.CurrOp;

            Operand ne = EmitVectorExtractZx(context, op.Rn, op.DstIndex, op.Size);

            SetIntOrZR(context, op.Rd, ne);
        }
示例#2
0
        public static void Dup_S(ArmEmitterContext context)
        {
            OpCodeSimdIns op = (OpCodeSimdIns)context.CurrOp;

            Operand ne = EmitVectorExtractZx(context, op.Rn, op.DstIndex, op.Size);

            context.Copy(GetVec(op.Rd), EmitVectorInsert(context, context.VectorZero(), ne, 0, op.Size));
        }
示例#3
0
        public static void Ins_V(ArmEmitterContext context)
        {
            OpCodeSimdIns op = (OpCodeSimdIns)context.CurrOp;

            Operand d  = GetVec(op.Rd);
            Operand ne = EmitVectorExtractZx(context, op.Rn, op.SrcIndex, op.Size);

            context.Copy(d, EmitVectorInsert(context, d, ne, op.DstIndex, op.Size));
        }
示例#4
0
        public static void Ins_Gp(ArmEmitterContext context)
        {
            OpCodeSimdIns op = (OpCodeSimdIns)context.CurrOp;

            Operand d = GetVec(op.Rd);
            Operand n = GetIntOrZR(context, op.Rn);

            context.Copy(d, EmitVectorInsert(context, d, n, op.DstIndex, op.Size));
        }
示例#5
0
        public static void Smov_S(ArmEmitterContext context)
        {
            OpCodeSimdIns op = (OpCodeSimdIns)context.CurrOp;

            Operand ne = EmitVectorExtractSx(context, op.Rn, op.DstIndex, op.Size);

            if (op.RegisterSize == RegisterSize.Simd64)
            {
                ne = context.ZeroExtend32(OperandType.I64, ne);
            }

            SetIntOrZR(context, op.Rd, ne);
        }
示例#6
0
        public static void Dup_Gp(ArmEmitterContext context)
        {
            OpCodeSimdIns op = (OpCodeSimdIns)context.CurrOp;

            Operand n = GetIntOrZR(context, op.Rn);

            if (Optimizations.UseSse2)
            {
                switch (op.Size)
                {
                case 0: n = context.ZeroExtend8(n.Type, n); n = context.Multiply(n, Const(n.Type, 0x01010101)); break;

                case 1: n = context.ZeroExtend16(n.Type, n); n = context.Multiply(n, Const(n.Type, 0x00010001)); break;

                case 2: n = context.ZeroExtend32(n.Type, n); break;
                }

                Operand res = context.VectorInsert(context.VectorZero(), n, 0);

                if (op.Size < 3)
                {
                    if (op.RegisterSize == RegisterSize.Simd64)
                    {
                        res = context.AddIntrinsic(Intrinsic.X86Shufps, res, res, Const(0xf0));
                    }
                    else
                    {
                        res = context.AddIntrinsic(Intrinsic.X86Shufps, res, res, Const(0));
                    }
                }
                else
                {
                    res = context.AddIntrinsic(Intrinsic.X86Movlhps, res, res);
                }

                context.Copy(GetVec(op.Rd), res);
            }
            else
            {
                Operand res = context.VectorZero();

                int elems = op.GetBytesCount() >> op.Size;

                for (int index = 0; index < elems; index++)
                {
                    res = EmitVectorInsert(context, res, n, index, op.Size);
                }

                context.Copy(GetVec(op.Rd), res);
            }
        }
示例#7
0
        public static void Dup_V(ArmEmitterContext context)
        {
            OpCodeSimdIns op = (OpCodeSimdIns)context.CurrOp;

            if (Optimizations.UseSse2)
            {
                Operand res = GetVec(op.Rn);

                if (op.Size == 0)
                {
                    if (op.DstIndex != 0)
                    {
                        res = context.AddIntrinsic(Intrinsic.X86Psrldq, res, Const(op.DstIndex));
                    }

                    res = context.AddIntrinsic(Intrinsic.X86Punpcklbw, res, res);
                    res = context.AddIntrinsic(Intrinsic.X86Punpcklwd, res, res);
                    res = context.AddIntrinsic(Intrinsic.X86Shufps, res, res, Const(0));
                }
                else if (op.Size == 1)
                {
                    if (op.DstIndex != 0)
                    {
                        res = context.AddIntrinsic(Intrinsic.X86Psrldq, res, Const(op.DstIndex * 2));
                    }

                    res = context.AddIntrinsic(Intrinsic.X86Punpcklwd, res, res);
                    res = context.AddIntrinsic(Intrinsic.X86Shufps, res, res, Const(0));
                }
                else if (op.Size == 2)
                {
                    int mask = op.DstIndex * 0b01010101;

                    res = context.AddIntrinsic(Intrinsic.X86Shufps, res, res, Const(mask));
                }
                else if (op.DstIndex == 0 && op.RegisterSize != RegisterSize.Simd64)
                {
                    res = context.AddIntrinsic(Intrinsic.X86Movlhps, res, res);
                }
                else if (op.DstIndex == 1)
                {
                    res = context.AddIntrinsic(Intrinsic.X86Movhlps, res, res);
                }

                if (op.RegisterSize == RegisterSize.Simd64)
                {
                    res = context.VectorZeroUpper64(res);
                }

                context.Copy(GetVec(op.Rd), res);
            }
            else
            {
                Operand ne = EmitVectorExtractZx(context, op.Rn, op.DstIndex, op.Size);

                Operand res = context.VectorZero();

                int elems = op.GetBytesCount() >> op.Size;

                for (int index = 0; index < elems; index++)
                {
                    res = EmitVectorInsert(context, res, ne, index, op.Size);
                }

                context.Copy(GetVec(op.Rd), res);
            }
        }