|
|
@ -80,12 +80,12 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
protected void emitTopLevel(List<Stmt> statements)
|
|
|
|
protected void emitTopLevel(List<Stmt> statements)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
String mainlabel = "@..main.size";
|
|
|
|
StmtAnalyzer stmtAnalyzer = new StmtAnalyzer(null);
|
|
|
|
StmtAnalyzer stmtAnalyzer = new StmtAnalyzer(null);
|
|
|
|
backend.emitADDI(SP, SP, -2 * backend.getWordSize(), "Saved FP and saved RA (unused at top level).");
|
|
|
|
backend.emitADDI(SP, SP, "-"+mainlabel, "Saved FP and saved RA (unused at top level).");
|
|
|
|
backend.emitSW(ZERO, SP, 0, "Top saved FP is 0.");
|
|
|
|
backend.emitSW(ZERO, SP, mainlabel+"-4", "Top saved FP is 0.");
|
|
|
|
backend.emitSW(ZERO, SP, 4, "Top saved RA is 0.");
|
|
|
|
backend.emitSW(ZERO, SP, mainlabel+"-8", "Top saved RA is 0.");
|
|
|
|
backend.emitADDI(FP, SP, 2 * backend.getWordSize(), "Set FP to previous SP.");
|
|
|
|
backend.emitADDI(FP, SP, mainlabel, "Set FP to previous SP.");
|
|
|
|
backend.emitJAL(initcharsLabel,"Initialize one-character strings");
|
|
|
|
backend.emitJAL(initcharsLabel,"Initialize one-character strings");
|
|
|
|
for (Stmt stmt : statements)
|
|
|
|
for (Stmt stmt : statements)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -117,14 +117,14 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
// space for control link = 1
|
|
|
|
// space for control link = 1
|
|
|
|
// space for static link = 1
|
|
|
|
// space for static link = 1
|
|
|
|
// space for locals = num of locals
|
|
|
|
// space for locals = num of locals
|
|
|
|
int requiredStackSpace = (1 + 1 + 1 + funcInfo.getLocals().size())*wordSize;
|
|
|
|
//int requiredStackSpace = (1 + 1 + 1 + funcInfo.getLocals().size())*wordSize;
|
|
|
|
|
|
|
|
String sizelabel = "@" + funcInfo.getFuncName()+".size";
|
|
|
|
backend.emitADDI(SP, SP, -requiredStackSpace, "Reserve space for stack frame.");
|
|
|
|
backend.emitADDI(SP, SP, "-"+sizelabel, "Reserve space for stack frame.");
|
|
|
|
backend.emitSW(RA, SP, requiredStackSpace-4, "return address");
|
|
|
|
backend.emitSW(RA, SP, sizelabel+"-4", "return address");
|
|
|
|
backend.emitSW(FP, SP, requiredStackSpace-8, "control link");
|
|
|
|
backend.emitSW(FP, SP, sizelabel + "-8", "control link");
|
|
|
|
// if we want to add static link
|
|
|
|
// if we want to add static link
|
|
|
|
//backend.emitSW(FP, SP, requiredStackSpace-12, "static link");
|
|
|
|
//backend.emitSW(FP, SP, requiredStackSpace-12, "static link");
|
|
|
|
backend.emitADDI(FP, SP, requiredStackSpace, "New fp is at old SP.");
|
|
|
|
backend.emitADDI(FP, SP, sizelabel, "New fp is at old SP.");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
StmtAnalyzer stmtAnalyzer = new StmtAnalyzer(funcInfo);
|
|
|
|
StmtAnalyzer stmtAnalyzer = new StmtAnalyzer(funcInfo);
|
|
|
@ -133,7 +133,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
Literal varLiteral = var.getInitialValue();
|
|
|
|
Literal varLiteral = var.getInitialValue();
|
|
|
|
varLiteral.dispatch(stmtAnalyzer);
|
|
|
|
varLiteral.dispatch(stmtAnalyzer);
|
|
|
|
// All Literals should save locations for the values in A0
|
|
|
|
// All Literals should save locations for the values in A0
|
|
|
|
backend.emitSW(A0, SP, requiredStackSpace-emptySlotNum*wordSize, "Push local variable " + var.getVarName() + " onto stack");
|
|
|
|
backend.emitSW(A0, SP, sizelabel+String.format("-%d",emptySlotNum*wordSize), "Push local variable " + var.getVarName() + " onto stack");
|
|
|
|
emptySlotNum++;
|
|
|
|
emptySlotNum++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -154,7 +154,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
backend.emitLocalLabel(stmtAnalyzer.epilogue, "Epilogue");
|
|
|
|
backend.emitLocalLabel(stmtAnalyzer.epilogue, "Epilogue");
|
|
|
|
backend.emitLW(RA, FP, -4, "Get return address");
|
|
|
|
backend.emitLW(RA, FP, -4, "Get return address");
|
|
|
|
backend.emitLW(FP, FP, -8, "Use control link to restore caller's fp");
|
|
|
|
backend.emitLW(FP, FP, -8, "Use control link to restore caller's fp");
|
|
|
|
backend.emitADDI(SP, SP, requiredStackSpace, "Restore stack pointer");
|
|
|
|
backend.emitADDI(SP, SP, sizelabel, "Restore stack pointer");
|
|
|
|
backend.emitJR(RA, "Return to caller");
|
|
|
|
backend.emitJR(RA, "Return to caller");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -326,17 +326,20 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
backend.emitLW(tmp, tmp, curr.getParams().size()*wordSize, "Load static link to " + curr.getFuncName());
|
|
|
|
backend.emitLW(tmp, tmp, curr.getParams().size()*wordSize, "Load static link to " + curr.getFuncName());
|
|
|
|
curr = curr.getParentFuncInfo();
|
|
|
|
curr = curr.getParentFuncInfo();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
backend.emitSW(tmp, FP, -(sp_off+1) * wordSize, "Push static link onto active frame.");
|
|
|
|
backend.emitSW(tmp, FP, -(1+sp_off) * wordSize, "Push static link onto active frame.");
|
|
|
|
|
|
|
|
freeRegister(tmpHandle);
|
|
|
|
freeRegister(tmpHandle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else {
|
|
|
|
backend.emitSW(FP, FP, -(1+sp_off) * wordSize, "Push static link onto active frame.");
|
|
|
|
backend.emitSW(FP, FP, -(sp_off+1) * wordSize, "Push static link onto active frame.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int origsp = sp_off;
|
|
|
|
|
|
|
|
incSp(1);
|
|
|
|
|
|
|
|
|
|
|
|
List<Expr> args = node.args;
|
|
|
|
List<Expr> args = node.args;
|
|
|
|
int spaceRequiredForArgs = (args.size() + 1)*4;
|
|
|
|
int spaceRequiredForArgs = (args.size() + 1)*4;
|
|
|
|
for (int i = 0; i < args.size(); i++) {
|
|
|
|
for (int i = 0; i < args.size(); i++) {
|
|
|
|
|
|
|
|
incSp(1);
|
|
|
|
|
|
|
|
|
|
|
|
int argNum = i + 1;
|
|
|
|
int argNum = i + 1;
|
|
|
|
int slotNum = argNum + 1; // We have extra slot for static link
|
|
|
|
int slotNum = argNum + 1; // We have extra slot for static link
|
|
|
|
Expr expr = args.get(i);
|
|
|
|
Expr expr = args.get(i);
|
|
|
@ -368,12 +371,16 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
|
|
|
|
|
|
|
// All expressions should save their end result in A0
|
|
|
|
// All expressions should save their end result in A0
|
|
|
|
// So, once expr is evaluated add value inside A0 onto stack as an actual argument
|
|
|
|
// So, once expr is evaluated add value inside A0 onto stack as an actual argument
|
|
|
|
backend.emitSW(A0, FP, -(slotNum+sp_off) * wordSize, "Push actual argument for " + formalParamName + " onto stack");
|
|
|
|
//System.out.printf("1: %d\n",sp_off + 1 - slotNum-origsp);
|
|
|
|
}
|
|
|
|
backend.emitSW(A0, FP, -(sp_off) * wordSize, "Push actual argument for " + formalParamName + " onto stack");
|
|
|
|
|
|
|
|
|
|
|
|
backend.emitADDI(SP, FP, -spaceRequiredForArgs-sp_off*wordSize, "Set SP to last argument.");
|
|
|
|
}
|
|
|
|
|
|
|
|
//System.out.printf("2: %d",sp_off - spaceRequiredForArgs/wordSize - origsp);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend.emitADDI(SP, FP, -(sp_off)*wordSize, "Set SP to last argument.");
|
|
|
|
backend.emitJAL(calleeFunctionInfo.getCodeLabel(), "Invoke function: " + functionId.name);
|
|
|
|
backend.emitJAL(calleeFunctionInfo.getCodeLabel(), "Invoke function: " + functionId.name);
|
|
|
|
backend.emitADDI(SP, FP, spaceRequiredForArgs+sp_off*wordSize, "Set SP to stack frame top.");
|
|
|
|
backend.emitADDI(SP, FP, "-"+size_label, "Set SP to stack frame top.");
|
|
|
|
|
|
|
|
sp_off-=spaceRequiredForArgs/wordSize;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return A0;
|
|
|
|
return A0;
|
|
|
@ -421,11 +428,10 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
Expr expr = stmt.value;
|
|
|
|
Expr expr = stmt.value;
|
|
|
|
if (expr == null) {
|
|
|
|
if (expr == null) {
|
|
|
|
backend.emitMV(A0, ZERO, "Return None");
|
|
|
|
backend.emitMV(A0, ZERO, "Return None");
|
|
|
|
return A0;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
// All expressions should save their end result in A0
|
|
|
|
// All expressions should save their end result in A0
|
|
|
|
expr.dispatch(this);
|
|
|
|
expr.dispatch(this);
|
|
|
|
backend.emitJ(this.epilogue, "Jump to function epilogue");
|
|
|
|
backend.emitJ(this.epilogue, "Jump to function epilogue");
|
|
|
|
return A0;
|
|
|
|
return A0;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -781,15 +787,13 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(operator.equals("+"))
|
|
|
|
if(operator.equals("+"))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
node.left.dispatch(this);
|
|
|
|
incSp(2);
|
|
|
|
backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push left operand on stack slot "+sp_off);
|
|
|
|
backend.emitSW(node.left.dispatch(this), Register.FP, -(sp_off-1)*wordSize, "Push left operand on stack slot "+sp_off);
|
|
|
|
incSp(1);
|
|
|
|
backend.emitSW(node.right.dispatch(this), Register.FP, -(sp_off)*wordSize, "Push right operand on stack slot "+sp_off);
|
|
|
|
node.right.dispatch(this);
|
|
|
|
backend.emitADDI(Register.SP,Register.FP,-(sp_off)*wordSize,"Set SP to last argument");
|
|
|
|
backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push right operand on stack slot "+sp_off);
|
|
|
|
|
|
|
|
incSp(1);
|
|
|
|
|
|
|
|
backend.emitADDI(Register.SP,Register.FP,-(sp_off-1)*wordSize,"Set SP to last argument");
|
|
|
|
|
|
|
|
backend.emitJAL(concatLabel, "Call concatenation routine");
|
|
|
|
backend.emitJAL(concatLabel, "Call concatenation routine");
|
|
|
|
backend.emitADDI(Register.SP, Register.FP, "-"+size_label, "Set SP to stack frame");
|
|
|
|
backend.emitADDI(Register.SP, Register.FP, "-"+size_label, "Set SP to stack frame");
|
|
|
|
|
|
|
|
sp_off -= 2;
|
|
|
|
return Register.A0;
|
|
|
|
return Register.A0;
|
|
|
|
//addLists();
|
|
|
|
//addLists();
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -821,9 +825,10 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(operator.equals("+"))
|
|
|
|
else if(operator.equals("+"))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
incSp(2);
|
|
|
|
incSp(1);
|
|
|
|
backend.emitSW(node.left.dispatch(this), FP, (1 - sp_off) *wordSize, "Push argument 0 from last.");
|
|
|
|
backend.emitSW(node.left.dispatch(this), FP, (- sp_off) *wordSize, "Push argument 0 from last.");
|
|
|
|
backend.emitSW(node.right.dispatch(this), FP, ( - sp_off) *wordSize, "Push argument 1 from last.");
|
|
|
|
incSp(1);
|
|
|
|
|
|
|
|
backend.emitSW(node.right.dispatch(this), FP, (- sp_off) *wordSize, "Push argument 1 from last.");
|
|
|
|
backend.emitADDI(SP, FP, -sp_off * wordSize, "Set SP to last argument.");
|
|
|
|
backend.emitADDI(SP, FP, -sp_off * wordSize, "Set SP to last argument.");
|
|
|
|
backend.emitJAL(strcatLabel, "Invoke method:strcat");
|
|
|
|
backend.emitJAL(strcatLabel, "Invoke method:strcat");
|
|
|
|
sp_off -= 2;
|
|
|
|
sp_off -= 2;
|
|
|
@ -927,7 +932,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
backend.emitADDI(Register.SP, Register.FP, -(sp_off-1)*wordSize, "Set SP to last argument");
|
|
|
|
backend.emitADDI(Register.SP, Register.FP, -(sp_off-1)*wordSize, "Set SP to last argument");
|
|
|
|
backend.emitJAL(conslistLabel, "Move values to new list object");
|
|
|
|
backend.emitJAL(conslistLabel, "Move values to new list object");
|
|
|
|
backend.emitADDI(Register.SP, Register.FP, "-"+size_label, "Set SP to stack frame");
|
|
|
|
backend.emitADDI(Register.SP, Register.FP, "-"+size_label, "Set SP to stack frame");
|
|
|
|
sp_off-=l;
|
|
|
|
sp_off-=l+1;
|
|
|
|
return Register.A0;
|
|
|
|
return Register.A0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -976,14 +981,12 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
backend.emitSW(iter, Register.FP, -sp_off*wordSize, "Store index on stack");
|
|
|
|
backend.emitSW(iter, Register.FP, -sp_off*wordSize, "Store index on stack");
|
|
|
|
incSp(1);
|
|
|
|
incSp(1);
|
|
|
|
backend.emitLocalLabel(startLoop, "Start for loop");
|
|
|
|
backend.emitLocalLabel(startLoop, "Start for loop");
|
|
|
|
sp_off--;
|
|
|
|
backend.emitLW(iter, Register.FP, -(sp_off-1)*wordSize, "Load index from stack");
|
|
|
|
backend.emitLW(iter, Register.FP, -sp_off*wordSize, "Load index from stack");
|
|
|
|
backend.emitLW(l, Register.FP, -(sp_off-2)*wordSize, "Store list location from stack");
|
|
|
|
backend.emitLW(l, Register.FP, -(sp_off-1)*wordSize, "Store list location from stack");
|
|
|
|
|
|
|
|
backend.emitLW(ln, l, getAttrOffset(listClass, "__len__"), "Get attribute __len__");
|
|
|
|
backend.emitLW(ln, l, getAttrOffset(listClass, "__len__"), "Get attribute __len__");
|
|
|
|
backend.emitBGEU(iter, ln, endLoop, "Jump to end loop if counter exceeds length");
|
|
|
|
backend.emitBGEU(iter, ln, endLoop, "Jump to end loop if counter exceeds length");
|
|
|
|
backend.emitADDI(iter, iter, 1, "Increment counter");
|
|
|
|
backend.emitADDI(iter, iter, 1, "Increment counter");
|
|
|
|
backend.emitSW(iter, Register.FP, -sp_off*wordSize, "Store index on stack");
|
|
|
|
backend.emitSW(iter, Register.FP, -(sp_off-1)*wordSize, "Store index on stack");
|
|
|
|
incSp(1);
|
|
|
|
|
|
|
|
backend.emitADDI(iden, iter, 3, "Compute list element offset in words");
|
|
|
|
backend.emitADDI(iden, iter, 3, "Compute list element offset in words");
|
|
|
|
backend.emitLI(ln, wordSize, "Word size in bytes");
|
|
|
|
backend.emitLI(ln, wordSize, "Word size in bytes");
|
|
|
|
backend.emitMUL(iden, iden, ln, "Compute list element offset in bytes");
|
|
|
|
backend.emitMUL(iden, iden, ln, "Compute list element offset in bytes");
|
|
|
@ -1003,6 +1006,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for(Stmt stmt:node.body)
|
|
|
|
for(Stmt stmt:node.body)
|
|
|
|
stmt.dispatch(this);
|
|
|
|
stmt.dispatch(this);
|
|
|
|
|
|
|
|
sp_off -= 2;
|
|
|
|
backend.emitJ(startLoop, "Jump to beginning of loop");
|
|
|
|
backend.emitJ(startLoop, "Jump to beginning of loop");
|
|
|
|
backend.emitLocalLabel(endLoop, "End of for loop");
|
|
|
|
backend.emitLocalLabel(endLoop, "End of for loop");
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1060,6 +1064,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for(Stmt stmt:node.body)
|
|
|
|
for(Stmt stmt:node.body)
|
|
|
|
stmt.dispatch(this);
|
|
|
|
stmt.dispatch(this);
|
|
|
|
|
|
|
|
sp_off -= 2;
|
|
|
|
backend.emitJ(startLoop, "Jump to beginning of loop");
|
|
|
|
backend.emitJ(startLoop, "Jump to beginning of loop");
|
|
|
|
backend.emitLocalLabel(endLoop, "End of for loop");
|
|
|
|
backend.emitLocalLabel(endLoop, "End of for loop");
|
|
|
|
}
|
|
|
|
}
|
|
|
|