示例#1
0
        public override void Run(IRContext context)
        {
            var longRightShiftVar      = new IRRegisterVariable(IRPrimitive.U64, "mergeVar");
            var shiftAmountA           = new IRRegisterVariable(IRPrimitive.S32, "a");
            var shiftAmountB           = new IRRegisterVariable(IRPrimitive.S32, "b");
            var shiftAmountNew         = new IRRegisterVariable(IRPrimitive.U64, "c");
            var longRightShiftTemplate =
                longRightShiftVar.Cast(IRPrimitive.U32).ShiftRightLogical(shiftAmountA) |
                longRightShiftVar.ShiftRightLogical(32).Cast(IRPrimitive.U32).ShiftLeft(shiftAmountB);
            var longRightShiftSubst = longRightShiftVar.ShiftRightLogical(shiftAmountNew).Cast(IRPrimitive.U32);

            foreach (var basicBlock in context.Function.BasicBlocks)
            {
                foreach (var instruction in basicBlock.Instructions)
                {
                    instruction.Substitute(longRightShiftTemplate, longRightShiftSubst, mapping =>
                    {
                        var shiftA = mapping[shiftAmountA] as IRConstant <int>;
                        var shiftB = mapping[shiftAmountB] as IRConstant <int>;
                        if (shiftA is null || shiftB is null)
                        {
                            return(false);
                        }
                        if (shiftA.Value <= 0 || shiftA.Value >= 32)
                        {
                            return(false);
                        }
                        if (shiftB.Value != 32 - shiftA.Value)
                        {
                            return(false);
                        }
                        mapping[shiftAmountNew] = (ulong)shiftA.Value;
                        return(true);
                    });
        public void VarConstTest()
        {
            IRExpression expression   = 3;
            var          templateVarA = new IRRegisterVariable(IRPrimitive.S32, "a");
            var          template     = templateVarA;
            var          mapping      = new Dictionary <IRVariable, IRExpression>();

            Assert.IsTrue(expression.Unify(template, mapping));
            Assert.AreEqual(1, mapping.Count);
            Assert.AreEqual(mapping[templateVarA], expression);
        }
        public void MultiVarNeTest()
        {
            var exprVar      = new IRRegisterVariable(IRPrimitive.S32, "exprVar");
            var exprVar2     = new IRRegisterVariable(IRPrimitive.S32, "exprVar2");
            var expression   = exprVar + exprVar2;
            var templateVarA = new IRRegisterVariable(IRPrimitive.S32, "a");
            var template     = templateVarA + templateVarA;
            var mapping      = new Dictionary <IRVariable, IRExpression>();

            Assert.IsFalse(expression.Unify(template, mapping));
        }
        public void MultiVarNeTest2()
        {
            IRExpression irConst3     = 3;
            IRExpression irConst2     = 2;
            IRExpression expression   = irConst3 + irConst2;
            var          templateVarA = new IRRegisterVariable(IRPrimitive.S32, "a");
            var          template     = templateVarA + templateVarA;
            var          mapping      = new Dictionary <IRVariable, IRExpression>();

            Assert.IsFalse(expression.Unify(template, mapping));
        }
        public void MultiVarEqTest2()
        {
            IRExpression irConst3     = 3;
            IRExpression expression   = irConst3 + irConst3;
            var          templateVarA = new IRRegisterVariable(IRPrimitive.S32, "a");
            var          template     = templateVarA + templateVarA;
            var          mapping      = new Dictionary <IRVariable, IRExpression>();

            Assert.IsTrue(expression.Unify(template, mapping));
            Assert.AreEqual(1, mapping.Count);
            Assert.AreEqual(mapping[templateVarA], irConst3);
        }
        public void MultiVarEqTest()
        {
            var exprVar      = new IRRegisterVariable(IRPrimitive.S32, "exprVar");
            var expression   = exprVar + exprVar;
            var templateVarA = new IRRegisterVariable(IRPrimitive.S32, "a");
            var template     = templateVarA + templateVarA;
            var mapping      = new Dictionary <IRVariable, IRExpression>();

            Assert.IsTrue(expression.Unify(template, mapping));
            Assert.AreEqual(1, mapping.Count);
            Assert.AreEqual(mapping[templateVarA], exprVar);
        }
        public override void Run(IRContext context)
        {
            var s64ExprMergeVar      = new IRRegisterVariable(IRPrimitive.S64, "mergeVar");
            var s64ExprMergeTemplate =
                s64ExprMergeVar.Cast(IRPrimitive.U32).Cast(IRPrimitive.U64) |
                s64ExprMergeVar.ShiftRightLogical(32).Cast(IRPrimitive.U32).Cast(IRPrimitive.U64).ShiftLeft(32);
            var s64ExprMergeSubst = s64ExprMergeVar.Cast(IRPrimitive.U64);

            foreach (var basicBlock in context.Function.BasicBlocks)
            {
                foreach (var instruction in basicBlock.Instructions)
                {
                    instruction.Substitute(s64ExprMergeTemplate, s64ExprMergeSubst);
                }
            }
        }
示例#8
0
        public override void Run(IRContext context)
        {
            var fxMulVarA     = new IRRegisterVariable(IRPrimitive.S32, "a");
            var fxMulVarB     = new IRRegisterVariable(IRPrimitive.S32, "b");
            var fxMulTemplate =
                ((fxMulVarA.Cast(IRPrimitive.S64) * fxMulVarB.Cast(IRPrimitive.S64)).Cast(IRPrimitive.U64) +
                 new IRConversionExpression(IRPrimitive.U64, 0x800u))
                .ShiftRightLogical(12ul).Cast(IRPrimitive.U32);
            var fxMulSubst = new IRCallExpression(IRPrimitive.S32, "FX_Mul", fxMulVarA, fxMulVarB).Cast(IRPrimitive.U32);

            foreach (var basicBlock in context.Function.BasicBlocks)
            {
                foreach (var instruction in basicBlock.Instructions)
                {
                    instruction.Substitute(fxMulTemplate, fxMulSubst);
                }
            }
        }
        public override void Run(IRContext context)
        {
            var s32Var = new IRRegisterVariable(IRPrimitive.S32, "x");

            foreach (var basicBlock in context.Function.BasicBlocks)
            {
                foreach (var instruction in basicBlock.Instructions)
                {
                    instruction.Substitute(s32Var.Cast(IRPrimitive.U32).Cast(IRPrimitive.S32), s32Var);
                }
            }

            var u32Var = new IRRegisterVariable(IRPrimitive.U32, "x");

            foreach (var basicBlock in context.Function.BasicBlocks)
            {
                foreach (var instruction in basicBlock.Instructions)
                {
                    instruction.Substitute(u32Var.Cast(IRPrimitive.S32).Cast(IRPrimitive.U32), u32Var);
                }
            }
        }
        public override void Run(IRContext context)
        {
            var x = new IRRegisterVariable(IRPrimitive.U32, "x");
            foreach (var basicBlock in context.Function.BasicBlocks)
                foreach (var instruction in basicBlock.Instructions)
                    instruction.Substitute(x.ShiftLeft(16u).ShiftRightLogical(16u),
                        x.Cast(IRPrimitive.U16).Cast(IRPrimitive.U32));

            foreach (var basicBlock in context.Function.BasicBlocks)
                foreach (var instruction in basicBlock.Instructions)
                    instruction.Substitute(x.ShiftLeft(16u).ShiftRightArithmetic(16u),
                        x.Cast(IRPrimitive.S16).Cast(IRPrimitive.U32));

            foreach (var basicBlock in context.Function.BasicBlocks)
                foreach (var instruction in basicBlock.Instructions)
                    instruction.Substitute(x.ShiftLeft(24u).ShiftRightLogical(24u),
                        x.Cast(IRPrimitive.U8).Cast(IRPrimitive.U32));

            foreach (var basicBlock in context.Function.BasicBlocks)
                foreach (var instruction in basicBlock.Instructions)
                    instruction.Substitute(x.ShiftLeft(24u).ShiftRightArithmetic(24u),
                        x.Cast(IRPrimitive.S8).Cast(IRPrimitive.U32));
        }
示例#11
0
        public override void Run(IRContext context)
        {
            var x        = new IRRegisterVariable(IRPrimitive.U32, "x");
            var magicVal = new IRRegisterVariable(IRPrimitive.U32, "magicVal");
            var shiftVal = new IRRegisterVariable(IRPrimitive.S32, "shiftVal");
            var divisor  = new IRRegisterVariable(IRPrimitive.S32, "divisor");
            var subst    = (x.Cast(IRPrimitive.S32) / divisor).Cast(IRPrimitive.U32);

            //Signed, division by two
            foreach (var basicBlock in context.Function.BasicBlocks)
            {
                foreach (var instruction in basicBlock.Instructions)
                {
                    instruction.Substitute((x + x.ShiftRightLogical(31)).ShiftRightArithmetic(1),
                                           (x.Cast(IRPrimitive.S32) / 2).Cast(IRPrimitive.U32));
                }
            }

            //Signed, no shift, positive constant
            var template = (magicVal.Cast(IRPrimitive.S32).Cast(IRPrimitive.S64) *
                            x.Cast(IRPrimitive.S32).Cast(IRPrimitive.S64)).ShiftRightLogical(32)
                           .Cast(IRPrimitive.U32) +
                           x.ShiftRightLogical(31);

            foreach (var basicBlock in context.Function.BasicBlocks)
            {
                foreach (var instruction in basicBlock.Instructions)
                {
                    instruction.Substitute(template, subst, mapping =>
                    {
                        var magic = mapping[magicVal] as IRConstant <uint>;

                        if (magic is null)
                        {
                            return(false);
                        }

                        int magicSigned = (int)magic.Value;

                        float divisorVal = (float)(1ul << 32) / magicSigned;

                        if (divisorVal != (float)Math.Round(divisorVal))
                        {
                            return(false);
                        }

                        mapping[divisor] = (int)divisorVal;
                        return(true);
                    });
                }
            }

            //Signed, shift, positive constant
            template = x.ShiftRightLogical(31) +
                       (magicVal.Cast(IRPrimitive.S32).Cast(IRPrimitive.S64) *
                        x.Cast(IRPrimitive.S32).Cast(IRPrimitive.S64)).ShiftRightLogical(32)
                       .Cast(IRPrimitive.U32).ShiftRightArithmetic(shiftVal);
            foreach (var basicBlock in context.Function.BasicBlocks)
            {
                foreach (var instruction in basicBlock.Instructions)
                {
                    instruction.Substitute(template, subst, mapping =>
                    {
                        var magic = mapping[magicVal] as IRConstant <uint>;
                        var shift = mapping[shiftVal] as IRConstant <int>;

                        if (magic is null || shift is null)
                        {
                            return(false);
                        }

                        int magicSigned = (int)magic.Value;

                        float divisorVal = (float)(1ul << 32 << shift.Value) / magicSigned;

                        if (divisorVal != (float)Math.Round(divisorVal))
                        {
                            return(false);
                        }

                        mapping[divisor] = (int)divisorVal;
                        return(true);
                    });