static List<CStatement> Bclr_C(uint pc, uint instruction) { Instruction i = new Instruction(instruction); List<CStatement> stats = new List<CStatement>(); if ((i.BO() & 4) == 0) { CStatement ctrSub = new CStatement(CStatement.Kinds.Subtraction, "CTR", 1); CStatement ctrAss = new CStatement(CStatement.Kinds.Assignment, "CTR", ctrSub); stats.Add(ctrAss); } CStatement final = ConditionCheck(i); CStatement branch = new CStatement(); if (i.LK()) { branch.Kind = CStatement.Kinds.Assignment; branch.Op1 = new CStatement.COperand("r3"); CStatement realBranch = new CStatement(CStatement.Kinds.Call); realBranch.CallFuncName = "lr"; realBranch.BranchDestinationRegister = "lr"; branch.Op2 = new CStatement.COperand(realBranch); } else branch.Kind = CStatement.Kinds.Return; if (final == null) final = branch; else { final.InnerBlock = new List<CStatement>(); final.InnerBlock.Add(branch); } stats.Add(final); return stats; }
static List<CStatement> Bc_C(uint pc, uint instruction) { Instruction i = new Instruction(instruction); List<CStatement> stats = new List<CStatement>(); if ((i.BO() & 4) == 0) { CStatement ctrSub = new CStatement(CStatement.Kinds.Subtraction, "CTR", 1); CStatement ctrAss = new CStatement(CStatement.Kinds.Assignment, "CTR", ctrSub); stats.Add(ctrAss); } CStatement final = ConditionCheck(i); uint destination = (uint)(int)(short)(i.BD() << 2); if ((instruction & 2) != 2) destination += pc; Function f = decompiler.Functions.Find(delegate(Function fn) { return fn.Address == destination; }); String destName; if (f != null) destName = f.Name; else destName = "L" + destination.ToString("X8"); CStatement branch = new CStatement(); if (i.LK()) { if (f != null && decompiler.IgnoredCalls.Contains(f)) return new List<CStatement>(); if (f != null && f.Returns.Name == "void" && f.Returns.Kind == CType.TypeKind.ValueType) { branch.Kind = CStatement.Kinds.Call; branch.CallFuncName = destName; branch.CalledFunction = f; } else { branch.Kind = CStatement.Kinds.Assignment; branch.Op1 = new CStatement.COperand("r3"); CStatement realBranch = new CStatement(CStatement.Kinds.Call); realBranch.CallFuncName = destName; realBranch.CalledFunction = f; branch.Op2 = new CStatement.COperand(realBranch); } } else { if (f != null && decompiler.CallIsRet.Contains(f)) branch.Kind = CStatement.Kinds.Return; else { branch.Kind = CStatement.Kinds.Goto; branch.BranchDestination = destName; branch.BranchDestinationAddr = destination; } } if (final == null) final = branch; else { final.InnerBlock = new List<CStatement>(); final.InnerBlock.Add(branch); } stats.Add(final); return stats; }
private static CStatement ConditionCheck(Instruction i) { CStatement CtrCondition = null; CStatement CrCondition = null; if ((i.BO() & 4) == 0) { CtrCondition = new CStatement(); } if ((i.BO() & 0x10) == 0) { CrCondition = new CStatement(); CrCondition.Kind = CStatement.Kinds.Comparison; uint cr = i.BI() / 4; uint fld = i.BI() % 4; CrCondition.Op1 = new CStatement.COperand("cr" + cr); CrCondition.Op2 = new CStatement.COperand(0); bool bo = ((i.BO() >> 3) & 1) == 1; switch (fld) { case 0: if (bo) CrCondition.ConditionSign = CStatement.Conditions.LessThan; else CrCondition.ConditionSign = CStatement.Conditions.GreaterEqualThan; break; case 1: if (bo) CrCondition.ConditionSign = CStatement.Conditions.GreaterThan; else CrCondition.ConditionSign = CStatement.Conditions.LessEqualThan; break; case 2: if (bo) CrCondition.ConditionSign = CStatement.Conditions.Equal; else CrCondition.ConditionSign = CStatement.Conditions.NotEqual; break; case 3: if (bo) CrCondition.ConditionSign = CStatement.Conditions.Overflow; else CrCondition.ConditionSign = CStatement.Conditions.NotOverflow; break; } } CStatement final = null; if (CrCondition != null) { if (CtrCondition != null) { CStatement composite = new CStatement(CStatement.Kinds.CompositeCondition, CrCondition, CtrCondition); composite.ConditionSign = CStatement.Conditions.And; final = new CStatement(); final.Kind = CStatement.Kinds.Conditional; final.Condition = composite; } else { final = new CStatement(); final.Kind = CStatement.Kinds.Conditional; final.Condition = CrCondition; } } else if (CtrCondition != null) { final = new CStatement(); final.Kind = CStatement.Kinds.Conditional; final.Condition = CtrCondition; } return final; }