1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-17 01:55:22 +00:00

Fixed issue where compound addignments multiplied the index by sizeof() squared.

This commit is contained in:
Jesper Gravgaard 2019-04-19 08:42:42 +02:00
parent 46e2f3ced4
commit eb26618295
6 changed files with 76 additions and 9 deletions

View File

@ -0,0 +1,7 @@
clc
lda {c1},x
adc #<{c2}
sta {c1},x
lda {c1}+1,x
adc #>{c2}
sta {c1}+1,x

View File

@ -0,0 +1,7 @@
clc
lda {c1},y
adc #<{c2}
sta {c1},y
lda {c1}+1,y
adc #>{c2}
sta {c1}+1,y

View File

@ -1162,11 +1162,26 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
String op = ((TerminalNode) ctx.getChild(1)).getSymbol().getText();
Operator operator = Operators.getBinaryCompound(op);
// Assignment with operator
Statement stmt = new StatementAssignment(lValue, lValue, operator, rValue, new StatementSource(ctx), ensureUnusedComments(getCommentsSymbol(ctx)));
LValue rValue1 = copyLValue(lValue);
Statement stmt = new StatementAssignment(lValue, rValue1, operator, rValue, new StatementSource(ctx), ensureUnusedComments(getCommentsSymbol(ctx)));
sequence.addStatement(stmt);
return lValue;
}
private LValue copyLValue(LValue lValue) {
if(lValue instanceof VariableRef) {
return new VariableRef(((VariableRef) lValue).getFullName());
} else if(lValue instanceof LvalueIntermediate) {
return new LvalueIntermediate((VariableRef) copyLValue(((LvalueIntermediate) lValue).getVariable()));
} else if(lValue instanceof PointerDereferenceSimple) {
return new PointerDereferenceSimple(((PointerDereferenceSimple) lValue).getPointer());
} else if(lValue instanceof PointerDereferenceIndexed) {
return new PointerDereferenceIndexed(((PointerDereferenceIndexed) lValue).getPointer(), ((PointerDereferenceIndexed) lValue).getIndex());
} else {
throw new CompileError("Unknown LValue type "+lValue);
}
}
@Override
public RValue visitExprCast(KickCParser.ExprCastContext ctx) {
RValue child = (RValue) this.visit(ctx.expr());

View File

@ -14,9 +14,10 @@ import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypePointer;
import dk.camelot64.kickc.model.values.ConstantRef;
import dk.camelot64.kickc.model.values.PointerDereferenceIndexed;
import dk.camelot64.kickc.model.values.RValue;
import dk.camelot64.kickc.model.values.VariableRef;
import java.util.ListIterator;
import java.util.*;
/**
* Fixes pointer math to use sizeof(type)
@ -44,6 +45,9 @@ public class Pass1PointerSizeofFix extends Pass1Base {
}
}
// For each statement maps RValues used as index to the new *2 variable created
Map<Statement, Map<RValue, VariableRef>> handled = new LinkedHashMap<>();
ProgramValueIterator.execute(getProgram(), (programValue, currentStmt, stmtIt, currentBlock) -> {
if(programValue.get() instanceof PointerDereferenceIndexed) {
PointerDereferenceIndexed deref = (PointerDereferenceIndexed) programValue.get();
@ -54,13 +58,20 @@ public class Pass1PointerSizeofFix extends Pass1Base {
if(pointerType.getElementType().getSizeBytes() > 1) {
// Array-indexing into a non-byte pointer - multiply by sizeof()
getLog().append("Fixing pointer array-indexing " + deref.toString(getProgram()));
VariableIntermediate tmpVar = getScope().getScope(currentBlock.getScope()).addVariableIntermediate();
tmpVar.setType(SymbolType.BYTE);
stmtIt.remove();
ConstantRef sizeOfTargetType = OperatorSizeOf.getSizeOfConstantVar(getProgram().getScope(), pointerType.getElementType());
stmtIt.add(new StatementAssignment(tmpVar.getRef(), deref.getIndex(), Operators.MULTIPLY, sizeOfTargetType, currentStmt.getSource(), Comment.NO_COMMENTS));
stmtIt.add(currentStmt);
deref.setIndex(tmpVar.getRef());
VariableRef idx2VarRef = handled.getOrDefault(currentStmt, new LinkedHashMap<>()).get(deref.getIndex());
if(idx2VarRef==null) {
VariableIntermediate idx2Var = getScope().getScope(currentBlock.getScope()).addVariableIntermediate();
idx2Var.setType(SymbolType.BYTE);
ConstantRef sizeOfTargetType = OperatorSizeOf.getSizeOfConstantVar(getProgram().getScope(), pointerType.getElementType());
StatementAssignment idx2 = new StatementAssignment(idx2Var.getRef(), deref.getIndex(), Operators.MULTIPLY, sizeOfTargetType, currentStmt.getSource(), Comment.NO_COMMENTS);
stmtIt.previous();
stmtIt.add(idx2);
stmtIt.next();
idx2VarRef = idx2Var.getRef();
handled.putIfAbsent(currentStmt, new LinkedHashMap<>());
handled.get(currentStmt).put(deref.getIndex(), idx2VarRef);
}
deref.setIndex(idx2VarRef);
}
}
}

View File

@ -37,6 +37,11 @@ public class TestPrograms {
// compileAndCompare("pointer-cast-3");
//}
@Test
public void testWordPointerCompound() throws IOException, URISyntaxException {
compileAndCompare("word-pointer-compound");
}
@Test
public void testWordPointerMath() throws IOException, URISyntaxException {
compileAndCompare("word-pointer-math");

View File

@ -0,0 +1,22 @@
// Test word pointer compound assignment
void main() {
word[] words = { $3031, $3233, $3435 };
for( byte i: 0..2) {
words[i] += $0101;
}
const byte* SCREEN = $0400;
SCREEN[0] = >words[0];
SCREEN[1] = <words[0];
SCREEN[2] = >words[1];
SCREEN[3] = <words[1];
SCREEN[4] = >words[2];
SCREEN[5] = <words[2];
}