mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-04-22 03:38:31 +00:00
Added *idx operator for array indexing.
This commit is contained in:
parent
65f41f874f
commit
357bbecade
@ -109,6 +109,8 @@ public class AsmFragment {
|
||||
switch (op) {
|
||||
case "*":
|
||||
return "_star_";
|
||||
case "*idx":
|
||||
return "_staridx_";
|
||||
case "+":
|
||||
return "_plus_";
|
||||
case "-":
|
||||
|
@ -0,0 +1,2 @@
|
||||
lda #{coby3}
|
||||
sta {cowo1}+{coby2}
|
@ -0,0 +1,2 @@
|
||||
lda {cowo1},x
|
||||
sta {zpby1}
|
@ -216,14 +216,11 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
||||
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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user