diff --git a/src/dk/camelot64/kickc/asm/AsmFragment.java b/src/dk/camelot64/kickc/asm/AsmFragment.java index b1b2286a5..f76cece28 100644 --- a/src/dk/camelot64/kickc/asm/AsmFragment.java +++ b/src/dk/camelot64/kickc/asm/AsmFragment.java @@ -109,6 +109,8 @@ public class AsmFragment { switch (op) { case "*": return "_star_"; + case "*idx": + return "_staridx_"; case "+": return "_plus_"; case "-": diff --git a/src/dk/camelot64/kickc/asm/fragment/ptr_cowo1_coby2=coby3.asm b/src/dk/camelot64/kickc/asm/fragment/ptr_cowo1_coby2=coby3.asm new file mode 100644 index 000000000..63bcfdda1 --- /dev/null +++ b/src/dk/camelot64/kickc/asm/fragment/ptr_cowo1_coby2=coby3.asm @@ -0,0 +1,2 @@ +lda #{coby3} +sta {cowo1}+{coby2} \ No newline at end of file diff --git a/src/dk/camelot64/kickc/asm/fragment/zpby1=cowo1_staridx_xby.asm b/src/dk/camelot64/kickc/asm/fragment/zpby1=cowo1_staridx_xby.asm new file mode 100644 index 000000000..a32b0efee --- /dev/null +++ b/src/dk/camelot64/kickc/asm/fragment/zpby1=cowo1_staridx_xby.asm @@ -0,0 +1,2 @@ +lda {cowo1},x +sta {zpby1} \ No newline at end of file diff --git a/src/dk/camelot64/kickc/icl/Pass1GenerateStatementSequence.java b/src/dk/camelot64/kickc/icl/Pass1GenerateStatementSequence.java index 5ee3149a0..2746ae370 100644 --- a/src/dk/camelot64/kickc/icl/Pass1GenerateStatementSequence.java +++ b/src/dk/camelot64/kickc/icl/Pass1GenerateStatementSequence.java @@ -216,14 +216,11 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor { public RValue visitExprArray(KickCParser.ExprArrayContext ctx) { RValue array = (LValue) visit(ctx.expr(0)); RValue index = (RValue) visit(ctx.expr(1)); - Operator operator = new Operator("+"); + Operator operator = new Operator("*idx"); VariableIntermediate tmpVar = symbolTable.newIntermediateAssignment(); Statement stmt = new StatementAssignment(tmpVar, array, operator, index); sequence.addStatement(stmt); - VariableIntermediate tmpVar2 = symbolTable.newIntermediateAssignment(); - Statement stmt2 = new StatementAssignment(tmpVar2, null, new Operator("*"), tmpVar ); - sequence.addStatement(stmt2); - return tmpVar2; + return tmpVar; } @Override diff --git a/src/dk/camelot64/kickc/icl/Pass2ConstantAdditionElimination.java b/src/dk/camelot64/kickc/icl/Pass2ConstantAdditionElimination.java index 1685ad11a..5b92c81c8 100644 --- a/src/dk/camelot64/kickc/icl/Pass2ConstantAdditionElimination.java +++ b/src/dk/camelot64/kickc/icl/Pass2ConstantAdditionElimination.java @@ -1,6 +1,8 @@ package dk.camelot64.kickc.icl; -/** Compiler Pass eliminating several additions of constants by consolidating them to a single (compile time) constant c1+v+c2 => (c1+c2)+v */ +/** + * Compiler Pass eliminating several additions of constants by consolidating them to a single (compile time) constant c1+v+c2 => (c1+c2)+v + */ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization { public Pass2ConstantAdditionElimination(ControlFlowGraph graph, SymbolTable symbolTable) { @@ -9,6 +11,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization { /** * For assignments with a constant part the variable part is examined looking for constants to consolidate into the constant. + * * @return true optimization was performed. false if no optimization was possible. */ @Override @@ -17,49 +20,88 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization { // Examine all assigments - performing constant consolidation for (ControlFlowBlock block : getGraph().getAllBlocks()) { for (Statement statement : block.getStatements()) { - if(statement instanceof StatementAssignment) { + if (statement instanceof StatementAssignment) { + boolean subOpt = false; StatementAssignment assignment = (StatementAssignment) statement; - if(assignment.getOperator()!=null && "+".equals(assignment.getOperator().getOperator())) { - if(assignment.getRValue1() instanceof ConstantInteger && assignment.getRValue2() instanceof Variable) { - Variable variable = (Variable) assignment.getRValue2(); - ConstantInteger consolidated = consolidateSubConstants(variable); - if(consolidated!=null) { - ConstantInteger const1 = (ConstantInteger) assignment.getRValue1(); - assignment.setRValue1(new ConstantInteger(const1.getNumber()+consolidated.getNumber())); - optimized = true; - System.out.println("Consolidated constant in assignment "+assignment.getLValue()); - } - } else if(assignment.getRValue1() instanceof Variable && assignment.getRValue2() instanceof ConstantInteger) { - Variable variable = (Variable) assignment.getRValue1(); - ConstantInteger consolidated = consolidateSubConstants(variable); - if(consolidated!=null) { - ConstantInteger const2 = (ConstantInteger) assignment.getRValue2(); - assignment.setRValue2(new ConstantInteger(const2.getNumber()+consolidated.getNumber())); - optimized = true; - System.out.println("Consolidated constant in assignment "+assignment.getLValue()); - } + Operator operator = assignment.getOperator(); + if (operator != null) { + switch (operator.getOperator()) { + case "+": + subOpt = optimizePlus(assignment); + break; + case "*idx": + subOpt = optimizeArrayDeref(assignment); + break; } } + if (subOpt) { + optimized = true; + } } } } return optimized; } + private boolean optimizeArrayDeref(StatementAssignment assignment) { + if (assignment.getRValue1() instanceof ConstantInteger && assignment.getRValue2() instanceof Variable) { + Variable variable = (Variable) assignment.getRValue2(); + ConstantInteger consolidated = consolidateSubConstants(variable); + if (consolidated != null) { + ConstantInteger ptrConstant = (ConstantInteger) assignment.getRValue1(); + int newPtr = ptrConstant.getNumber() + consolidated.getNumber(); + assignment.setRValue1(new ConstantInteger(newPtr)); + System.out.println("Consolidated constant in assignment " + assignment.getLValue()); + return true; + } + } + return false; + } + + private boolean optimizePlus(StatementAssignment assignment) { + if (assignment.getRValue1() instanceof ConstantInteger && assignment.getRValue2() instanceof Variable) { + Variable variable = (Variable) assignment.getRValue2(); + ConstantInteger consolidated = consolidateSubConstants(variable); + if (consolidated != null) { + ConstantInteger const1 = (ConstantInteger) assignment.getRValue1(); + assignment.setRValue1(new ConstantInteger(const1.getNumber() + consolidated.getNumber())); + System.out.println("Consolidated constant in assignment " + assignment.getLValue()); + return true; + } + } else if (assignment.getRValue1() instanceof Variable && assignment.getRValue2() instanceof ConstantInteger) { + Variable variable = (Variable) assignment.getRValue1(); + ConstantInteger consolidated = consolidateSubConstants(variable); + if (consolidated != null) { + ConstantInteger const2 = (ConstantInteger) assignment.getRValue2(); + int newNumber = const2.getNumber() + consolidated.getNumber(); + if (newNumber < 0) { + assignment.setRValue2(new ConstantInteger(-newNumber)); + assignment.setOperator(new Operator("-")); + } else { + assignment.setRValue2(new ConstantInteger(newNumber)); + } + System.out.println("Consolidated constant in assignment " + assignment.getLValue()); + return true; + } + } + return false; + } + /** * Gather up constants from sub addition expressions of a variable, remove them there, and return the aggregated sum. + * * @param variable The variable to examine * @return The consolidated constant. Null if no sub-constants were found. */ private ConstantInteger consolidateSubConstants(Variable variable) { StatementAssignment assignment = getGraph().getAssignment(variable); - if(assignment!=null && assignment.getOperator()!=null && "+".equals(assignment.getOperator().getOperator())) { - if(assignment.getRValue1() instanceof ConstantInteger) { + if (assignment != null && assignment.getOperator() != null && "+".equals(assignment.getOperator().getOperator())) { + if (assignment.getRValue1() instanceof ConstantInteger) { ConstantInteger constant = (ConstantInteger) assignment.getRValue1(); assignment.setRValue1(null); assignment.setOperator(null); return constant; - } else if(assignment.getRValue2() instanceof ConstantInteger) { + } else if (assignment.getRValue2() instanceof ConstantInteger) { ConstantInteger constant = (ConstantInteger) assignment.getRValue2(); assignment.setRValue2(assignment.getRValue1()); assignment.setOperator(null); @@ -67,20 +109,52 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization { return constant; } else { ConstantInteger const1 = null; - if(assignment.getRValue1() instanceof Variable) { + if (assignment.getRValue1() instanceof Variable) { const1 = consolidateSubConstants((Variable) assignment.getRValue1()); } ConstantInteger const2 = null; - if(assignment.getRValue2() instanceof Variable) { + if (assignment.getRValue2() instanceof Variable) { const2 = consolidateSubConstants((Variable) assignment.getRValue2()); } ConstantInteger result = null; - if(const1!=null) { + if (const1 != null) { result = const1; - if(const2!=null) { - result = new ConstantInteger(const1.getNumber()+const2.getNumber()); + if (const2 != null) { + result = new ConstantInteger(const1.getNumber() + const2.getNumber()); } - } else if(const2!=null) { + } else if (const2 != null) { + result = const2; + } + return result; + } + } + if (assignment != null && assignment.getOperator() != null && "-".equals(assignment.getOperator().getOperator())) { + if (assignment.getRValue1() instanceof ConstantInteger) { + ConstantInteger constant = (ConstantInteger) assignment.getRValue1(); + assignment.setRValue1(null); + return constant; + } else if (assignment.getRValue2() instanceof ConstantInteger) { + ConstantInteger constant = (ConstantInteger) assignment.getRValue2(); + assignment.setRValue2(assignment.getRValue1()); + assignment.setOperator(null); + assignment.setRValue1(null); + return new ConstantInteger(-constant.getNumber()); + } else { + ConstantInteger const1 = null; + if (assignment.getRValue1() instanceof Variable) { + const1 = consolidateSubConstants((Variable) assignment.getRValue1()); + } + ConstantInteger const2 = null; + if (assignment.getRValue2() instanceof Variable) { + const2 = consolidateSubConstants((Variable) assignment.getRValue2()); + } + ConstantInteger result = null; + if (const1 != null) { + result = const1; + if (const2 != null) { + result = new ConstantInteger(const1.getNumber() - const2.getNumber()); + } + } else if (const2 != null) { result = const2; } return result; @@ -89,5 +163,4 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization { return null; } - } diff --git a/src/dk/camelot64/kickc/icl/PassTypeInference.java b/src/dk/camelot64/kickc/icl/PassTypeInference.java index 8537b45fc..ffd7dd62a 100644 --- a/src/dk/camelot64/kickc/icl/PassTypeInference.java +++ b/src/dk/camelot64/kickc/icl/PassTypeInference.java @@ -94,6 +94,11 @@ public class PassTypeInference { return SymbolTypeBasic.BYTE; } throw new RuntimeException("Type inference case not handled " + type1 + " " + operator + " " + type2); + case "*idx": + if(type1 instanceof SymbolTypePointer) { + return ((SymbolTypePointer) type1).getElementType(); + } + throw new RuntimeException("Type inference case not handled " + type1 + " " + operator + " " + type2); case "/": if (SymbolTypeBasic.WORD.equals(type1) || SymbolTypeBasic.WORD.equals(type2)) { return SymbolTypeBasic.WORD; diff --git a/src/dk/camelot64/kickc/test/fibmem.kc b/src/dk/camelot64/kickc/test/fibmem.kc index d727226f5..ea07cec8b 100644 --- a/src/dk/camelot64/kickc/test/fibmem.kc +++ b/src/dk/camelot64/kickc/test/fibmem.kc @@ -2,7 +2,7 @@ byte[15] fibs = $1100; fibs[0] = 0; fibs[1] = 1; byte i = 2; -while(i<15) { +do { fibs[i] = fibs[i-2]+fibs[i-1]; i = i + 1; -} +} while(i<15) diff --git a/src/dk/camelot64/kickc/test/minus.kc b/src/dk/camelot64/kickc/test/minus.kc index 131e8bdbe..af7e4071d 100644 --- a/src/dk/camelot64/kickc/test/minus.kc +++ b/src/dk/camelot64/kickc/test/minus.kc @@ -1,7 +1,6 @@ byte[16] p = $1100; byte i = 5; do { - byte c=2; - p[i] = 15+i+c+i+2; + p[i] = 2+i+2; i = i+1; } while(i<10)