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

                Operand n = GetVec(op.Rn);
                Operand m = GetVec(op.Rm);

                Operand res = context.AddIntrinsic(Intrinsic.X86Pandn, m, n);

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

                context.Copy(GetVec(op.Rd), res);
            }
            else
            {
                EmitVectorBinaryOpZx(context, (op1, op2) =>
                {
                    return(context.BitwiseAnd(op1, context.BitwiseNot(op2)));
                });
            }
        }
예제 #2
0
        public static Operand EmitAsrC(ArmEmitterContext context, Operand m, bool setCarry, Operand shift, Operand shiftIsZero)
        {
            Debug.Assert(m.Type == OperandType.I32 && shift.Type == OperandType.I32 && shiftIsZero.Type == OperandType.I32);

            Operand l32Result;
            Operand ge32Result;

            Operand less32 = context.ICompareLess(shift, Const(32));

            ge32Result = context.ShiftRightSI(m, Const(31));

            if (setCarry)
            {
                EmitIfHelper(context, context.BitwiseOr(less32, shiftIsZero), () =>
                {
                    SetCarryMLsb(context, ge32Result);
                }, false);
            }

            l32Result = context.ShiftRightSI(m, shift);
            if (setCarry)
            {
                EmitIfHelper(context, context.BitwiseAnd(less32, context.BitwiseNot(shiftIsZero)), () =>
                {
                    Operand cOut = context.ShiftRightUI(m, context.Subtract(shift, Const(1)));

                    cOut = context.BitwiseAnd(cOut, Const(1));

                    SetFlag(context, PState.CFlag, cOut);
                });
            }

            return(context.ConditionalSelect(less32, l32Result, ge32Result));
        }
예제 #3
0
 public static void Bic_Vi(ArmEmitterContext context)
 {
     EmitVectorImmBinaryOp(context, (op1, op2) =>
     {
         return(context.BitwiseAnd(op1, context.BitwiseNot(op2)));
     });
 }
예제 #4
0
파일: InstEmitCsel.cs 프로젝트: derparb/h
        private static void EmitCsel(ArmEmitterContext context, CselOperation cselOp)
        {
            OpCodeCsel op = (OpCodeCsel)context.CurrOp;

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

            if (cselOp == CselOperation.Increment)
            {
                m = context.Add(m, Const(m.Type, 1));
            }
            else if (cselOp == CselOperation.Invert)
            {
                m = context.BitwiseNot(m);
            }
            else if (cselOp == CselOperation.Negate)
            {
                m = context.Negate(m);
            }

            Operand condTrue = GetCondTrue(context, op.Cond);

            Operand d = context.ConditionalSelect(condTrue, n, m);

            SetIntOrZR(context, op.Rd, d);
        }
예제 #5
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)));
                });
            }
        }
예제 #6
0
        private static void EmitBifBit(ArmEmitterContext context, bool notRm)
        {
            OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;

            if (Optimizations.UseSse2)
            {
                EmitVectorTernaryOpSimd32(context, (d, n, m) =>
                {
                    Operand res = context.AddIntrinsic(Intrinsic.X86Pxor, n, d);
                    res         = context.AddIntrinsic((notRm) ? Intrinsic.X86Pandn : Intrinsic.X86Pand, m, res);
                    return(context.AddIntrinsic(Intrinsic.X86Pxor, d, res));
                });
            }
            else
            {
                EmitVectorTernaryOpZx32(context, (d, n, m) =>
                {
                    if (notRm)
                    {
                        m = context.BitwiseNot(m);
                    }
                    return(context.BitwiseExclusiveOr(
                               context.BitwiseAnd(m,
                                                  context.BitwiseExclusiveOr(d, n)), d));
                });
            }
        }
예제 #7
0
        private static void EmitBifBit(ArmEmitterContext context, bool notRm)
        {
            OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;

            if (Optimizations.UseSse2)
            {
                Operand d = GetVec(op.Rd);
                Operand n = GetVec(op.Rn);
                Operand m = GetVec(op.Rm);

                Operand res = context.AddIntrinsic(Intrinsic.X86Pxor, n, d);

                if (notRm)
                {
                    res = context.AddIntrinsic(Intrinsic.X86Pandn, m, res);
                }
                else
                {
                    res = context.AddIntrinsic(Intrinsic.X86Pand, m, res);
                }

                res = context.AddIntrinsic(Intrinsic.X86Pxor, d, res);

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

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

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

                for (int index = 0; index < elems; index++)
                {
                    Operand d = EmitVectorExtractZx(context, op.Rd, index, 3);
                    Operand n = EmitVectorExtractZx(context, op.Rn, index, 3);
                    Operand m = EmitVectorExtractZx(context, op.Rm, index, 3);

                    if (notRm)
                    {
                        m = context.BitwiseNot(m);
                    }

                    Operand e = context.BitwiseExclusiveOr(d, n);

                    e = context.BitwiseAnd(e, m);
                    e = context.BitwiseExclusiveOr(e, d);

                    res = EmitVectorInsert(context, res, e, index, 3);
                }

                context.Copy(GetVec(op.Rd), res);
            }
        }
예제 #8
0
        public static void Orn(ArmEmitterContext context)
        {
            Operand n = GetAluN(context);
            Operand m = GetAluM(context);

            Operand d = context.BitwiseOr(n, context.BitwiseNot(m));

            SetAluD(context, d);
        }
예제 #9
0
        public static void EmitAddsVCheck(ArmEmitterContext context, Operand n, Operand m, Operand d)
        {
            // V = (Rd ^ Rn) & ~(Rn ^ Rm) < 0
            Operand vOut = context.BitwiseExclusiveOr(d, n);

            vOut = context.BitwiseAnd(vOut, context.BitwiseNot(context.BitwiseExclusiveOr(n, m)));

            vOut = context.ICompareLess(vOut, Const(vOut.Type, 0));

            SetFlag(context, PState.VFlag, vOut);
        }
