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); } } }
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)); }
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); });