예제 #1
0
        public static void Bic_Vi(ArmEmitterContext context)
        {
            if (Optimizations.UseSse2)
            {
                OpCodeSimdImm op = (OpCodeSimdImm)context.CurrOp;

                int eSize = 8 << op.Size;

                Operand d   = GetVec(op.Rd);
                Operand imm = eSize switch {
                    16 => X86GetAllElements(context, (short)~op.Immediate),
                    32 => X86GetAllElements(context, (int)~op.Immediate),
                    _ => throw new InvalidOperationException($"Invalid element size {eSize}.")
                };

                Operand res = context.AddIntrinsic(Intrinsic.X86Pand, d, imm);

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

                context.Copy(GetVec(op.Rd), res);
            }
            else
            {
                EmitVectorImmBinaryOp(context, (op1, op2) =>
                {
                    return(context.BitwiseAnd(op1, context.BitwiseNot(op2)));
                });
            }
        }
예제 #2
0
        public static void Fmov_Vi(ArmEmitterContext context)
        {
            OpCodeSimdImm op = (OpCodeSimdImm)context.CurrOp;

            if (Optimizations.UseSse2)
            {
                if (op.RegisterSize == RegisterSize.Simd128)
                {
                    context.Copy(GetVec(op.Rd), X86GetAllElements(context, op.Immediate));
                }
                else
                {
                    context.Copy(GetVec(op.Rd), X86GetScalar(context, op.Immediate));
                }
            }
            else
            {
                Operand e = Const(op.Immediate);

                Operand res = context.VectorZero();

                int elems = op.RegisterSize == RegisterSize.Simd128 ? 2 : 1;

                for (int index = 0; index < elems; index++)
                {
                    res = EmitVectorInsert(context, res, e, index, 3);
                }

                context.Copy(GetVec(op.Rd), res);
            }
        }
예제 #3
0
        public static void Fmov_Vi(ArmEmitterContext context)
        {
            OpCodeSimdImm op = (OpCodeSimdImm)context.CurrOp;

            Operand e = Const(op.Immediate);

            Operand res = context.VectorZero();

            int elems = op.RegisterSize == RegisterSize.Simd128 ? 4 : 2;

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

            context.Copy(GetVec(op.Rd), res);
        }
예제 #4
0
        private static void EmitSse2MoviMvni(ArmEmitterContext context, bool not)
        {
            OpCodeSimdImm op = (OpCodeSimdImm)context.CurrOp;

            long imm = op.Immediate;

            switch (op.Size)
            {
            case 0: imm *= 0x01010101; break;

            case 1: imm *= 0x00010001; break;
            }

            if (not)
            {
                imm = ~imm;
            }

            Operand mask;

            if (op.Size < 3)
            {
                mask = X86GetAllElements(context, (int)imm);
            }
            else
            {
                mask = X86GetAllElements(context, imm);
            }

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

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