Cleanup Part 1

master
Apoorva Ranade 3 years ago
parent bb25165c34
commit d529a8f17b

@ -92,7 +92,6 @@ public class CodeGenImpl extends CodeGenBase
stmt.dispatch(stmtAnalyzer); stmt.dispatch(stmtAnalyzer);
} }
stmtAnalyzer.emitSizeLabel(); stmtAnalyzer.emitSizeLabel();
backend.emitLI(A0, EXIT_ECALL, "Code for ecall: exit"); backend.emitLI(A0, EXIT_ECALL, "Code for ecall: exit");
backend.emitEcall(null); backend.emitEcall(null);
} }
@ -110,8 +109,6 @@ public class CodeGenImpl extends CodeGenBase
{ {
backend.emitGlobalLabel(funcInfo.getCodeLabel()); backend.emitGlobalLabel(funcInfo.getCodeLabel());
// --- Prologue --- // --- Prologue ---
// space for return address = 1 // space for return address = 1
// space for control link = 1 // space for control link = 1
@ -126,14 +123,14 @@ public class CodeGenImpl extends CodeGenBase
//backend.emitSW(FP, SP, requiredStackSpace-12, "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); StmtAnalyzer stmtAnalyzer = new StmtAnalyzer(funcInfo);
int emptySlotNum = 3; int emptySlotNum = 3;
for (StackVarInfo var : funcInfo.getLocals()) { for (StackVarInfo var : funcInfo.getLocals())
{
Literal varLiteral = var.getInitialValue(); Literal varLiteral = var.getInitialValue();
varLiteral.dispatch(stmtAnalyzer); Register reg = 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, 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++; emptySlotNum++;
} }
@ -143,13 +140,13 @@ public class CodeGenImpl extends CodeGenBase
// statements use fp to load the variables // statements use fp to load the variables
// example: 0(fp) is the last variable (z) while 8(fp) is the first variable (x) // example: 0(fp) is the last variable (z) while 8(fp) is the first variable (x)
// for function with 3 params f(x, y, z) // for function with 3 params f(x, y, z)
for (Stmt stmt : funcInfo.getStatements()) { for (Stmt stmt : funcInfo.getStatements())
{
stmt.dispatch(stmtAnalyzer); stmt.dispatch(stmtAnalyzer);
} }
stmtAnalyzer.emitSizeLabel(); stmtAnalyzer.emitSizeLabel();
backend.emitJ(stmtAnalyzer.epilogue, "Jump to function epilogue"); backend.emitJ(stmtAnalyzer.epilogue, "Jump to function epilogue");
// --- Epilogue --- // --- Epilogue ---
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");
@ -159,7 +156,8 @@ public class CodeGenImpl extends CodeGenBase
} }
/** An analyzer that encapsulates code generation for statements. */ /** An analyzer that encapsulates code generation for statements. */
private class StmtAnalyzer extends AbstractNodeAnalyzer<Register> { private class StmtAnalyzer extends AbstractNodeAnalyzer<Register>
{
/* /*
* The symbol table has all the info you need to determine what a given * The symbol table has all the info you need to determine what a given
* identifier 'x' in the current scope is. You can use it as follows: SymbolInfo * identifier 'x' in the current scope is. You can use it as follows: SymbolInfo
@ -199,8 +197,7 @@ public class CodeGenImpl extends CodeGenBase
/** Label of code that exits from block. */ /** Label of code that exits from block. */
protected Stack<Label> elseBlock = new Stack<Label>(); protected Stack<Label> elseBlock = new Stack<Label>();
/** Label which stores total size of function on stack */
private final String size_label; private final String size_label;
/** Variable to store offset from frame pointer to identify next /** Variable to store offset from frame pointer to identify next
* empty space on stack frame to store variable*/ * empty space on stack frame to store variable*/
@ -210,7 +207,8 @@ public class CodeGenImpl extends CodeGenBase
private boolean l_value = false; private boolean l_value = false;
private final Register[] registerPool = {T2,T3, T4, T5, T6, A2, A3, A4, A5, A6, A7}; private final Register[] registerPool = {T2,T3, T4, T5, T6, A2, A3, A4, A5, A6, A7};
private final boolean[] registerAvilMap = {true, true, true, true, true, true, true, true, true, true, true}; private final boolean[] registerAvilMap = {true, true, true, true, true, true, true, true, true, true, true};
private int getRegister(){ //return a handle of a vacant register private int getRegister()
{ //return a handle of a vacant register
for(int i = 0; i < 11; ++i) for(int i = 0; i < 11; ++i)
if(registerAvilMap[i]) if(registerAvilMap[i])
{ {
@ -222,13 +220,16 @@ public class CodeGenImpl extends CodeGenBase
System.out.println("Insufficient Registers!!!"); System.out.println("Insufficient Registers!!!");
registerAvilMap[i] = true; //freeall; registerAvilMap[i] = true; //freeall;
} }
registerAvilMap[0]=false;
return 0; return 0;
} }
private void freeRegister(int handle){ //handle used to free the register private void freeRegister(int handle)
{ //handle used to free the register
registerAvilMap[handle] = true; registerAvilMap[handle] = true;
} }
private int getParamLocationOffset(int index, int paramSize) { private int getParamLocationOffset(int index, int paramSize)
{
return (paramSize - index - 1) * wordSize; return (paramSize - index - 1) * wordSize;
} }
@ -236,7 +237,8 @@ public class CodeGenImpl extends CodeGenBase
return - (index - paramSize + 1) * wordSize; return - (index - paramSize + 1) * wordSize;
} }
private int getStaticLinkOffset(int paramSize) { private int getStaticLinkOffset(int paramSize)
{
return paramSize * wordSize; return paramSize * wordSize;
} }
@ -244,39 +246,44 @@ public class CodeGenImpl extends CodeGenBase
* An analyzer for the function described by FUNCINFO0, which is null for the * An analyzer for the function described by FUNCINFO0, which is null for the
* top level. * top level.
*/ */
StmtAnalyzer(FuncInfo funcInfo0) { StmtAnalyzer(FuncInfo funcInfo0)
{
funcInfo = funcInfo0; funcInfo = funcInfo0;
if (funcInfo == null) { if (funcInfo == null)
{
sym = globalSymbols; sym = globalSymbols;
sp_off = max_sp = 2; sp_off = max_sp = 2;
size_label = "@..main.size"; size_label = "@..main.size";
} else { }
else
{
sym = funcInfo.getSymbolTable(); sym = funcInfo.getSymbolTable();
sp_off = max_sp = funcInfo0.getLocals().size() + 2 + 1; sp_off = max_sp = funcInfo0.getLocals().size() + 2 + 1;
size_label = "@"+funcInfo0.getFuncName()+".size"; size_label = "@"+funcInfo0.getFuncName()+".size";
} }
epilogue = generateLocalLabel(); epilogue = generateLocalLabel();
} }
private void incSp(int i){ private void incSp(int i)
{
sp_off+=i; sp_off+=i;
max_sp = max_sp >= sp_off?max_sp:sp_off; max_sp = max_sp >= sp_off?max_sp:sp_off;
} }
public void emitSizeLabel(){ public void emitSizeLabel()
{
backend.defineSym(size_label, max_sp*wordSize); backend.defineSym(size_label, max_sp*wordSize);
} }
// *********** functions start *********** // *********** functions start ***********
public Register analyze(CallExpr node) { public Register analyze(CallExpr node)
System.out.println("Inside CallExpr: " + node.function.name); {
//ackend.emitLW(T6, FP, 0, "Inside CallExpr: " + node.function.name); SymbolInfo ty = sym.get(node.function.name);
if(ty instanceof ClassInfo)
SymbolInfo Ty = sym.get(node.function.name); {
if(Ty instanceof ClassInfo){
//object create //object create
ClassInfo cls = (ClassInfo) Ty; ClassInfo cls = (ClassInfo) ty;
/** /**
la a0, $DoublingVector$prototype # Load pointer to prototype of: DoublingVector la a0, $DoublingVector$prototype # Load pointer to prototype of: DoublingVector
jal alloc # Allocate new object in A0 jal alloc # Allocate new object in A0
@ -289,8 +296,7 @@ public class CodeGenImpl extends CodeGenBase
addi sp, fp, -@..main.size # Set SP to stack frame top. addi sp, fp, -@..main.size # Set SP to stack frame top.
lw a0, -12(fp) # Pop stack slot 3 lw a0, -12(fp) # Pop stack slot 3
*/ */
backend.emitLA(A0, cls.getPrototypeLabel(), backend.emitLA(A0, cls.getPrototypeLabel(), String.format("Load pointer to prototype of: %s", cls.getClassName()));
String.format("Load pointer to prototype of: %s", cls.getClassName()));
backend.emitJAL(objectAllocLabel, "Allocate new object in A0"); backend.emitJAL(objectAllocLabel, "Allocate new object in A0");
backend.emitSW(A0, FP, -sp_off*wordSize, String.format("Push on stack slot %d", sp_off)); backend.emitSW(A0, FP, -sp_off*wordSize, String.format("Push on stack slot %d", sp_off));
incSp(1); incSp(1);
@ -303,16 +309,16 @@ public class CodeGenImpl extends CodeGenBase
backend.emitADDI(SP, FP, "-"+size_label, "Set SP to stack frame top."); backend.emitADDI(SP, FP, "-"+size_label, "Set SP to stack frame top.");
-- sp_off; -- sp_off;
backend.emitLW(A0, FP, -sp_off*wordSize, String.format("Pop stack slot %d", sp_off)); backend.emitLW(A0, FP, -sp_off*wordSize, String.format("Pop stack slot %d", sp_off));
} else { }
// function else
Identifier functionId = node.function; {
FuncInfo calleeFunctionInfo = (FuncInfo) sym.get(node.function.name); // function
boolean isInMainFunction = funcInfo == null; Identifier functionId = node.function;
if (!isInMainFunction) { FuncInfo calleeFunctionInfo = (FuncInfo) sym.get(node.function.name);
System.out.println("--> caller: " + funcInfo.getFuncName() + " depth: " + funcInfo.getDepth()); boolean isInMainFunction = funcInfo == null;
System.out.println("--> callee: " + calleeFunctionInfo.getFuncName() + " depth: " + calleeFunctionInfo.getDepth()); if (!isInMainFunction)
{
int calleeDepth = calleeFunctionInfo.getDepth(); int calleeDepth = calleeFunctionInfo.getDepth();
int callerDepth = funcInfo.getDepth(); int callerDepth = funcInfo.getDepth();
int jumps = callerDepth - calleeDepth + 1; int jumps = callerDepth - calleeDepth + 1;
@ -322,74 +328,81 @@ public class CodeGenImpl extends CodeGenBase
backend.emitMV(tmp, FP, "Load FP"); backend.emitMV(tmp, FP, "Load FP");
FuncInfo curr = funcInfo; FuncInfo curr = funcInfo;
for (int i = 0; i < jumps; i++) { for (int i = 0; i < jumps; i++)
{
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, -(sp_off+1) * wordSize, "Push static link onto active frame.");
freeRegister(tmpHandle); freeRegister(tmpHandle);
} }
else { else
backend.emitSW(FP, FP, -(sp_off+1) * 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); 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); {
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);
expr.dispatch(this); expr.dispatch(this);
String formalParamName = calleeFunctionInfo.getParams().get(i); String formalParamName = calleeFunctionInfo.getParams().get(i);
StackVarInfo formalParamInfo = (StackVarInfo) calleeFunctionInfo.getSymbolTable().get(formalParamName); StackVarInfo formalParamInfo = (StackVarInfo) calleeFunctionInfo.getSymbolTable().get(formalParamName);
if (expr.getInferredType().equals(Type.INT_TYPE)) { if (expr.getInferredType().equals(Type.INT_TYPE))
if ((functionId.name.equals("print")) &&(formalParamInfo.getVarType().equals(Type.OBJECT_TYPE) || formalParamInfo.getVarType().equals(Type.INT_TYPE))) { {
if(!(args.size() == 1 && (args.get(0) instanceof CallExpr) && if ((functionId.name.equals("print")) &&(formalParamInfo.getVarType().equals(Type.OBJECT_TYPE) || formalParamInfo.getVarType().equals(Type.INT_TYPE)))
{
if(!(args.size() == 1 && (args.get(0) instanceof CallExpr) &&
(sym.get(((CallExpr) args.get(0)).function.name) instanceof ClassInfo))) (sym.get(((CallExpr) args.get(0)).function.name) instanceof ClassInfo)))
backend.emitJAL(makeintLabel, "Box integer"); backend.emitJAL(makeintLabel, "Box integer");
} else { }
else
{
// FIXME: passed argument does not match formal parameter // FIXME: passed argument does not match formal parameter
} }
} else if (expr.getInferredType().equals(Type.BOOL_TYPE)) { }
if ((functionId.name.equals("print"))&&(formalParamInfo.getVarType().equals(Type.OBJECT_TYPE) || formalParamInfo.getVarType().equals(Type.BOOL_TYPE))) { else if (expr.getInferredType().equals(Type.BOOL_TYPE))
if(!(args.size() == 1 && (args.get(0) instanceof CallExpr) && {
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))) (sym.get(((CallExpr) args.get(0)).function.name) instanceof ClassInfo)))
backend.emitJAL(makeboolLabel, "Box boolean"); backend.emitJAL(makeboolLabel, "Box boolean");
} }
else { else
{
// FIXME: passed argument does not match formal parameter // FIXME: passed argument does not match formal parameter
} }
} }
// 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
//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.emitSW(A0, FP, -(sp_off) * wordSize, "Push actual argument for " + formalParamName + " onto stack");
} }
//System.out.printf("2: %d",sp_off - spaceRequiredForArgs/wordSize - origsp); //System.out.printf("2: %d",sp_off - spaceRequiredForArgs/wordSize - origsp);
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(calleeFunctionInfo.getCodeLabel(), "Invoke function: " + functionId.name); backend.emitJAL(calleeFunctionInfo.getCodeLabel(), "Invoke function: " + functionId.name);
backend.emitADDI(SP, FP, "-"+size_label, "Set SP to stack frame top."); backend.emitADDI(SP, FP, "-"+size_label, "Set SP to stack frame top.");
sp_off-=spaceRequiredForArgs/wordSize; sp_off-=spaceRequiredForArgs/wordSize;
} }
return A0; return A0;
} }
public Register analyze(MethodCallExpr node) { public Register analyze(MethodCallExpr node)
{
System.out.println("Inside MethodCallExpr: " + node.method.member.name); System.out.println("Inside MethodCallExpr: " + node.method.member.name);
// backend.emitLW(T6, FP, 0, "Inside MethodCallExpr: " + node.method.member.name); Register obj = node.method.object.dispatch(this);
Register obj = node.method.object.dispatch(this);
int n_args = node.args.size(); int n_args = node.args.size();
Label label = generateLocalLabel(); Label label = generateLocalLabel();
@ -422,29 +435,23 @@ public class CodeGenImpl extends CodeGenBase
@Override @Override
public Register analyze(ReturnStmt stmt) { public Register analyze(ReturnStmt stmt)
System.out.println("Inside ReturnStmt: "); {
// backend.emitLW(T6, FP, 0, "Inside ReturnStmt: "); 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"); else
} // All expressions should save their end result in A0
else expr.dispatch(this);
// All expressions should save their end result in A0 backend.emitJ(this.epilogue, "Jump to function epilogue");
expr.dispatch(this);
backend.emitJ(this.epilogue, "Jump to function epilogue");
return A0; return A0;
} }
// *********** functions end *********** // *********** functions end ***********
@Override @Override
public Register analyze(NoneLiteral node) public Register analyze(NoneLiteral node)
{ {
System.out.println("Inside NoneLiteral: ");
// backend.emitLW(T6, FP, 0, "Inside NoneLiteral: ");
backend.emitMV(Register.A0, Register.ZERO, "Load none"); backend.emitMV(Register.A0, Register.ZERO, "Load none");
return Register.A0; return Register.A0;
} }
@ -452,8 +459,6 @@ public class CodeGenImpl extends CodeGenBase
@Override @Override
public Register analyze(StringLiteral node) public Register analyze(StringLiteral node)
{ {
System.out.println("Inside StringLiteral: ");
//backend.emitLW(T6, FP, 0, "Inside StringLiteral: ");
Label l = constants.getStrConstant(node.value); Label l = constants.getStrConstant(node.value);
backend.emitLA(Register.A0, l, "Load string literal"); backend.emitLA(Register.A0, l, "Load string literal");
return Register.A0; return Register.A0;
@ -462,8 +467,6 @@ public class CodeGenImpl extends CodeGenBase
@Override @Override
public Register analyze(BooleanLiteral node) public Register analyze(BooleanLiteral node)
{ {
System.out.println("Inside BooleanLiteral: ");
// backend.emitLW(T6, FP, 0, "Inside BooleanLiteral: ");
if(node.value==true) if(node.value==true)
backend.emitLI(Register.A0, 1, "Load boolean literal: true "); backend.emitLI(Register.A0, 1, "Load boolean literal: true ");
else else
@ -471,7 +474,8 @@ public class CodeGenImpl extends CodeGenBase
return Register.A0; return Register.A0;
} }
class StackVarRuntimeInfo { class StackVarRuntimeInfo
{
public final int off; public final int off;
public final Register sl; public final Register sl;
public int regHandle; public int regHandle;

Loading…
Cancel
Save