|
|
|
@ -114,14 +114,12 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
// space for control link = 1
|
|
|
|
|
// space for static link = 1
|
|
|
|
|
// space for locals = num of locals
|
|
|
|
|
//int requiredStackSpace = (1 + 1 + 1 + funcInfo.getLocals().size())*wordSize;
|
|
|
|
|
String sizelabel = "@" + funcInfo.getFuncName()+".size";
|
|
|
|
|
backend.emitADDI(SP, SP, "-"+sizelabel, "Reserve space for stack frame.");
|
|
|
|
|
backend.emitSW(RA, SP, sizelabel+"-4", "return address");
|
|
|
|
|
backend.emitSW(FP, SP, sizelabel + "-8", "control link");
|
|
|
|
|
// if we want to add static link
|
|
|
|
|
//backend.emitSW(FP, SP, requiredStackSpace-12, "static link");
|
|
|
|
|
backend.emitADDI(FP, SP, sizelabel, "New fp is at old SP.");
|
|
|
|
|
backend.emitADDI(FP, SP, sizelabel, "New FP is at old SP.");
|
|
|
|
|
|
|
|
|
|
StmtAnalyzer stmtAnalyzer = new StmtAnalyzer(funcInfo);
|
|
|
|
|
int emptySlotNum = 3;
|
|
|
|
@ -130,7 +128,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
Literal varLiteral = var.getInitialValue();
|
|
|
|
|
Register reg = varLiteral.dispatch(stmtAnalyzer);
|
|
|
|
|
// All Literals should save locations for the values in A0
|
|
|
|
|
backend.emitSW(reg, SP, sizelabel+String.format("-%d",emptySlotNum*wordSize), "Push local variable " + var.getVarName() + " onto stack");
|
|
|
|
|
backend.emitSW(reg, SP, sizelabel+String.format("-%d",emptySlotNum*wordSize), "Push local variable: " + var.getVarName() + " onto stack");
|
|
|
|
|
emptySlotNum++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -274,7 +272,6 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
backend.defineSym(size_label, max_sp*wordSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// *********** functions start ***********
|
|
|
|
|
|
|
|
|
|
public Register analyze(CallExpr node)
|
|
|
|
@ -374,9 +371,11 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
}
|
|
|
|
|
else if (expr.getInferredType().equals(Type.BOOL_TYPE))
|
|
|
|
|
{
|
|
|
|
|
if (!formalParamInfo.getVarType().equals(Type.OBJECT_TYPE) && !formalParamInfo.getVarType().equals(Type.BOOL_TYPE)) {
|
|
|
|
|
if(!formalParamInfo.getVarType().equals(Type.OBJECT_TYPE) && !formalParamInfo.getVarType().equals(Type.BOOL_TYPE))
|
|
|
|
|
{
|
|
|
|
|
backend.emitJAL(errorNI, "Passed argument does not match formal parameter");
|
|
|
|
|
} else if ((functionId.name.equals("print"))&&(formalParamInfo.getVarType().equals(Type.OBJECT_TYPE) || formalParamInfo.getVarType().equals(Type.BOOL_TYPE)))
|
|
|
|
|
}
|
|
|
|
|
else if ((functionId.name.equals("print"))&&(formalParamInfo.getVarType().equals(Type.OBJECT_TYPE) || formalParamInfo.getVarType().equals(Type.BOOL_TYPE)))
|
|
|
|
|
{
|
|
|
|
|
if(!(args.size() == 1 && (args.get(0) instanceof CallExpr) &&
|
|
|
|
|
(sym.get(((CallExpr) args.get(0)).function.name) instanceof ClassInfo)))
|
|
|
|
@ -388,8 +387,6 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
// So, once expr is evaluated add value inside A0 onto stack as an actual argument
|
|
|
|
|
backend.emitSW(A0, FP, -(sp_off) * wordSize, "Push actual argument for " + formalParamName + " onto stack");
|
|
|
|
|
}
|
|
|
|
|
//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.emitADDI(SP, FP, "-"+size_label, "Set SP to stack frame top.");
|
|
|
|
@ -400,7 +397,6 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
|
|
|
|
|
public Register analyze(MethodCallExpr node)
|
|
|
|
|
{
|
|
|
|
|
System.out.println("Inside MethodCallExpr: " + node.method.member.name);
|
|
|
|
|
Register obj = node.method.object.dispatch(this);
|
|
|
|
|
int n_args = node.args.size();
|
|
|
|
|
|
|
|
|
@ -532,7 +528,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
backend.emitMV(tmp, FP, "Referencing local variable"+info.getVarName());
|
|
|
|
|
backend.emitMV(tmp, FP, "Referencing local variable: "+info.getVarName());
|
|
|
|
|
}
|
|
|
|
|
int idx = varFuncInfo.getVarIndex(info.getVarName());
|
|
|
|
|
int paramSize = varFuncInfo.getParams().size();
|
|
|
|
@ -563,7 +559,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
backend.emitSW(reg, Register.FP, -sp_off*wordSize, "Store value to b stored");
|
|
|
|
|
backend.emitSW(reg, Register.FP, -sp_off*wordSize, "Store value to be stored");
|
|
|
|
|
incSp(1);
|
|
|
|
|
boolean old_lvalue = l_value;
|
|
|
|
|
l_value = true;
|
|
|
|
@ -577,7 +573,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
tmpHandle = getRegister();
|
|
|
|
|
tmp = registerPool[tmpHandle];
|
|
|
|
|
}
|
|
|
|
|
backend.emitLW(tmp, Register.FP, -sp_off*wordSize, "Load value to b stored");
|
|
|
|
|
backend.emitLW(tmp, Register.FP, -sp_off*wordSize, "Load value to be stored");
|
|
|
|
|
backend.emitSW(tmp, ret, 0, "Set list element");
|
|
|
|
|
if(tmpHandle >= 0)
|
|
|
|
|
freeRegister(tmpHandle);
|
|
|
|
@ -589,8 +585,6 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
@Override
|
|
|
|
|
public Register analyze(ExprStmt node)
|
|
|
|
|
{
|
|
|
|
|
System.out.println("Inside ExprStmt: ");
|
|
|
|
|
// backend.emitLW(T6, FP, 0, "Inside ExprStmt: ");
|
|
|
|
|
node.expr.dispatch(this);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
@ -598,7 +592,6 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
@Override
|
|
|
|
|
public Register analyze(IfExpr node)
|
|
|
|
|
{
|
|
|
|
|
System.out.println("Inside IfExpr: ");
|
|
|
|
|
Register result = node.condition.dispatch(this);
|
|
|
|
|
Label ln = generateLocalLabel();
|
|
|
|
|
elseBlock.push(generateLocalLabel());
|
|
|
|
@ -606,12 +599,12 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
backend.emitBEQZ(result, elseBlock.peek(),"Jump to end of loop");
|
|
|
|
|
result = node.thenExpr.dispatch(this);
|
|
|
|
|
if(result != A0)
|
|
|
|
|
backend.emitMV(A0, result, "move result");
|
|
|
|
|
backend.emitMV(A0, result, "Move result");
|
|
|
|
|
backend.emitJ(ln, "Jump to end of if expression");
|
|
|
|
|
backend.emitLocalLabel(elseBlock.peek(), "Else part of if expression");
|
|
|
|
|
result = node.elseExpr.dispatch(this);
|
|
|
|
|
if(result != A0)
|
|
|
|
|
backend.emitMV(A0, result, "move result");
|
|
|
|
|
backend.emitMV(A0, result, "Move result");
|
|
|
|
|
elseBlock.pop();
|
|
|
|
|
backend.emitLocalLabel(ln, "End of if expression");
|
|
|
|
|
return A0;
|
|
|
|
@ -620,9 +613,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
@Override
|
|
|
|
|
public Register analyze(IfStmt node)
|
|
|
|
|
{
|
|
|
|
|
System.out.println("Inside IfStmt: ");
|
|
|
|
|
Register result = node.condition.dispatch(this);
|
|
|
|
|
|
|
|
|
|
Label ln = generateLocalLabel();
|
|
|
|
|
elseBlock.push(generateLocalLabel());
|
|
|
|
|
backend.emitBEQZ(result, elseBlock.peek(),"Jump to end of loop");
|
|
|
|
@ -640,9 +631,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
@Override
|
|
|
|
|
public Register analyze(BinaryExpr node)
|
|
|
|
|
{
|
|
|
|
|
System.out.println("Inside BinaryExpr: ");
|
|
|
|
|
String operator = node.operator;
|
|
|
|
|
//backend.emitLW(T6, FP, 0, "Inside BinaryExpr: ");
|
|
|
|
|
|
|
|
|
|
if(node.left.getInferredType().equals(Type.INT_TYPE) && node.right.getInferredType().equals(Type.INT_TYPE))
|
|
|
|
|
{
|
|
|
|
@ -705,12 +694,6 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
backend.emitADDI(Register.A0,Register.A0, 1, "Increment by 1");
|
|
|
|
|
backend.emitSLT(Register.A0, T0, A0, comment);
|
|
|
|
|
}
|
|
|
|
|
/* Maybe NA
|
|
|
|
|
else if(operator.equals("is"))
|
|
|
|
|
{
|
|
|
|
|
backend.emitXOR(Register.A0, Register.A0, Register.T0, comment);
|
|
|
|
|
backend.emitSEQZ(Register.A0, Register.A0, "Result is True if XOR equals 0");
|
|
|
|
|
}*/
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
backend.emitJAL(errorNI, "Operator not implemented for integer operands");
|
|
|
|
@ -719,7 +702,6 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
}
|
|
|
|
|
else if(node.left.getInferredType().equals(Type.BOOL_TYPE) && node.right.getInferredType().equals(Type.BOOL_TYPE))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// Comparison operators
|
|
|
|
|
if(operator.equals("=="))
|
|
|
|
|
{
|
|
|
|
@ -769,12 +751,6 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
backend.emitOR(Register.A0, Register.A0, Register.T0, "OR operation");
|
|
|
|
|
backend.emitLocalLabel(label, "Next step after OR");
|
|
|
|
|
}
|
|
|
|
|
/*Maybe NA
|
|
|
|
|
else if(operator.equals("is"))
|
|
|
|
|
{
|
|
|
|
|
backend.emitXOR(Register.A0, Register.A0, Register.T0, comment);
|
|
|
|
|
backend.emitSEQZ(Register.A0, Register.A0, "Result is True if XOR equals 0");
|
|
|
|
|
}*/
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
backend.emitJAL(errorNI, "Operator not implemented for boolean operands");
|
|
|
|
@ -792,7 +768,6 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
backend.emitADDI(Register.SP, Register.FP, "-"+size_label, "Set SP to stack frame");
|
|
|
|
|
sp_off -= 2;
|
|
|
|
|
return Register.A0;
|
|
|
|
|
//addLists();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
backend.emitJAL(errorNI, "Operator not implemented for list operands");
|
|
|
|
@ -803,33 +778,33 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
if(operator.equals("=="))
|
|
|
|
|
{
|
|
|
|
|
incSp(2);
|
|
|
|
|
backend.emitSW(node.left.dispatch(this), FP, (1 - sp_off) *wordSize, "Push argument 0 from last.");
|
|
|
|
|
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.emitSW(node.left.dispatch(this), FP, (1 - sp_off) *wordSize, "Push argument 0 from last");
|
|
|
|
|
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.emitJAL(streqlLabel, "Invoke method:streql");
|
|
|
|
|
sp_off -= 2;
|
|
|
|
|
backend.emitADDI(SP, FP, -sp_off*wordSize, "restore sp");
|
|
|
|
|
backend.emitADDI(SP, FP, -sp_off*wordSize, "Restore sp");
|
|
|
|
|
}
|
|
|
|
|
else if(operator.equals("!="))
|
|
|
|
|
{
|
|
|
|
|
incSp(2);
|
|
|
|
|
backend.emitSW(node.left.dispatch(this), FP, (1 - sp_off) *wordSize, "Push argument 0 from last.");
|
|
|
|
|
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.emitSW(node.left.dispatch(this), FP, (1 - sp_off) *wordSize, "Push argument 0 from last");
|
|
|
|
|
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.emitJAL(strneqlLabel, "Invoke method:strneql");
|
|
|
|
|
sp_off -= 2;
|
|
|
|
|
backend.emitADDI(SP, FP, -sp_off*wordSize, "restore sp");
|
|
|
|
|
backend.emitADDI(SP, FP, -sp_off*wordSize, "Restore SP");
|
|
|
|
|
}
|
|
|
|
|
else if(operator.equals("+"))
|
|
|
|
|
{
|
|
|
|
|
incSp(1);
|
|
|
|
|
backend.emitSW(node.left.dispatch(this), FP, (- sp_off) *wordSize, "Push argument 0 from last.");
|
|
|
|
|
backend.emitSW(node.left.dispatch(this), FP, (- sp_off) *wordSize, "Push argument 0 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.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.emitJAL(strcatLabel, "Invoke method:strcat");
|
|
|
|
|
sp_off -= 2;
|
|
|
|
|
backend.emitADDI(SP, FP, -sp_off*wordSize, "restore sp");
|
|
|
|
|
backend.emitADDI(SP, FP, -sp_off*wordSize, "Restore sp");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
backend.emitJAL(errorNI, "Operator not implemented for String operands");
|
|
|
|
@ -866,8 +841,6 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
@Override
|
|
|
|
|
public Register analyze(Identifier node)
|
|
|
|
|
{
|
|
|
|
|
//backend.emitLW(T6, FP, 0, "Inside Identifier: ");
|
|
|
|
|
System.out.println(node.getInferredType());
|
|
|
|
|
Identifier targetID = (Identifier)node;
|
|
|
|
|
Object var = getVar(targetID);
|
|
|
|
|
if(var instanceof StackVarRuntimeInfo){
|
|
|
|
@ -881,11 +854,9 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
return Register.A0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Register analyze(WhileStmt node)
|
|
|
|
|
{
|
|
|
|
|
System.out.println("Inside WhileStmt: ");
|
|
|
|
|
Label startLoop = generateLocalLabel();
|
|
|
|
|
backend.emitLocalLabel(startLoop, "Beginning of while loop");
|
|
|
|
|
Register result = node.condition.dispatch(this);
|
|
|
|
@ -933,18 +904,13 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
return Register.A0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Register analyze(IntegerLiteral node) {
|
|
|
|
|
System.out.println("Inside IntegerLiteral: " + node.value);
|
|
|
|
|
//backend.emitLW(T6, FP, 0, "Inside IntegerLiteral: " + node.value);
|
|
|
|
|
public Register analyze(IntegerLiteral node)
|
|
|
|
|
{
|
|
|
|
|
backend.emitLI(A0, node.value, "Load integer literal " + node.value);
|
|
|
|
|
|
|
|
|
|
return A0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Register analyze(ForStmt node)
|
|
|
|
|
{
|
|
|
|
@ -1011,7 +977,6 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
{
|
|
|
|
|
Label startLoop = generateLocalLabel();
|
|
|
|
|
Label endLoop = generateLocalLabel();
|
|
|
|
|
//Label temp = generateLocalLabel();
|
|
|
|
|
r=getRegister();
|
|
|
|
|
regs.add(r);
|
|
|
|
|
Register iden = registerPool[r];
|
|
|
|
@ -1031,7 +996,6 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
backend.emitMV(iter, Register.ZERO, "Initialize index variable");
|
|
|
|
|
backend.emitSW(iter, Register.FP, -sp_off*wordSize, "Store index on stack");
|
|
|
|
|
incSp(1);
|
|
|
|
|
//backend.emitADDI(Register.SP, Register.SP, -2*wordSize, "Set SP to last argument");
|
|
|
|
|
backend.emitLocalLabel(startLoop, "Start for loop");
|
|
|
|
|
backend.emitLW(iter, Register.FP, -(sp_off-1)*wordSize, "Load index from stack");
|
|
|
|
|
backend.emitLW(l, Register.FP, -(sp_off-2)*wordSize, "Load string location from stack");
|
|
|
|
@ -1067,7 +1031,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
System.out.println("Iterable not a list or a string");
|
|
|
|
|
backend.emitJAL(errorNI, "Operator not implemented");
|
|
|
|
|
}
|
|
|
|
|
for(int n:regs)
|
|
|
|
|
freeRegister(n);
|
|
|
|
@ -1124,7 +1088,7 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
backend.emitLBU(T0, T0, 0, "Load character");
|
|
|
|
|
backend.emitSLLI(A0, T0, 2, "A0 = T0 * 4");
|
|
|
|
|
backend.emitSLLI(T0, T0, 4, "T0 = T0 * 16");
|
|
|
|
|
backend.emitADD(T0, T0, A0, " T0*20 = offset to all chars");
|
|
|
|
|
backend.emitADD(T0, T0, A0, "T0*20 = offset to all chars");
|
|
|
|
|
backend.emitLA(A0, allCharsLabel, "All chars");
|
|
|
|
|
backend.emitADD(A0, A0, T0, "get the char");
|
|
|
|
|
}
|
|
|
|
@ -1172,7 +1136,8 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
* error and exit the program. For example, to throw an OOB error: backend.emitJ(errorOob, "Go
|
|
|
|
|
* to out-of-bounds error and abort");
|
|
|
|
|
*/
|
|
|
|
|
protected void emitCustomCode() {
|
|
|
|
|
protected void emitCustomCode()
|
|
|
|
|
{
|
|
|
|
|
emitStdFunc("concat");
|
|
|
|
|
emitStdFunc("conslist");
|
|
|
|
|
emitStdFunc("strcat");
|
|
|
|
@ -1190,7 +1155,8 @@ public class CodeGenImpl extends CodeGenBase
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Emit an error routine labeled ERRLABEL that aborts with message MSG. */
|
|
|
|
|
private void emitErrorFunc(Label errLabel, String msg) {
|
|
|
|
|
private void emitErrorFunc(Label errLabel, String msg)
|
|
|
|
|
{
|
|
|
|
|
backend.emitGlobalLabel(errLabel);
|
|
|
|
|
if(errLabel==errorOob)
|
|
|
|
|
backend.emitLI(A0, ERROR_OOB, "Exit code for: " + msg);
|
|
|
|
|