/* Copyright (c) 1997 Andrew W. Appel. Licensed software: see LICENSE file */ package Mips; import Temp.Temp; import Temp.TempList; import Temp.Label; import java.util.*; class InFrame extends Frame.Access { int offset; InFrame(int o) {offset=o;} public Tree.Exp exp(Tree.Exp framePtr) { return new Tree.MEM(new Tree.BINOP(Tree.BINOP.PLUS,framePtr,new Tree.CONST(offset))); } } class InReg extends Frame.Access { Temp temp; InReg(Temp t) {temp=t;} public Tree.Exp exp(Tree.Exp framePtr) { return new Tree.TEMP(temp); } } public class MipsFrame extends Frame.Frame { static java.util.Dictionary tempTab = new java.util.Hashtable(); static TempList regs = null; static Temp enterTemp(String reg) { Temp t = new Temp(); regs = new TempList(t, regs); tempTab.put(t, reg); return t; } public String tempMap(Temp t) {return (String)tempTab.get(t);} public TempList registers() {return regs;} final static Temp FPx = new Temp(); final static Temp ZEROx = enterTemp("$0"); final static Temp SPx = enterTemp("$sp"); final static Temp RAx = enterTemp("$31"); static {tempTab.put(FPx,"$fp");} final static TempList callerSaves=withtemp("$2 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $24 $25"), calleeSaves=withtemp("$16 $17 $18 $19 $20 $21 $22 $23 $30"), calleeSavesRA = new TempList(RAx, calleeSaves); final static Temp RVx = callerSaves.head; final static int numArgRegs = 5; private static TempList withtemp(String s) { java.util.StringTokenizer st = new java.util.StringTokenizer(s); TempList p = new TempList(ZEROx,null); TempList head=p; while (st.hasMoreTokens()) { p.tail = new TempList(enterTemp(st.nextToken()),null); p=p.tail; } return head.tail; } int nFormals; int locals; Tree.Stm mover = new Tree.EXP(new Tree.CONST(0)); private Frame.AccessList params(int i, TempList argregs, Util.BoolList escapes) { if (escapes==null) return null; else if (i < numArgRegs) { Frame.Access formal; Tree.Exp actual = new Tree.TEMP(argregs.head); if (escapes.head) formal= new InFrame(i*wordSize()); else formal= new InReg(new Temp()); mover = new Tree.SEQ(mover, new Tree.MOVE(formal.exp(new Tree.TEMP(FP())),actual)); return new Frame.AccessList(formal, params(i+1,argregs.tail,escapes.tail)); } else return new Frame.AccessList(new InFrame(i*wordSize()), params(i+1,null,escapes.tail)); } private MipsFrame(Label nm, Util.BoolList fmls) { formals=params(0,callerSaves,fmls); name=nm; locals=0; } public MipsFrame() { this(new Label(""), null);} public Temp RV() {return RVx;} public Temp FP() {return FPx;} public int wordSize() {return 4;} public Tree.Exp externalCall(String func, Tree.ExpList args) { return new Tree.CALL(new Tree.NAME(new Label(func)), new Tree.ExpList(new Tree.CONST(0),args)); } public Frame.Frame newFrame(Label name, Util.BoolList formals) { return new MipsFrame(name,formals); } public Frame.Access allocLocal(boolean escape) { if (escape) return new InFrame(-wordSize()*(++locals)); else return new InReg(new Temp()); } public String string(Label label, String value) { StringBuffer b = new StringBuffer(); int i; char c; b.append(".data\n"); b.append(label.toString()); b.append(":\t.word\t"); b.append(String.valueOf(value.length())); b.append("\n\t.ascii\t\""); for(i=0; i= ' ' && c<127) b.append(c); else { b.append('\\'); b.append('0' + c>>6); b.append('0' + (c>>3)&8); b.append('0' + c&8); } } b.append("\"\n\t.align\t2\n"); return b.toString(); } final static boolean hasSpillPhase = true; /* public Tree.Stm procEntryExit1(Tree.Stm body) { Tree.Stm saveStm=new Tree.EXP(new Tree.CONST(0)), restoreStm=new Tree.EXP(new Tree.CONST(0)); for(TempList r = calleeSavesRA; r!=null; r=r.tail) { Frame.Access saveLoc = allocLocal(!hasSpillPhase); saveStm=new Tree.SEQ(saveStm,new Tree.MOVE(saveLoc.exp(new Tree.TEMP(FP())), new Tree.TEMP(r.head))); restoreStm=new Tree.SEQ(restoreStm,new Tree.MOVE(new Tree.TEMP(r.head), saveLoc.exp(new Tree.TEMP(FP())))); } return new Tree.SEQ(mover,new Tree.SEQ(saveStm,new Tree.SEQ(body, restoreStm))); } */ public Vector procEntryExit1(Tree.Stm body) { Vector result=new Vector(); Tree.Stm saveStm=new Tree.EXP(new Tree.CONST(0)), restoreStm=new Tree.EXP(new Tree.CONST(0)); for(TempList r = calleeSavesRA; r!=null; r=r.tail) { Frame.Access saveLoc = allocLocal(!hasSpillPhase); saveStm=new Tree.SEQ(saveStm,new Tree.MOVE(saveLoc.exp(new Tree.TEMP(FP())), new Tree.TEMP(r.head))); restoreStm=new Tree.SEQ(restoreStm,new Tree.MOVE(new Tree.TEMP(r.head), saveLoc.exp(new Tree.TEMP(FP())))); } saveStm=new Tree.SEQ(mover, saveStm); result.addElement(saveStm); result.addElement(body); result.addElement(restoreStm); return result; } static TempList returnSink = new TempList(ZEROx, new TempList(RAx, new TempList(SPx, calleeSaves))); static Assem.InstrList append(Assem.InstrList a, Assem.InstrList b) { Assem.InstrList p; if (a==null) return b; else { for(p=a; p.tail!=null; p=p.tail) ; p.tail=b; return a; } } public Assem.InstrList procEntryExit2(Assem.InstrList body) { return append(body, new Assem.InstrList(new Assem.OPER("", null, returnSink),null)); } public Frame.Proc procEntryExit3(Assem.InstrList body) { int maxOutgoingActuals = 8; /* should be calculated! */ int framesize = 4 * (maxOutgoingActuals + locals); String framename = name.toString() + "_framesize"; String maxframename = name.toString() + "_framesize_max"; /* String prolog = "\n\t.globl\t" + name.toString() + "\n\t.ent\t" + name.toString() + "\n\t" + framename + "=" + String.valueOf(framesize) + "\n\t.frame\t$sp," + framename + ",$31\n" + name.toString() + ":\n\taddiu\t$sp,$sp,-" + framename + "\n"; */ String prolog = "\n.text\n\t.globl\t" + name.toString() + "\n\t.ent\t" + name.toString() + "\n\t" + framename + "=" + String.valueOf(framesize) + "\n\t" + maxframename + "=" + "-" + String.valueOf(framesize) +"\n\t.frame\t$sp," + framename + ",$31\n" + name.toString() + ":\n\taddiu\t$sp,$sp," + maxframename + "\n"; String epilog = "\taddiu\t$sp,$sp," + framename + "\n\tj\t$31\n\t.end\t" + name.toString() +"\n"; return new Frame.Proc(prolog,body, epilog); } public Assem.InstrList codegen(Tree.Stm stm) { return (new Codegen(this)).codegen(stm); } }