package vaporize; import cs132.vapor.ast.*; import misc.*; import java.util.*; public class VaporizeVisitor extends VInstr.VisitorP { private ArrayList vaporm; String[] callee_save = new String[] { "$s0", "$s1", "$s2", "$s3", "$s4", "$s5", "$s6", "$s7" }; String[] caller_save = new String[] { "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8" }; String[] arg_pass = new String[] { "$a0", "$a1", "$a2", "$a3" }; String[] ret_pass = new String[] { "$v0" }; public VaporizeVisitor(VaporProgram vp, ArrayList vaporm, ArrayList interval_list) { this.vaporm = vaporm; // is it possible for interval_list and the // function in vp to be out of order? for (int i = 0; i < vp.functions.length; ++i) { this.addVaporm(String.format("func %s [in %d, out %d, local %d]", vp.functions[i].ident, 0, 0, interval_list.get(i).getSpilledNum() + 17)); for (int j = 0; j < this.callee_save.length; ++j) { this.addVaporm(String.format(" local[%s] = %s", j, this.callee_save[j])); } for (int j = 0; j < vp.functions[i].params.length; ++j) this.addVaporm(String.format(" %s = %s", interval_list.get(i).getInterval(vp.functions[i].params[j].toString()) .getAssignedRegister(), arg_pass[j])); TreeSet f = this.sortFunction(vp.functions[i]); MinimalLogger.info(String.format("Starting loop with function:\n %s", f.toString())); for (Node n : f) { if (n instanceof VInstr) ((VInstr) n).accept(interval_list.get(i), this); else this.addVaporm(((VCodeLabel) n).ident + ":"); } } } public TreeSet sortFunction(VFunction f) { TreeSet sort = new TreeSet((v1, v2) -> { return Integer.compare(v1.sourcePos.line, v2.sourcePos.line); }); for (VInstr s : f.body) { sort.add(s); } for (VCodeLabel l : f.labels) { sort.add(l); } return sort; } public ArrayList getVaporm() { return this.vaporm; } public void addVaporm(String str) { MinimalLogger.info(String.format("Adding string:\n%s", str)); this.vaporm.add(str); } public void visit(LIRDict d, VAssign n) throws RuntimeException { MinimalLogger.info(String.format("->%s (%s)", n.getClass().getSimpleName(), n.sourcePos.toString())); /////////////////////////////////////////////////////////////// String dest = d.getInterval(((VVarRef.Local) n.dest).ident).getAssignedRegister(); String source = (n.source instanceof VVarRef.Local) ? d.getInterval(n.source.toString()).getAssignedRegister() : n.source.toString(); this.addVaporm(String.format(" %s = %s", dest, source)); /////////////////////////////////////////////////////////////// MinimalLogger.info(String.format("<-%s (%s)", n.getClass().getSimpleName(), n.sourcePos.toString())); } public void visit(LIRDict d, VCall n) throws RuntimeException { MinimalLogger.info(String.format("->%s (%s)", n.getClass().getSimpleName(), n.sourcePos.toString())); /////////////////////////////////////////////////////////////// for (int i = 0; i < this.caller_save.length; ++i) { this.addVaporm(String.format(" local[%s] = %s", i+8, this.caller_save[i])); } // FIXME for arg num > 4! for (int i = 0; i < n.args.length; ++i) { String reg = (n.args[i] instanceof VVarRef.Local) ? d.getInterval(n.args[i].toString()).getAssignedRegister() : n.args[i].toString(); MinimalLogger.info(String.format("Adding argument for %s", n.args[i].toString())); this.addVaporm(String.format(" %s = %s", this.arg_pass[i], reg)); } MinimalLogger.severe(String.format("n addr: %s", n.addr.toString())); MinimalLogger.severe(String.format("Interval: %s", d.getInterval(n.addr.toString()))); LIRVar interval = d.getInterval(n.addr.toString()); if (interval == null) // a label this.addVaporm(String.format(" call %s", n.addr.toString())); else this.addVaporm(String.format(" call %s", interval .getAssignedRegister())); for (int i = 0; i < this.caller_save.length; ++i) { this.addVaporm(String.format(" %s = local[%s]", this.caller_save[i], i+8)); } // get dest if (n.dest != null) { this.addVaporm(String.format(" %s = $v0", d.getInterval(((VVarRef.Local) n.dest).ident) .getAssignedRegister())); } /////////////////////////////////////////////////////////////// MinimalLogger.info(String.format("<-%s (%s)", n.getClass().getSimpleName(), n.sourcePos.toString())); } public void visit(LIRDict d, VBuiltIn n) throws RuntimeException { MinimalLogger.info(String.format("->%s (%s)", n.getClass().getSimpleName(), n.sourcePos.toString())); /////////////////////////////////////////////////////////////// String ret = ""; if (n.dest != null) { ret += String.format("%s = ", d.getInterval(((VVarRef.Local) n.dest).ident) .getAssignedRegister()); } ret += String.format("%s(", ((VBuiltIn.Op) n.op).name); String par; for (VOperand a : n.args) { par = (a instanceof VVarRef.Local) ? d.getInterval(a.toString()).getAssignedRegister() : a.toString(); ret += String.format("%s ", par); } ret += ")"; this.addVaporm(String.format(" %s", ret)); /////////////////////////////////////////////////////////////// MinimalLogger.info(String.format("<-%s (%s)", n.getClass().getSimpleName(), n.sourcePos.toString())); } public void visit(LIRDict d, VMemWrite n) throws RuntimeException { MinimalLogger.info(String.format("->%s (%s)", n.getClass().getSimpleName(), n.sourcePos.toString())); /////////////////////////////////////////////////////////////// String dest = d.getInterval(((VMemRef.Global) n.dest).base.toString()) .getAssignedRegister(); String source = (n.source instanceof VVarRef.Local) ? d.getInterval(n.source.toString()).getAssignedRegister() : n.source.toString(); int byteOffset = ((VMemRef.Global) n.dest).byteOffset; this.addVaporm(String.format(" [%s+%d] = %s", dest, byteOffset, source)); /////////////////////////////////////////////////////////////// MinimalLogger.info(String.format("<-%s (%s)", n.getClass().getSimpleName(), n.sourcePos.toString())); } public void visit(LIRDict d, VMemRead n) throws RuntimeException { MinimalLogger.info(String.format("->%s (%s)", n.getClass().getSimpleName(), n.sourcePos.toString())); /////////////////////////////////////////////////////////////// String dest = (n.dest instanceof VVarRef.Local) ? d.getInterval(n.dest.toString()).getAssignedRegister() : n.dest.toString(); String source = d.getInterval(((VMemRef.Global) n.source).base.toString()) .getAssignedRegister(); int byteOffset = ((VMemRef.Global) n.source).byteOffset; this.addVaporm(String.format(" %s = [%s+%d]", dest, source, byteOffset)); /////////////////////////////////////////////////////////////// MinimalLogger.info(String.format("<-%s (%s)", n.getClass().getSimpleName(), n.sourcePos.toString())); } public void visit(LIRDict d, VBranch n) throws RuntimeException { MinimalLogger.info(String.format("->%s (%s)", n.getClass().getSimpleName(), n.sourcePos.toString())); /////////////////////////////////////////////////////////////// String ret = " "; if (n.positive) ret += "if "; else ret += "if0 "; ret += d.getInterval(n.value.toString()) .getAssignedRegister() + " goto :"; ret += n.target.ident; this.addVaporm(String.format("%s", ret)); /////////////////////////////////////////////////////////////// MinimalLogger.info(String.format("<-%s (%s)", n.getClass().getSimpleName(), n.sourcePos.toString())); } public void visit(LIRDict d, VGoto n) throws RuntimeException { MinimalLogger.info(String.format("->%s (%s)", n.getClass().getSimpleName(), n.sourcePos.toString())); /////////////////////////////////////////////////////////////// this.addVaporm(String.format(" goto :%s", (((VAddr.Label) n.target).label).ident)); /////////////////////////////////////////////////////////////// MinimalLogger.info(String.format("<-%s (%s)", n.getClass().getSimpleName(), n.sourcePos.toString())); } public void visit(LIRDict d, VReturn n) throws RuntimeException { MinimalLogger.info(String.format("->%s (%s)", n.getClass().getSimpleName(), n.sourcePos.toString())); /////////////////////////////////////////////////////////////// // get ret if (n.value != null) { String reg = (n.value instanceof VVarRef.Local) ? d.getInterval(n.value.toString()).getAssignedRegister() : n.value.toString(); this.addVaporm(String.format(" $v0 = %s", reg)); } for (int j = 0; j < this.callee_save.length; ++j) { this.addVaporm(String.format(" %s = local[%s]", this.callee_save[j], j)); } this.addVaporm(" ret"); /////////////////////////////////////////////////////////////// MinimalLogger.info(String.format("<-%s (%s)", n.getClass().getSimpleName(), n.sourcePos.toString())); } }