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

list + list passed

parent 4868efb3
No related branches found
No related tags found
No related merge requests found
Pipeline #495 passed with warnings with stages
in 12 minutes and 6 seconds
...@@ -712,67 +712,80 @@ public class CodeGenImpl extends CodeGenBase { ...@@ -712,67 +712,80 @@ public class CodeGenImpl extends CodeGenBase {
return null; return null;
} }
private RiscVBackend.Register emitStringAdd(RiscVBackend.Register left_const, RiscVBackend.Register right_const) { private void __rlib_emitStringLengthToWords(RiscVBackend.Register tmpReg) {
/* Assume already using: T5, T6 */ // I should do `tmp1 = ceil(tmp1 / WORD_SIZE)`
backend.emitADDI(tmpReg, tmpReg, backend.getWordSize() - 1, "STR ADD: tmp1 = ceil(tmp1 / WORD_SIZE)");
assert backend.getWordSize() == 4; // the following stmt requires it.
backend.emitSRAI(tmpReg, tmpReg, 2, "STR ADD: tmp1 = ceil(tmp1 / WORD_SIZE)");
}
private RiscVBackend.Register emitStringAdd(RiscVBackend.Register left_const, RiscVBackend.Register right_const, boolean isStringElseList) {
/* Assume already using: T5, T6 */ // isStringElseList: true for string, false for list.
String prefix = isStringElseList ? "STR ADD: " : "LIST ADD: ";
// Check for None
backend.emitBEQZ(left_const, errorNone, prefix + "Exception: NullPointerException left");
backend.emitBEQZ(right_const, errorNone, prefix + "Exception: NullPointerException right");
// Prepare new object
RiscVBackend.Register tmp1 = T4, tmp2 = A5; RiscVBackend.Register tmp1 = T4, tmp2 = A5;
backend.emitLW(tmp1, left_const, 3*backend.getWordSize(), "STR ADD: get left len"); backend.emitLW(tmp1, left_const, 3*backend.getWordSize(), prefix + "get left len");
backend.emitLW(tmp2, right_const, 3*backend.getWordSize(), "STR ADD: get right len"); backend.emitLW(tmp2, right_const, 3*backend.getWordSize(), prefix + "get right len");
backend.emitADD(tmp1, tmp1, tmp2, "STR ADD: get lenLeft + lenRight"); backend.emitADD(tmp1, tmp1, tmp2, prefix + "get lenLeft + lenRight");
backend.emitMV(tmp2, tmp1, "STR ADD: backup previous result"); backend.emitMV(tmp2, tmp1, prefix + "backup previous result");
// I should do `tmp1 = ceil(tmp1 / WORD_SIZE)` if(isStringElseList)
backend.emitADDI(tmp1, tmp1, backend.getWordSize() - 1, "STR ADD: tmp1 = ceil(tmp1 / WORD_SIZE)"); __rlib_emitStringLengthToWords(tmp1);
assert backend.getWordSize() == 4; // the following stmt requires it.
backend.emitSRAI(tmp1, tmp1, 2, "STR ADD: tmp1 = ceil(tmp1 / WORD_SIZE)");
// tmp1 is new string object size in word. // tmp1 is new string object size in word.
backend.emitADDI(tmp1, tmp1, 4, "STR ADD: Calc len: Add header size."); backend.emitADDI(tmp1, tmp1, 4, prefix + "Calc len: Add header size.");
backend.emitADDI(tmp1, tmp1, 1, "STR ADD: BUG WORKAROUND: Off-by-1 bug. just alloc one more byte"); if(isStringElseList)
backend.emitADDI(tmp1, tmp1, 1, prefix + "STR BUG WORKAROUND: Off-by-1 bug. just alloc one more byte");
// There should be some buffer-overflow for string! Don't worry, I alloc one more byte to contain junks!!!
// alloc new string // alloc new string
betterBackend.emitAllocPrototype(SymbolType.STR_TYPE, tmp1); // @returns A0 betterBackend.emitAllocPrototype(SymbolType.STR_TYPE, tmp1); // @returns A0
backend.emitSW(tmp2, A0, 3 * backend.getWordSize(), "STR ADD: Set new string len"); backend.emitSW(tmp2, A0, 3 * backend.getWordSize(), prefix + "Set new string len");
///////// tmp1 tmp2 die here. ///////// tmp1 tmp2 die here.
RiscVBackend.Register tmpNewStrDataPtr = A7, tmpOldStrDataPtr = A6; RiscVBackend.Register tmpNewStrDataPtr = A7, tmpOldStrDataPtr = A6;
// calc left string words to copy // calc left string words to copy
backend.emitLW(tmp1, left_const, 3*backend.getWordSize(), "STR ADD: leftStr.len"); backend.emitLW(tmp1, left_const, 3*backend.getWordSize(), prefix + "leftStr.len");
// I should do `tmp1 = ceil(tmp1 / WORD_SIZE)` if(isStringElseList)
backend.emitADDI(tmp1, tmp1, backend.getWordSize() - 1, "STR ADD: tmp1 = ceil(tmp1 / WORD_SIZE)"); __rlib_emitStringLengthToWords(tmp1);
// There should be some buffer-overflow! Don't worry, I alloc one more byte to contain junks!!!
backend.emitSRAI(tmp1, tmp1, 2, "STR ADD: tmp1 = ceil(tmp1 / WORD_SIZE)");
// Copy left string to dest. // Copy left string to dest.
backend.emitADDI(tmpNewStrDataPtr, A0, 4*backend.getWordSize(), "STR ADD: newStr.data"); backend.emitADDI(tmpNewStrDataPtr, A0, 4*backend.getWordSize(), prefix + "newStr.data");
backend.emitADDI(tmpOldStrDataPtr, left_const, 4*backend.getWordSize(), "STR ADD: leftStr.data"); backend.emitADDI(tmpOldStrDataPtr, left_const, 4*backend.getWordSize(), prefix + "leftStr.data");
betterBackend.emitMemcpy(tmpNewStrDataPtr, tmpOldStrDataPtr, tmp1, tmp2, getLabelPrefix()); betterBackend.emitMemcpy(tmpNewStrDataPtr, tmpOldStrDataPtr, tmp1, tmp2, getLabelPrefix());
// calc right string words to copy // calc right string words to copy
backend.emitLW(tmp1, right_const, 3*backend.getWordSize(), "STR ADD: rightStr.len"); backend.emitLW(tmp1, right_const, 3*backend.getWordSize(), prefix + "rightStr.len");
// I should do `tmp1 = ceil(tmp1 / WORD_SIZE)` if(isStringElseList)
backend.emitADDI(tmp1, tmp1, backend.getWordSize() - 1, "STR ADD: tmp1 = ceil(tmp1 / WORD_SIZE)"); __rlib_emitStringLengthToWords(tmp1);
backend.emitSRAI(tmp1, tmp1, 2, "STR ADD: tmp1 = ceil(tmp1 / WORD_SIZE)");
// Calc memcpy arg: dstPtr. // Calc memcpy arg: dstPtr.
backend.emitLW(tmp2, left_const, 3*backend.getWordSize(), "STR ADD: leftStr.len"); backend.emitLW(tmp2, left_const, 3*backend.getWordSize(), prefix + "leftStr.len");
backend.emitADDI(tmpNewStrDataPtr, A0, 4*backend.getWordSize(), "STR ADD: newStr.data"); if(!isStringElseList) // for list: should add WORD_SIZE*leftStr.len
backend.emitADD(tmpNewStrDataPtr, tmpNewStrDataPtr, tmp2, "STR ADD: &newStr.data + leftStr.len"); backend.emitSLLI(tmp2, tmp2, 2, prefix + "leftStr.len *= 4 for list.");
backend.emitADDI(tmpNewStrDataPtr, A0, 4*backend.getWordSize(), prefix + "newStr.data");
backend.emitADD(tmpNewStrDataPtr, tmpNewStrDataPtr, tmp2, prefix + "&newStr.data + leftStr.len");
// Copy right string to dest. // Copy right string to dest.
backend.emitADDI(tmpOldStrDataPtr, right_const, 4*backend.getWordSize(), "STR ADD: rightStr.data"); backend.emitADDI(tmpOldStrDataPtr, right_const, 4*backend.getWordSize(), prefix + "rightStr.data");
betterBackend.emitMemcpy(tmpNewStrDataPtr, tmpOldStrDataPtr, tmp1, tmp2, getLabelPrefix()); betterBackend.emitMemcpy(tmpNewStrDataPtr, tmpOldStrDataPtr, tmp1, tmp2, getLabelPrefix());
// There should be some buffer-overflow! Don't worry, I alloc one more byte to contain junks!!! // There should be some buffer-overflow for string! Don't worry, I alloc one more byte to contain junks!!!
return A0; return A0;
} }
@Override @Override
public Void analyze(BinaryExpr binaryExpr) { public Void analyze(BinaryExpr binaryExpr) {
SymbolType leftType = binaryExpr.left.getInferredType();
switch (binaryExpr.operator) { switch (binaryExpr.operator) {
case "+": case "+":
if (binaryExpr.left.getInferredType().equals(SymbolType.INT_TYPE)) { if (leftType.equals(SymbolType.INT_TYPE)) {
binaryExpr.left.dispatch(this); binaryExpr.left.dispatch(this);
binaryExpr.right.dispatch(this); binaryExpr.right.dispatch(this);
betterBackend.emitPop(T0, "Load operand 2 into t0"); betterBackend.emitPop(T0, "Load operand 2 into t0");
...@@ -782,14 +795,14 @@ public class CodeGenImpl extends CodeGenBase { ...@@ -782,14 +795,14 @@ public class CodeGenImpl extends CodeGenBase {
betterBackend.emitPush(T0, "Push result onto stack"); betterBackend.emitPush(T0, "Push result onto stack");
return null; return null;
} }
else if (binaryExpr.left.getInferredType().equals(SymbolType.STR_TYPE)) { else if (leftType.equals(SymbolType.STR_TYPE) || leftType.isListType() || leftType.equals(SymbolType.EMPTY_TYPE)) {
binaryExpr.left.dispatch(this); binaryExpr.left.dispatch(this);
binaryExpr.right.dispatch(this); binaryExpr.right.dispatch(this);
betterBackend.emitPop(T6, "rightStr => t6"); betterBackend.emitPop(T6, "rightStr/list => t6");
betterBackend.emitPop(T5, "leftStr => t5"); betterBackend.emitPop(T5, "leftStr/list => t5");
RiscVBackend.Register ret = emitStringAdd(T5, T6); RiscVBackend.Register ret = emitStringAdd(T5, T6, leftType.equals(SymbolType.STR_TYPE));
betterBackend.emitPush(ret, "Push result_of strLeft+strRight"); betterBackend.emitPush(ret, "Push result_of strLeft+strRight / listLeft+listRight");
return null; return null;
} }
case "-": case "-":
......
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