예제 #10
0
 public static void Mvni_V(ArmEmitterContext context)
 {
     if (Optimizations.UseSse2)
     {
         EmitSse2MoviMvni(context, not: true);
     }
     else
     {
         EmitVectorImmUnaryOp(context, (op1) => context.BitwiseNot(op1));
     }
 }
예제 #11
0
        public static void Mvn(ArmEmitterContext context)
        {
            IOpCode32Alu op = (IOpCode32Alu)context.CurrOp;
            Operand      m  = GetAluM(context);

            Operand res = context.BitwiseNot(m);

            if (op.SetFlags)
            {
                EmitNZFlagsCheck(context, res);
            }

            EmitAluStore(context, res);
        }
예제 #12
0
        public static void Vbic_II(ArmEmitterContext context)
        {
            OpCode32SimdImm op = (OpCode32SimdImm)context.CurrOp;

            long immediate = op.Immediate;

            // Replicate fields to fill the 64-bits, if size is < 64-bits.
            switch (op.Size)
            {
            case 0: immediate *= 0x0101010101010101L; break;

            case 1: immediate *= 0x0001000100010001L; break;

            case 2: immediate *= 0x0000000100000001L; break;
            }

            Operand imm = Const(immediate);
            Operand res = GetVecA32(op.Qd);

            if (op.Q)
            {
                for (int elem = 0; elem < 2; elem++)
                {
                    Operand de = EmitVectorExtractZx(context, op.Qd, elem, 3);

                    res = EmitVectorInsert(context, res, context.BitwiseAnd(de, context.BitwiseNot(imm)), elem, 3);
                }
            }
            else
            {
                Operand de = EmitVectorExtractZx(context, op.Qd, op.Vd & 1, 3);

                res = EmitVectorInsert(context, res, context.BitwiseAnd(de, context.BitwiseNot(imm)), op.Vd & 1, 3);
            }

            context.Copy(GetVecA32(op.Qd), res);
        }
예제 #13
0
        private static void EmitBic(ArmEmitterContext context, bool setFlags)
        {
            Operand n = GetAluN(context);
            Operand m = GetAluM(context);

            Operand d = context.BitwiseAnd(n, context.BitwiseNot(m));

            if (setFlags)
            {
                EmitNZFlagsCheck(context, d);
                EmitCVFlagsClear(context);
            }

            SetAluD(context, d, setFlags);
        }
예제 #14
0
        private static void EmitBifBit(ArmEmitterContext context, bool notRm)
        {
            OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;

            EmitVectorTernaryOpZx32(context, (d, n, m) =>
            {
                if (notRm)
                {
                    m = context.BitwiseNot(m);
                }
                return(context.BitwiseExclusiveOr(
                           context.BitwiseAnd(m,
                                              context.BitwiseExclusiveOr(d, n)), d));
            });
        }
예제 #15
0
 public static void Vmvn_I(ArmEmitterContext context)
 {
     if (Optimizations.UseSse2)
     {
         EmitVectorUnaryOpSimd32(context, (op1) =>
         {
             Operand mask = X86GetAllElements(context, -1L);
             return(context.AddIntrinsic(Intrinsic.X86Pandn, op1, mask));
         });
     }
     else
     {
         EmitVectorUnaryOpZx32(context, (op1) => context.BitwiseNot(op1));
     }
 }
예제 #16
0
        public static void Orn(ArmEmitterContext context)
        {
            IOpCode32Alu op = (IOpCode32Alu)context.CurrOp;

            Operand n = GetAluN(context);
            Operand m = GetAluM(context);

            Operand res = context.BitwiseOr(n, context.BitwiseNot(m));

            if (ShouldSetFlags(context))
            {
                EmitNZFlagsCheck(context, res);
            }

            EmitAluStore(context, res);
        }
예제 #17
0
        public static void Vorn_I(ArmEmitterContext context)
        {
            if (Optimizations.UseSse2)
            {
                Operand mask = context.VectorOne();

                EmitVectorBinaryOpSimd32(context, (n, m) =>
                {
                    m = context.AddIntrinsic(Intrinsic.X86Pandn, m, mask);
                    return(context.AddIntrinsic(Intrinsic.X86Por, n, m));
                });
            }
            else
            {
                EmitVectorBinaryOpZx32(context, (op1, op2) => context.BitwiseOr(op1, context.BitwiseNot(op2)));
            }
        }
예제 #18
0
        public static void Not_V(ArmEmitterContext context)
        {
            if (Optimizations.UseSse2)
            {
                OpCodeSimd op = (OpCodeSimd)context.CurrOp;

                Operand n = GetVec(op.Rn);

                Operand mask = X86GetAllElements(context, -1L);

                Operand res = context.AddIntrinsic(Intrinsic.X86Pandn, n, mask);

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

                context.Copy(GetVec(op.Rd), res);
            }
            else
            {
                EmitVectorUnaryOpZx(context, (op1) => context.BitwiseNot(op1));
            }
        }
예제 #19
0
 public static void Vmvn_II(ArmEmitterContext context)
 {
     EmitVectorImmUnaryOp32(context, (op1) => context.BitwiseNot(op1));
 }
예제 #20
0
 public static void Vbic_I(ArmEmitterContext context)
 {
     if (Optimizations.UseSse2)
     {
         EmitVectorBinaryOpSimd32(context, (n, m) => context.AddIntrinsic(Intrinsic.X86Pandn, m, n));
     }
     else
     {
         EmitVectorBinaryOpZx32(context, (op1, op2) => context.BitwiseAnd(op1, context.BitwiseNot(op2)));
     }
 }