From a86d93fcac34548d26bb1215c9ec1df7ca1e2538 Mon Sep 17 00:00:00 2001 From: bill Date: Mon, 3 May 2021 15:22:05 +0800 Subject: [PATCH] Index Expr, register pool, changed incSp --- .vscode/launch.json | 4 +- src/main/java/chocopy/pa3/CodeGenImpl.java | 106 ++++++++++++++------- 2 files changed, 73 insertions(+), 37 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 53608f3..40395d9 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -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": [] } ] diff --git a/src/main/java/chocopy/pa3/CodeGenImpl.java b/src/main/java/chocopy/pa3/CodeGenImpl.java index 939b9f0..4cd9c6f 100644 --- a/src/main/java/chocopy/pa3/CodeGenImpl.java +++ b/src/main/java/chocopy/pa3/CodeGenImpl.java @@ -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) {