|
|
@ -2,12 +2,12 @@ package chocopy.pa3;
|
|
|
|
|
|
|
|
|
|
|
|
import chocopy.common.analysis.AbstractNodeAnalyzer;
|
|
|
|
import chocopy.common.analysis.AbstractNodeAnalyzer;
|
|
|
|
import chocopy.common.analysis.SymbolTable;
|
|
|
|
import chocopy.common.analysis.SymbolTable;
|
|
|
|
import chocopy.common.analysis.types.FuncType;
|
|
|
|
|
|
|
|
import chocopy.common.analysis.types.Type;
|
|
|
|
|
|
|
|
import chocopy.common.astnodes.*;
|
|
|
|
import chocopy.common.astnodes.*;
|
|
|
|
import chocopy.common.codegen.*;
|
|
|
|
import chocopy.common.codegen.*;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
|
|
import chocopy.common.codegen.RiscVBackend.Register;
|
|
|
|
import chocopy.common.codegen.RiscVBackend.Register;
|
|
|
|
import static chocopy.common.codegen.RiscVBackend.Register.*;
|
|
|
|
import static chocopy.common.codegen.RiscVBackend.Register.*;
|
|
|
@ -128,6 +128,9 @@ public class CodeGenImpl extends CodeGenBase {
|
|
|
|
private final FuncInfo funcInfo;
|
|
|
|
private final FuncInfo funcInfo;
|
|
|
|
private final String size_label;
|
|
|
|
private final String size_label;
|
|
|
|
private int sp_off, max_sp;
|
|
|
|
private int sp_off, max_sp;
|
|
|
|
|
|
|
|
protected Label elseBlock;
|
|
|
|
|
|
|
|
/** Variable to store offset from frame pointer to identify next
|
|
|
|
|
|
|
|
* empty space on stack frame to store variable*/
|
|
|
|
|
|
|
|
|
|
|
|
/** An analyzer for the function described by FUNCINFO0, which is null for the top level. */
|
|
|
|
/** An analyzer for the function described by FUNCINFO0, which is null for the top level. */
|
|
|
|
StmtAnalyzer(FuncInfo funcInfo0) {
|
|
|
|
StmtAnalyzer(FuncInfo funcInfo0) {
|
|
|
@ -143,7 +146,10 @@ public class CodeGenImpl extends CodeGenBase {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
epilogue = generateLocalLabel();
|
|
|
|
epilogue = generateLocalLabel();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void incSp(int i){
|
|
|
|
|
|
|
|
sp_off+=i+1;
|
|
|
|
|
|
|
|
max_sp = max_sp >= sp_off?max_sp:sp_off;
|
|
|
|
|
|
|
|
}
|
|
|
|
public Register analyze(AssignStmt node) {
|
|
|
|
public Register analyze(AssignStmt node) {
|
|
|
|
return null;
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -177,16 +183,15 @@ public class CodeGenImpl extends CodeGenBase {
|
|
|
|
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));
|
|
|
|
if(sp_off>max_sp)
|
|
|
|
incSp(0);
|
|
|
|
max_sp = sp_off;
|
|
|
|
|
|
|
|
sp_off++;
|
|
|
|
|
|
|
|
backend.emitSW(A0, FP, -sp_off*wordSize, "Push argument 0 from last.");
|
|
|
|
backend.emitSW(A0, FP, -sp_off*wordSize, "Push argument 0 from last.");
|
|
|
|
backend.emitADDI(SP, FP, sp_off, "Set SP to last argument.");
|
|
|
|
backend.emitADDI(SP, FP, sp_off, "Set SP to last argument.");
|
|
|
|
backend.emitLW(A1, A0, getDispatchTableOffset(), "Load address of object's dispatch table");
|
|
|
|
backend.emitLW(A1, A0, getDispatchTableOffset(), "Load address of object's dispatch table");
|
|
|
|
backend.emitLW(A1, A1, getMethodOffset(cls, "__init__"), String.format("Load address of method: %s.__init__", cls.getClassName()));
|
|
|
|
backend.emitLW(A1, A1, getMethodOffset(cls, "__init__"), String.format("Load address of method: %s.__init__", cls.getClassName()));
|
|
|
|
backend.emitJALR(A1, String.format("Invoke method: %s.__init", cls.getClassName()));
|
|
|
|
backend.emitJALR(A1, String.format("Invoke method: %s.__init", cls.getClassName()));
|
|
|
|
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 {
|
|
|
|
} else {
|
|
|
|
//func call
|
|
|
|
//func call
|
|
|
@ -248,9 +253,7 @@ public class CodeGenImpl extends CodeGenBase {
|
|
|
|
backend.emitBNEZ(obj, label, "Ensure not None");
|
|
|
|
backend.emitBNEZ(obj, label, "Ensure not None");
|
|
|
|
backend.emitJ(errorNone, "Go to error handler");
|
|
|
|
backend.emitJ(errorNone, "Go to error handler");
|
|
|
|
backend.emitLocalLabel(label, "Not None");
|
|
|
|
backend.emitLocalLabel(label, "Not None");
|
|
|
|
if(sp_off>max_sp)
|
|
|
|
incSp(n_args+1);
|
|
|
|
max_sp = sp_off;
|
|
|
|
|
|
|
|
sp_off += (n_args+1)*wordSize;
|
|
|
|
|
|
|
|
backend.emitSW(obj, FP, (n_args - sp_off) *wordSize, String.format("Push argument %d from last.", n_args));
|
|
|
|
backend.emitSW(obj, FP, (n_args - sp_off) *wordSize, String.format("Push argument %d from last.", n_args));
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < n_args; ++i)
|
|
|
|
for (int i = 0; i < n_args; ++i)
|
|
|
@ -266,7 +269,7 @@ public class CodeGenImpl extends CodeGenBase {
|
|
|
|
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.emitJALR(A1, String.format("Invoke method: %s.%s", objectClass.getClassName(), node.method.member.name));
|
|
|
|
backend.emitJALR(A1, String.format("Invoke method: %s.%s", objectClass.getClassName(), node.method.member.name));
|
|
|
|
backend.emitInsn(String.format("addi sp, fp, -%s", size_label), "Set SP to stack frame top.");
|
|
|
|
backend.emitInsn(String.format("addi sp, fp, -%s", size_label), "Set SP to stack frame top.");
|
|
|
|
sp_off -= (n_args+1)*wordSize;
|
|
|
|
sp_off -= n_args+1;
|
|
|
|
|
|
|
|
|
|
|
|
return A0;
|
|
|
|
return A0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|