Skip to content
Snippets Groups Projects
Verified Commit 37ea8f4f authored by Recolic Keghart's avatar Recolic Keghart
Browse files

Fix function calling logic, not done

parent 4135d07a
No related branches found
No related tags found
No related merge requests found
......@@ -71,6 +71,9 @@ public class CodeGenImpl extends CodeGenBase {
// Return value should be in A0
List<RiscVBackend.Register> savedRegs = new ArrayList<RiscVBackend.Register>() {}; // regMgr.registerToSaveAndRestoreInFunc;
// Function return point:
backend.emitLocalLabel(new Label("$" + funcName + "$exitPoint"), "Function return point");
emitNoop(comment);
backend.emitADDI(SP, FP, -(2 + savedRegs.size()) * backend.getWordSize(), "Revert all local variables on this dying frame.");
for (int i = savedRegs.size(); i-- > 0; ) {
......@@ -87,30 +90,14 @@ public class CodeGenImpl extends CodeGenBase {
backend.emitJ(new Label("$" + funcName + "$saveRegContinue"), "go back to execute real function code.");
}
public void emitPushIntVal(RiscVBackend.Register tmpReg, Integer val, String comment) {
emitNoop(comment);
backend.emitLI(tmpReg, val, "INT VAL");
emitPush(tmpReg, null);
backend.emitLA(tmpReg, intClass.getDispatchTableLabel(), "OBJECT HEAD - DISPATCH TBL");
emitPush(tmpReg, null);
backend.emitLI(tmpReg, 4, "OBJECT HEAD - SIZE = 3+1");
emitPush(tmpReg, null);
backend.emitLI(tmpReg, 1, "OBJECT HEAD - TYPE = INT");
emitPush(tmpReg, null);
backend.emitMV(tmpReg, SP, "Return INT address.");
public void emitFunctionReturn(String funcName, String comment) {
backend.emitJ(new Label("$" + funcName + "$exitPoint"), comment);
}
public void emitPushBoolVal(RiscVBackend.Register tmpReg, Boolean val, String comment) {
emitNoop(comment);
backend.emitLI(tmpReg, val ? 1 : 0, "BOOL VAL");
emitPush(tmpReg, null);
backend.emitLA(tmpReg, boolClass.getDispatchTableLabel(), "OBJECT HEAD - DISPATCH TBL");
emitPush(tmpReg, null);
backend.emitLI(tmpReg, 4, "OBJECT HEAD - SIZE = 3+1");
emitPush(tmpReg, null);
backend.emitLI(tmpReg, 2, "OBJECT HEAD - TYPE = BOOL");
emitPush(tmpReg, null);
backend.emitMV(tmpReg, SP, "Return BOOL address.");
public void emitWrapIntValToIntObject(RiscVBackend.Register tmpReg, SymbolType typeIntOrBool) {
emitPop(tmpReg, "INT VAL TO INT OBJ: POP");
emitAllocPrototype(typeIntOrBool, tmpReg);
emitPush(A0, "INT VAL TO INT OBJ: PUSH");
}
public void emitPushStrVal(RiscVBackend.Register tmpReg, String val, String comment) {
......@@ -143,6 +130,30 @@ public class CodeGenImpl extends CodeGenBase {
emitPush(tmpReg, null);
backend.emitMV(tmpReg, SP, "Return STR OBJ address.");
}
private Void emitAllocPrototype(SymbolType typ, RiscVBackend.Register objReg) {
// Convention: if typ is INT_TYPE or BOOL_TYPE then objReg contains the literal value, not a pointer.
// @returns A0
if (typ.equals(SymbolType.INT_TYPE)) {
backend.emitLA(A0, intClass.getPrototypeLabel(), "Load prototype address");
// save our objReg on stack before `alloc`
backend.emitADDI(SP, SP, -4, "Decrement stack ptr 1");
backend.emitSW(objReg, SP, 0, "Store the literal value");
backend.emitJAL(objectAllocLabel, "Allocate int");
backend.emitLW(objReg, SP, 0, "Load literal value again");
backend.emitADDI(SP, SP, 4, "Increment stack ptr 1");
backend.emitSW(objReg, A0, 3 * backend.getWordSize(), "Set __int__ value");
} else if (typ.equals(SymbolType.STR_TYPE)) {
// objReg already has a ptr in this case. just move to A0.
backend.emitMV(A0, objReg, "move string ptr to A0");
} else if (typ.equals(SymbolType.BOOL_TYPE)){
backend.emitLA(A0, constants.getBoolConstant(false), "Load FALSE bool");
backend.emitSLLI(objReg, objReg, 4, "Compute offset to correct object");
backend.emitADD(A0, A0, objReg, "Add offset to curr pointer");
}
return null;
}
}
......@@ -201,23 +212,15 @@ public class CodeGenImpl extends CodeGenBase {
backend.emitGlobalLabel(funcInfo.getCodeLabel());
StmtAnalyzer stmtAnalyzer = new StmtAnalyzer(funcInfo);
// Prologue:
backend.emitSW(FP, SP, 0, "Save old FP");
backend.emitSW(RA, SP, -4, "Save RA");
backend.emitADDI(SP, SP, -8, "Increment stack pointer 2 places");
backend.emitADDI(FP, SP, 4, "FP is one slot below top of stack");
betterBackend.emitFunctionBegin(funcInfo.getFuncName(), null);
// Emit code for function stmts
for (Stmt stmt : funcInfo.getStatements()) {
stmt.dispatch(stmtAnalyzer);
}
backend.emitMV(A0, ZERO, "Returning None implicitly");
backend.emitLocalLabel(stmtAnalyzer.epilogue, "Epilogue");
// FIXME: {... reset fp etc. ...}
backend.emitLW(RA, FP, 0, "Restore RA");
backend.emitLW(FP, FP, 4, "Restore old FP");
backend.emitJR(RA, "Return to caller");
betterBackend.emitFunctionEnd(funcInfo.getFuncName(), null, null);
}
/** An analyzer that encapsulates code generation for statments. */
......@@ -265,28 +268,6 @@ public class CodeGenImpl extends CodeGenBase {
private int _r_local_label_counter = 427;
private Void allocPrototype(SymbolType typ, RiscVBackend.Register objReg) {
// Convention: if typ is INT_TYPE or BOOL_TYPE then objReg contains the literal value, not a pointer.
if (typ.equals(SymbolType.INT_TYPE)) {
backend.emitLA(A0, intClass.getPrototypeLabel(), "Load prototype address");
// save our objReg on stack before `alloc`
backend.emitADDI(SP, SP, -4, "Decrement stack ptr 1");
backend.emitSW(objReg, SP, 0, "Store the literal value");
backend.emitJAL(objectAllocLabel, "Allocate int");
backend.emitLW(objReg, SP, 0, "Load literal value again");
backend.emitADDI(SP, SP, 4, "Increment stack ptr 1");
backend.emitSW(objReg, A0, 3 * backend.getWordSize(), "Set __int__ value");
} else if (typ.equals(SymbolType.STR_TYPE)) {
// objReg already has a ptr in this case. just move to A0.
backend.emitMV(A0, objReg, "move string ptr to A0");
} else if (typ.equals(SymbolType.BOOL_TYPE)){
backend.emitLA(A0, constants.getBoolConstant(false), "Load FALSE bool");
backend.emitSLLI(objReg, objReg, 4, "Compute offset to correct object");
backend.emitADD(A0, A0, objReg, "Add offset to curr pointer");
}
return null;
}
/** An analyzer for the function described by FUNCINFO0, which is null
* for the top level. */
StmtAnalyzer(FuncInfo funcInfo0) {
......@@ -299,14 +280,6 @@ public class CodeGenImpl extends CodeGenBase {
epilogue = generateLocalLabel();
}
// FIXME: Example of statement.
@Override
public Void analyze(ReturnStmt stmt) {
stmt.value.dispatch(this);
backend.emitLW(A0, SP, 0, "Load return value into A0");
return null;
}
@Override
public Void analyze(ExprStmt exprStmt) {
exprStmt.expr.dispatch(this);
......@@ -415,30 +388,43 @@ public class CodeGenImpl extends CodeGenBase {
return null;
}
@Override
public Void analyze(ReturnStmt node) {
node.value.dispatch(this);
betterBackend.emitPop(A0, "ReturnStmt: Get value");
betterBackend.emitFunctionReturn(this.funcInfo.getFuncName(), "ReturnStmt: GO");
return null;
}
@Override
public Void analyze(CallExpr callExpr) {
// NOT DONE
if (globalSymbols.get(callExpr.function.name) instanceof FuncInfo) {
FuncInfo func = (FuncInfo) globalSymbols.get(callExpr.function.name);
for (Expr e : callExpr.args) {
backend.emitADDI(SP, SP, -4, "Increment stack ptr by 1");
e.dispatch(this);
}
// Push parameters onto stack
if (func.getFuncName().equals("print")) {
backend.emitLW(T0, SP, 0, "Load param for boxing");
allocPrototype(callExpr.args.get(0).getInferredType(), T0);
// after this A0 should contain address of newly allocated object
backend.emitSW(A0, SP, 0, "put boxed argument back on stack");
public Void analyze(CallExpr node) {
SymbolInfo called = sym.get(node.function.name);
if (called instanceof FuncInfo) {
FuncInfo func = (FuncInfo) called;
// TODO: Push the FUCKING arg0 (outter function frame ptr)
for (Expr expr : node.args) {
expr.dispatch(this);
// WARNING: ALL EXPR SHOULD NEVER EDIT STACK POINTER
// THE EXPR PUSH ITS RETURN VAL TO STACK, AS FUNCTION ARG
if(func.getFuncName().equals("print")) {
// FUCKING SILLY FUCKING NOOB IDOLT FUNCTION PRINT.
if(expr.getInferredType().equals(SymbolType.INT_TYPE) || expr.getInferredType().equals(SymbolType.BOOL_TYPE))
betterBackend.emitWrapIntValToIntObject(T6, expr.getInferredType());
}
}
backend.emitJAL(func.getCodeLabel(), "Invoke function");
// Restore SP
for (Expr e : callExpr.args) {
backend.emitADDI(SP, SP, 4, "Decrement stack ptr by 1");
}
betterBackend.emitCall(func.getCodeLabel(), null);
for (Object arg : node.args)
betterBackend.emitPop(null, "Pop function arguments.");
betterBackend.emitPush(A0, "CallExpr: Push function return val");
return null;
} else if (called instanceof ClassInfo) {
// TODO: Fuck the fucking framework.
}
return null;
}
......@@ -447,21 +433,21 @@ public class CodeGenImpl extends CodeGenBase {
public Void analyze(BooleanLiteral literal) {
/* Push boolean literal onto stack, incrementing stack pointer*/
backend.emitLI(A0, (literal.value == true) ? 1 : 0, "Load boolean literal into a0");
backend.emitSW(A0, SP, 0, "Push on stack");
betterBackend.emitPush(A0, "Push literal onto stack");
return null;
}
@Override
public Void analyze(IntegerLiteral literal) {
backend.emitLI(A0, literal.value, "Load integer literal into a0");
backend.emitSW(A0, SP, 0, "Push on stack");
betterBackend.emitPush(A0, "Push literal onto stack");
return null;
}
@Override
public Void analyze(StringLiteral literal) {
backend.emitLA(A0, constants.getStrConstant(literal.value), "Load string addr into a0");
backend.emitSW(A0, SP, 0, "Push on stack");
betterBackend.emitPush(A0, "Push literal onto stack");
return null;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment