Index Expr, register pool, changed incSp

master
bill 3 years ago
parent 3c4eeb2fdc
commit a86d93fcac

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

@ -5,14 +5,13 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import chocopy.common.analysis.AbstractNodeAnalyzer; import chocopy.common.analysis.*;
import chocopy.common.analysis.SymbolTable;
import chocopy.common.astnodes.*; import chocopy.common.astnodes.*;
import chocopy.common.analysis.types.*; import chocopy.common.analysis.types.*;
import chocopy.common.codegen.*; import chocopy.common.codegen.*;
import static chocopy.common.codegen.RiscVBackend.Register.*;
import 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; private int sp_off;
/** Variable to store maximum possible offset depending on stack size.*/ /** Variable to store maximum possible offset depending on stack size.*/
private int max_sp; 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 * An analyzer for the function described by FUNCINFO0, which is null for the
* top level. * top level.
@ -226,7 +237,7 @@ public class CodeGenImpl extends CodeGenBase
epilogue = generateLocalLabel(); epilogue = generateLocalLabel();
} }
private void incSp(int i){ private void incSp(int i){
sp_off+=i+1; sp_off+=i;
max_sp = max_sp >= sp_off?max_sp:sp_off; 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())); 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(0); incSp(1);
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.");
@ -687,7 +698,7 @@ public class CodeGenImpl extends CodeGenBase
backend.emitSEQZ(Register.T0, Register.A0, "Not operation on Register A0"); backend.emitSEQZ(Register.T0, Register.A0, "Not operation on Register A0");
} }
else else
return null; System.err.println("return null!");
return Register.A0; return Register.A0;
} }
@ -789,35 +800,60 @@ public class CodeGenImpl extends CodeGenBase
} }
@Override @Override
public Register analyze(IndexExpr node) public Register analyze(IndexExpr node)
{ {
// incSp(1); incSp(1);
// Register listObj = node.list.dispatch(this); Register listObj = node.list.dispatch(this);
// backend.emitSW(listObj, FP, -sp_off * wordSize, String.format("Push on stack slot %d", sp_off)); backend.emitSW(listObj, FP, -sp_off * wordSize, String.format("Push on stack slot %d", sp_off));
// Register index = node.index.dispatch(this); Register index = node.index.dispatch(this);
// Register vacantReg = (index != A0) ? A0 : A1; Register vacantReg = (index != A0) ? A0 : A1;
// int tmpHandle = getRegister();
// if (node.list.getInferredType().isListType()) { Register temp= registerPool[tmpHandle];
// backend.emitLW(vacantReg, FP, -sp_off * wordSize, String.format("Pop stack slot %d", sp_off));
// if (node.list.getInferredType().isListType()) {
// this.d(vacantReg); backend.emitLW(vacantReg, FP, -sp_off * wordSize, String.format("Pop stack slot %d", sp_off));
// return this.a(vacantReg, index, A0, false); final Label bp = generateLocalLabel();
// }else{ backend.emitBNEZ(listObj, bp, "Ensure not None");
// this.a(0, vacantReg); backend.emitJ(errorNone, "Go to error handler");
// Register a = a(index); backend.emitLocalLabel(bp, "Not None");
// Label ch = generateLocalLabel(); final Label bt = generateLocalLabel();
// backend.emitLW(a, vacantReg, getAttrOffset(strClass, "__len__"), "Load attribute: __len__"); backend.emitLW(temp, listObj, getAttrOffset(listClass, "__len__"), "Load attribute: __len__");
// backend.emitBLTU(index, a, ch, "Ensure 0 <= idx < len"); backend.emitBLTU(index, temp, bt, "Ensure 0 <= index < len");
// backend.emitJ(f, "Go to error handler"); backend.emitJ(errorOob, "Go to error handler");
// backend.emitLocalLabel(ch, "Index within bounds"); backend.emitLocalLabel(bt, "Index within bounds");
// this.c(index); backend.emitADDI(index, index, 4, "Compute list element offset in words");
// Register a2 = this.a(false); backend.emitLI(temp, wordSize, "Word size in bytes");
// this.a(1); backend.emitMUL(index, index, temp, "Compute list element offset in bytes");
// return a2; backend.emitADD(index, listObj, index, "Pointer to list element");
// } backend.emitLW(vacantReg, index, 0, "Set list element");
return null; } 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) public Register analyze(MemberExpr node)
{ {

Loading…
Cancel
Save