master
bill 3 years ago
parent b8781807fd
commit cfc8120c78

@ -24,11 +24,11 @@
lw s1, 4(fp) lw s1, 4(fp)
lw s2, @.__len__(s1) lw s2, @.__len__(s1)
addi s1, s1, @.__elts__ addi s1, s1, @.__elts__
lw s4, 12(fp) #lw s4, 12(fp)
concat_1: concat_1:
beqz s2, concat_2 beqz s2, concat_2
lw a0, 0(s1) lw a0, 0(s1)
jalr ra, s4, 0 #jalr ra, s4, 0
sw a0, 0(s3) sw a0, 0(s3)
addi s2, s2, -1 addi s2, s2, -1
addi s1, s1, 4 addi s1, s1, 4
@ -38,11 +38,11 @@ concat_2:
lw s1, 0(fp) lw s1, 0(fp)
lw s2, @.__len__(s1) lw s2, @.__len__(s1)
addi s1, s1, @.__elts__ addi s1, s1, @.__elts__
lw s4, 8(fp) #lw s4, 8(fp)
concat_3: concat_3:
beqz s2, concat_4 beqz s2, concat_4
lw a0, 0(s1) lw a0, 0(s1)
jalr ra, s4, 0 #jalr ra, s4, 0
sw a0, 0(s3) sw a0, 0(s3)
addi s2, s2, -1 addi s2, s2, -1
addi s1, s1, 4 addi s1, s1, 4

@ -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");
} }

Loading…
Cancel
Save