Index Expr, register pool, changed incSp

master
bill 3 years ago
parent 3c4eeb2fdc
commit a86d93fcac

@ -12,8 +12,8 @@
"request": "launch",
"classPaths": ["chocopy-ref.jar:target/assignment.jar"],
"mainClass": "chocopy.ChocoPy",
//"args": [ "--pass=rrs", "--test","--dir", "src/test/data/pa3/sample/list_set_element_oob_1.py"],
"args": [ "--pass=rrs", "--test","--dir", "test.py"],
"args": [ "--pass=rrs", "--test","--dir", "src/test/data/pa3/sample/stmt_return_early.py"],
//"args": [ "--pass=rrs", "--test","--dir", "test.py"],
"sourcePaths": []
}
]

@ -5,14 +5,13 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import chocopy.common.analysis.AbstractNodeAnalyzer;
import chocopy.common.analysis.SymbolTable;
import chocopy.common.analysis.*;
import chocopy.common.astnodes.*;
import chocopy.common.analysis.types.*;
import chocopy.common.codegen.*;
import static chocopy.common.codegen.RiscVBackend.Register.*;
import chocopy.common.codegen.RiscVBackend.Register;
import static chocopy.common.codegen.RiscVBackend.Register.*;
/**
@ -207,7 +206,19 @@ public class CodeGenImpl extends CodeGenBase
private int sp_off;
/** Variable to store maximum possible offset depending on stack size.*/
private int max_sp;
private final Register[] registerPool = {T2,T3, T4, T5, T6, A2, A3, A4, A5, A6};
private final boolean[] registerAvilMap = {true, true, true, true, true, true, true, true, true, true};
private int getRegister(){ //return a handle of a vacant reg
for(int i = 0; i < 10; ++i)
if(registerAvilMap[i])
return i;
for(int i = 0; i < 10; ++i)
registerAvilMap[i] = true; //freeall;
return 0;
}
private void freeRegister(int handle){ //handle used to free the reg
registerAvilMap[handle] = false;
}
/**
* An analyzer for the function described by FUNCINFO0, which is null for the
* top level.
@ -226,7 +237,7 @@ public class CodeGenImpl extends CodeGenBase
epilogue = generateLocalLabel();
}
private void incSp(int i){
sp_off+=i+1;
sp_off+=i;
max_sp = max_sp >= sp_off?max_sp:sp_off;
}
@ -257,7 +268,7 @@ public class CodeGenImpl extends CodeGenBase
String.format("Load pointer to prototype of: %s", cls.getClassName()));
backend.emitJAL(objectAllocLabel, "Allocate new object in A0");
backend.emitSW(A0, FP, -sp_off*wordSize, String.format("Push on stack slot %d", sp_off));
incSp(0);
incSp(1);
backend.emitSW(A0, FP, -sp_off*wordSize, "Push argument 0 from last.");
backend.emitADDI(SP, FP, sp_off, "Set SP to last argument.");
@ -687,7 +698,7 @@ public class CodeGenImpl extends CodeGenBase
backend.emitSEQZ(Register.T0, Register.A0, "Not operation on Register A0");
}
else
return null;
System.err.println("return null!");
return Register.A0;
}
@ -789,35 +800,60 @@ public class CodeGenImpl extends CodeGenBase
}
@Override
public Register analyze(IndexExpr node)
{
// incSp(1);
// Register listObj = node.list.dispatch(this);
// backend.emitSW(listObj, FP, -sp_off * wordSize, String.format("Push on stack slot %d", sp_off));
// Register index = node.index.dispatch(this);
// Register vacantReg = (index != A0) ? A0 : A1;
//
// if (node.list.getInferredType().isListType()) {
// backend.emitLW(vacantReg, FP, -sp_off * wordSize, String.format("Pop stack slot %d", sp_off));
//
// this.d(vacantReg);
// return this.a(vacantReg, index, A0, false);
// }else{
// this.a(0, vacantReg);
// Register a = a(index);
// Label ch = generateLocalLabel();
// backend.emitLW(a, vacantReg, getAttrOffset(strClass, "__len__"), "Load attribute: __len__");
// backend.emitBLTU(index, a, ch, "Ensure 0 <= idx < len");
// backend.emitJ(f, "Go to error handler");
// backend.emitLocalLabel(ch, "Index within bounds");
// this.c(index);
// Register a2 = this.a(false);
// this.a(1);
// return a2;
// }
return null;
@Override
public Register analyze(IndexExpr node)
{
incSp(1);
Register listObj = node.list.dispatch(this);
backend.emitSW(listObj, FP, -sp_off * wordSize, String.format("Push on stack slot %d", sp_off));
Register index = node.index.dispatch(this);
Register vacantReg = (index != A0) ? A0 : A1;
int tmpHandle = getRegister();
Register temp= registerPool[tmpHandle];
if (node.list.getInferredType().isListType()) {
backend.emitLW(vacantReg, FP, -sp_off * wordSize, String.format("Pop stack slot %d", sp_off));
final Label bp = generateLocalLabel();
backend.emitBNEZ(listObj, bp, "Ensure not None");
backend.emitJ(errorNone, "Go to error handler");
backend.emitLocalLabel(bp, "Not None");
final Label bt = generateLocalLabel();
backend.emitLW(temp, listObj, getAttrOffset(listClass, "__len__"), "Load attribute: __len__");
backend.emitBLTU(index, temp, bt, "Ensure 0 <= index < len");
backend.emitJ(errorOob, "Go to error handler");
backend.emitLocalLabel(bt, "Index within bounds");
backend.emitADDI(index, index, 4, "Compute list element offset in words");
backend.emitLI(temp, wordSize, "Word size in bytes");
backend.emitMUL(index, index, temp, "Compute list element offset in bytes");
backend.emitADD(index, listObj, index, "Pointer to list element");
backend.emitLW(vacantReg, index, 0, "Set list element");
} else {
backend.emitLW(vacantReg, FP, - sp_off * wordSize, String.format("Peek stack slot %d", sp_off- 1));
Label boundchk = generateLocalLabel();
backend.emitLW(temp, vacantReg, getAttrOffset(strClass, "__len__"), "Load attribute: __len__");
backend.emitBLTU(index, temp, boundchk, "Ensure 0 <= idx < len");
backend.emitJ(errorOob, "Go to error handler");
backend.emitLocalLabel(boundchk, "Index within bounds");
incSp(1);
backend.emitSW(index, RiscVBackend.Register.FP, -sp_off * wordSize, String.format("Push on stack slot %d",sp_off));
getAttrOffset(strClass, "__len__");
backend.emitLW(T0, FP, -sp_off * wordSize, String.format("Pop stack slot %d", sp_off));
--sp_off;
backend.emitSW(A1, FP, -sp_off*wordSize, String.format("Push Argument %d", sp_off));
backend.emitADDI(T0, T0, 4 * wordSize, "Convert index to offset to char in bytes");
backend.emitLBU(T0, T0, 0, "Load character");
backend.emitLA(vacantReg, strClass.getPrototypeLabel(), "Create Str for char");
backend.emitJAL(objectAllocLabel, "Alloc char");
backend.emitLI(T1, 1, "str size");
backend.emitSW(T1, vacantReg, 3*wordSize, "len");
backend.emitSW(T0, vacantReg, 4*wordSize, "ch");
}
freeRegister(tmpHandle);
-- sp_off;
return vacantReg;
}
public Register analyze(MemberExpr node)
{

Loading…
Cancel
Save