public bool WriteAsm(StreamWriter sw, MethodData md) { bool ok = true; string name = md.FullName; sw.WriteLine("; {0}", name); sw.WriteLine("{0}:", Util.MangleFunction(md)); ArrayList list = new ArrayList(); if (md.LocalVars != null || md.ParamCount > 0) { list.Add(new X86Code("push", "bp")); list.Add(new X86Code("mov", "bp", "sp")); if (md.LocalVars != null) { list.Add(new X86Code("sub", "sp", (md.LocalVars.Count * 2).ToString())); } } foreach (object obj in ConvertNative(md)) { X86Codes codes = obj as X86Codes; if (codes == null) { ILCode il = obj as ILCode; codes = ConvertIL(md, il); if (codes == null) { ok = false; Console.WriteLine("ERROR PE_{0:X8}: {1} in {2}", il.Address, il.OpCode, md.FullName); continue; } } codes.Output(list); } switch (this.optimize) { case 1: X86Code.Optimize(list); break; case 2: this.Optimize(list, md); break; } foreach (object obj in list) { X86Code x = obj as X86Code; x.Write(sw); } return(ok); }
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++; } } } }