Beispiel #1
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);
            }
        }
Beispiel #2
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);
            }
        }