public static void Optimize(ArrayList list) { for (int i = 1; i < list.Count; i++) { X86Code x0 = list[i] as X86Code; if (x0 == null || x0.ignore || x0.IsBrTarget) { continue; } ArrayList listx = new ArrayList(); listx.Add(x0); for (int j = 1;; j++) { X86Code xx = GetPrevious(list, i, j); if (xx == null) { break; } listx.Add(xx); } if (listx.Count < 2) { continue; } X86Code[] x = listx.ToArray(typeof(X86Code)) as X86Code[]; if (IsMovEtc(x[0].Mnemonic) && !IsXS(x[0].Operand1) && IsXX(x[0].Operand2) && x[0].Operand1 != x[0].Operand2) { for (int j = 1; j < x.Length; j++) { if (x[j].Mnemonic == "mov" && x[j].Operand1 == x[0].Operand2 && !IsXS(x[j].Operand2) && !(IsAddr(x[0].Operand1) && IsAddr(x[j].Operand2))) { if (x[0].Operand1 != x[j].Operand2 && (IsXX(x[0].Operand1) || IsXX(x[j].Operand2))) { x[j].Ignore(); x[0].Ignore(); X86Code xx = new X86Code(x[0].Mnemonic, x[0].Operand1, x[j].Operand2); xx.Notes = "[optimize] add"; list.Insert(i + 1, xx); } } else if (IsMovEtc(x[j].Mnemonic) && x[j].Operand1 != x[0].Operand2) { continue; } break; } if (x[0].ignore) { continue; } } switch (x[0].Mnemonic) { case "pop": { Hashtable t = new Hashtable(); for (int j = 1; j < x.Length; j++) { if (x[j].Mnemonic == "push") { if (!t.Contains(x[j].Operand1)) { if (x[j].Operand1 == x[0].Operand1) { x[j].Ignore(); x[0].Ignore(); } else if (IsXX(x[j].Operand1) || IsXX(x[0].Operand1)) { x[j].Ignore(); x[0].Ignore(); X86Code xx = new X86Code("mov", x[0].Operand1, x[j].Operand1); xx.Notes = "[optimize] add"; list.Insert(i + 1, xx); } } else if (!t.Contains(x[0].Operand1)) { if (IsXX(x[j].Operand1) || IsXX(x[0].Operand1)) { x[j].Ignore(); x[0].Ignore(); X86Code xx = new X86Code("mov", x[0].Operand1, x[j].Operand1); xx.Notes = "[optimize] add"; i = list.IndexOf(x[j]); list.Insert(i + 1, xx); } } } else if (IsMovEtc(x[j].Mnemonic)) { t[x[j].Operand1] = true; continue; } break; } break; } case "cmp": if (IsXX(x[0].Operand1) && IsDigit(x[0].Operand2)) { for (int j = 1; j < x.Length; j++) { if (x[j].Mnemonic == "mov" && x[j].Operand1 == x[0].Operand1) { x[j].Ignore(); x[0].Ignore(); X86Code xx = new X86Code("cmp", x[j].Operand2, x[0].Operand2); xx.Notes = "[optimize] add"; list.Insert(i + 1, xx); } else if (IsMovEtc(x[j].Mnemonic) && x[j].Operand1 != x[0].Operand1) { continue; } break; } } break; case "je": case "jne": case "jz": case "jnz": if (x[1].Mnemonic == "cmp" && IsXX(x[1].Operand1) && !IsDigit(x[1].Operand2)) { for (int j = 2; j < x.Length; j++) { if (x[j].Mnemonic == "mov" && x[j].Operand1 == x[1].Operand1) { x[j].Ignore(); x[1].Ignore(); X86Code xx = new X86Code("cmp", x[1].Operand2, x[j].Operand2); xx.Notes = "[optimize] add"; i = list.IndexOf(x[1]); list.Insert(i + 1, xx); } else if (IsMovEtc(x[j].Mnemonic) && x[j].Operand1 != x[1].Operand1) { continue; } break; } } break; case "mov": if (x.Length > 2 && IsAddEtc(x[1].Mnemonic) && x[2].Mnemonic == "mov" && x[0].Operand2 == x[1].Operand1 && x[1].Operand1 == x[2].Operand1) { if (x[1].Mnemonic == "inc" || x[1].Mnemonic == "dec") { x[2].Ignore(); x[1].Ignore(); x[0].Ignore(); X86Code xx = new X86Code(x[1].Mnemonic, x[0].Operand1); xx.Notes = "[optimize] add"; list.Insert(i + 1, xx); } else if (x[0].Operand1 == x[1].Operand2 && !IsAddr(x[2].Operand2)) { x[2].Ignore(); x[1].Ignore(); x[0].Ignore(); X86Code xx = new X86Code(x[1].Mnemonic, x[0].Operand1, x[2].Operand2); xx.Notes = "[optimize] add"; list.Insert(i + 1, xx); } else if (x[0].Operand1 == x[2].Operand2 && !IsAddr(x[1].Operand2)) { x[2].Ignore(); x[1].Ignore(); x[0].Ignore(); X86Code xx = new X86Code(x[1].Mnemonic, x[0].Operand1, x[1].Operand2); xx.Notes = "[optimize] add"; list.Insert(i + 1, xx); } } break; case "add": if (x[0].Operand2 == "1") { x[0].Ignore(); X86Code xx = new X86Code("inc", x[0].Operand1); xx.Notes = "[Optimize] add"; list.Insert(i + 1, xx); } break; case "sub": if (x[0].Operand2 == "1") { x[0].Ignore(); X86Code xx = new X86Code("dec", x[0].Operand1); xx.Notes = "[Optimize] add"; list.Insert(i + 1, xx); } break; } } StringCollection jmp = new StringCollection(); for (int i = 0; i < list.Count; i++) { X86Code x = list[i] as X86Code; if (x == null || x.ignore) { continue; } if (x.Mnemonic == "mov" && X86Code.IsXX(x.Operand1) && x.Operand2 == "0") { x.Ignore(); X86Code xx = new X86Code("xor", x.Operand1, x.Operand1); xx.Notes = "[optimize] add"; list.Insert(i + 1, xx); } else if (x.Mnemonic == "mov" && x.Operand1 == x.Operand2) { x.Ignore(); } else if (x.Mnemonic.StartsWith("j")) { jmp.Add(x.Operand1); } } for (int i = 0; i < list.Count; i++) { X86Code x = list[i] as X86Code; if (x == null) { continue; } if (x.IsBrTarget && !jmp.Contains(x.Label)) { x.IsBrTarget = false; } } }
public void Optimize(ArrayList list, MethodData md) { X86Code.Optimize(list); bool bx = true; Hashtable locals = new Hashtable(); int max = 0; string target = null; for (int i = 0; i < list.Count; i++) { X86Code x = list[i] as X86Code; if (x == null || x.ignore) { continue; } if (x.Mnemonic == "int" || x.Operand1 == "bx") { bx = false; } int p1a = x.Operand1.IndexOf("[ss:bp-"), p1b = x.Operand1.LastIndexOf(']'); if (0 <= p1a && p1a < p1b) { string var = x.Operand1.Substring(p1a + 1, p1b - p1a - 1); int v = !locals.Contains(var) ? 1 : ((int)locals[var]) + 1; locals[var] = v; if (max < v) { max = v; target = var; } } int p2a = x.Operand2.IndexOf("[ss:bp-"), p2b = x.Operand2.LastIndexOf(']'); if (0 <= p2a && p2a < p2b) { string var = x.Operand2.Substring(p2a + 1, p2b - p2a - 1); int v = !locals.Contains(var) ? 1 : ((int)locals[var]) + 1; locals[var] = v; if (max < v) { max = v; target = var; } } } if (bx && target != null) { for (int i = 0; i < list.Count; i++) { X86Code x = list[i] as X86Code; if (x == null || x.ignore) { continue; } string op1 = x.Operand1, op2 = x.Operand2; int p1 = op1.IndexOf(target), p2 = op2.IndexOf(target); if (p1 >= 0) { op1 = "bx"; } if (p2 >= 0) { op2 = "bx"; } if (p1 < 0 && p2 < 0) { continue; } x.Ignore(); X86Code xx = new X86Code(x.Mnemonic, op1, op2); xx.Notes = "[optimize] add"; list.Insert(i + 1, xx); } if (md.LocalVars != null && md.LocalVars.Count == 1 && target.StartsWith("ss:bp-")) { for (int i = 0; i < list.Count; i++) { X86Code x = list[i] as X86Code; if (x == null || x.ignore) { continue; } if (x.Mnemonic == "sub" && x.Operand1 == "sp") { x.Ignore(); break; } } for (int i = list.Count - 1; i >= 0; i--) { X86Code x = list[i] as X86Code; if (x == null || x.ignore) { continue; } if (x.Mnemonic == "mov" && x.Operand1 == "sp") { x.Ignore(); break; } } } } X86Code.Optimize(list); if (md.LocalVars != null || md.ParamCount > 0 || !bx) { X86Code xb1 = new X86Code("push", "bx"), xb2 = new X86Code("pop", "bx"); xb1.Notes = xb2.Notes = "[optimize] add"; list.Insert(0, xb1); for (int i = 0; i < list.Count; i++) { X86Code x = list[i] as X86Code; if (x == null || x.ignore) { continue; } if (x.Mnemonic == "ret") { list.Insert(i, xb2); i++; } } } }