1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-06-02 00:41:42 +00:00

Added special ALU register support

This commit is contained in:
jespergravgaard 2017-06-04 00:45:40 +02:00
parent 357bbecade
commit 4aa00d4536
9 changed files with 161 additions and 54 deletions

View File

@ -35,27 +35,8 @@ public class AsmFragment {
public AsmFragment(StatementConditionalJump conditionalJump, ControlFlowBlock block, SymbolTable symbols, ControlFlowGraph graph) {
this.bindings = new HashMap<>();
this.symbols = symbols;
StringBuilder signature = new StringBuilder();
if (conditionalJump.getRValue1() != null) {
signature.append(bind(conditionalJump.getRValue1()));
}
if (conditionalJump.getOperator() != null) {
signature.append(getOperatorFragmentName(conditionalJump.getOperator()));
}
if (conditionalJump.getRValue2() instanceof ConstantInteger && ((ConstantInteger) conditionalJump.getRValue2()).getNumber() == 0) {
signature.append("0");
} else {
signature.append(bind(conditionalJump.getRValue2()));
}
signature.append("_then_");
Label destination = conditionalJump.getDestination();
ControlFlowBlock destinationBlock = graph.getBlock(destination);
String destinationLabel = destination.getName();
if (destinationBlock.hasPhiStatements()) {
destinationLabel = destination.getName() + "_from_" + block.getLabel().getName();
}
signature.append(bind(new Label(destinationLabel, false)));
setSignature(signature.toString());
String conditionalJumpSignature = conditionalJumpSignature(conditionalJump, block, graph);
setSignature(conditionalJumpSignature);
}
public AsmFragment(StatementAssignment assignment, SymbolTable symbols) {
@ -70,10 +51,42 @@ public class AsmFragment {
setSignature(assignmentSignature(lValue, null, null, rValue));
}
public AsmFragment(StatementAssignment assignment, StatementAssignment assignmentAlu, SymbolTable symbols) {
this.bindings = new HashMap<>();
this.symbols = symbols;
setSignature(assignmentWithAluSignature(assignment, assignmentAlu));
}
private String assignmentWithAluSignature(StatementAssignment assignment, StatementAssignment assignmentAlu) {
RValue assignmentRValue2 = assignment.getRValue2();
RegisterAllocation.Register rVal2Register = symbols.getRegister((Variable) assignmentRValue2);
if(!rVal2Register.getType().equals(RegisterAllocation.RegisterType.REG_ALU_BYTE)) {
throw new RuntimeException("Error! ALU register only allowed as rValue2. "+assignment);
}
StringBuilder signature = new StringBuilder();
signature.append(bind(assignment.getLValue()));
signature.append("=");
if (assignment.getRValue1() != null) {
signature.append(bind(assignment.getRValue1()));
}
if (assignment.getOperator() != null) {
signature.append(getOperatorFragmentName(assignment.getOperator()));
}
signature.append(assignmentRightSideSignature(assignmentAlu.getRValue1(), assignmentAlu.getOperator(), assignmentAlu.getRValue2()));
return signature.toString();
}
private String assignmentSignature(LValue lValue, RValue rValue1, Operator operator, RValue rValue2) {
StringBuilder signature = new StringBuilder();
signature.append(bind(lValue));
signature.append("=");
signature.append(assignmentRightSideSignature(rValue1, operator, rValue2));
return signature.toString();
}
private String assignmentRightSideSignature(RValue rValue1, Operator operator, RValue rValue2) {
StringBuilder signature = new StringBuilder();
if (rValue1 != null) {
signature.append(bind(rValue1));
}
@ -104,6 +117,30 @@ public class AsmFragment {
return signature.toString();
}
private String conditionalJumpSignature(StatementConditionalJump conditionalJump, ControlFlowBlock block, ControlFlowGraph graph) {
StringBuilder signature = new StringBuilder();
if (conditionalJump.getRValue1() != null) {
signature.append(bind(conditionalJump.getRValue1()));
}
if (conditionalJump.getOperator() != null) {
signature.append(getOperatorFragmentName(conditionalJump.getOperator()));
}
if (conditionalJump.getRValue2() instanceof ConstantInteger && ((ConstantInteger) conditionalJump.getRValue2()).getNumber() == 0) {
signature.append("0");
} else {
signature.append(bind(conditionalJump.getRValue2()));
}
signature.append("_then_");
Label destination = conditionalJump.getDestination();
ControlFlowBlock destinationBlock = graph.getBlock(destination);
String destinationLabel = destination.getName();
if (destinationBlock.hasPhiStatements()) {
destinationLabel = destination.getName() + "_from_" + block.getLabel().getName();
}
signature.append(bind(new Label(destinationLabel, false)));
return signature.toString();
}
private static String getOperatorFragmentName(Operator operator) {
String op = operator.getOperator();
switch (op) {

View File

@ -0,0 +1,2 @@
clc
adc {cowo1},x

View File

@ -0,0 +1 @@
lda {cowo1},x

View File

@ -0,0 +1,3 @@
clc
adc {zpby2}
sta {zpby1}

View File

@ -21,28 +21,43 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
for (ControlFlowBlock block : getGraph().getAllBlocks()) {
for (Statement statement : block.getStatements()) {
if (statement instanceof StatementAssignment) {
boolean subOpt = false;
StatementAssignment assignment = (StatementAssignment) statement;
if(assignment.getLValue() instanceof PointerDereferenceIndexed) {
optimized |= optimizePointerDereferenceIndexed(assignment);
}
Operator operator = assignment.getOperator();
if (operator != null) {
switch (operator.getOperator()) {
case "+":
subOpt = optimizePlus(assignment);
optimized |= optimizePlus(assignment);
break;
case "*idx":
subOpt = optimizeArrayDeref(assignment);
optimized |= optimizeArrayDeref(assignment);
break;
}
}
if (subOpt) {
optimized = true;
}
}
}
}
return optimized;
}
private boolean optimizePointerDereferenceIndexed(StatementAssignment assignment) {
PointerDereferenceIndexed pointerDereferenceIndexed = (PointerDereferenceIndexed) assignment.getLValue();
if(pointerDereferenceIndexed.getPointer() instanceof ConstantInteger && pointerDereferenceIndexed.getIndex() instanceof Variable) {
Variable variable = (Variable) pointerDereferenceIndexed.getIndex();
ConstantInteger consolidated = consolidateSubConstants(variable);
if (consolidated != null) {
ConstantInteger ptrConstant = (ConstantInteger) pointerDereferenceIndexed.getPointer();
int newPtr = ptrConstant.getNumber() + consolidated.getNumber();
pointerDereferenceIndexed.setPointer(new ConstantInteger(newPtr));
System.out.println("Consolidated assigned array index constant in assignment " + assignment.getLValue());
return true;
}
}
return false;
}
private boolean optimizeArrayDeref(StatementAssignment assignment) {
if (assignment.getRValue1() instanceof ConstantInteger && assignment.getRValue2() instanceof Variable) {
Variable variable = (Variable) assignment.getRValue2();
@ -51,7 +66,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
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());
System.out.println("Consolidated referenced array index constant in assignment " + assignment.getLValue());
return true;
}
}

View File

@ -2,6 +2,8 @@ package dk.camelot64.kickc.icl;
import dk.camelot64.kickc.asm.*;
import java.util.Iterator;
/**
* Code Generation of 6502 Assembler from ICL/SSA Control Flow Graph
*/
@ -27,7 +29,7 @@ public class Pass3CodeGeneration {
// Generate exit
ControlFlowBlock defaultSuccessor = block.getDefaultSuccessor();
if (defaultSuccessor != null) {
if(defaultSuccessor.hasPhiStatements()) {
if (defaultSuccessor.hasPhiStatements()) {
genBlockPhiTransition(asm, block, defaultSuccessor);
}
asm.addInstruction("JMP", AsmAddressingMode.ABS, defaultSuccessor.getLabel().getName().replace('@', 'B'));
@ -37,31 +39,50 @@ public class Pass3CodeGeneration {
}
private void genStatements(AsmProgram asm, ControlFlowBlock block) {
for (Statement statement : block.getStatements()) {
Iterator<Statement> statementsIt = block.getStatements().iterator();
while (statementsIt.hasNext()) {
Statement statement = statementsIt.next();
if (!(statement instanceof StatementPhi)) {
genStatement(asm, statement, block);
if (statement instanceof StatementAssignment) {
StatementAssignment assignment = (StatementAssignment) statement;
LValue lValue = assignment.getLValue();
boolean isAlu = false;
if (lValue instanceof Variable) {
RegisterAllocation.Register lValRegister = symbols.getRegister((Variable) lValue);
if (lValRegister.getType().equals(RegisterAllocation.RegisterType.REG_ALU_BYTE)) {
asm.addComment(statement + " // ALU");
StatementAssignment assignmentAlu = assignment;
statement = statementsIt.next();
if (!(statement instanceof StatementAssignment)) {
throw new RuntimeException("Error! ALU statement must be followed immidiately by assignment using the ALU. " + statement);
}
assignment = (StatementAssignment) statement;
AsmFragment asmFragment = new AsmFragment(assignment, assignmentAlu, symbols);
asm.addComment(statement + " // " + asmFragment.getSignature());
asmFragment.generate(asm);
isAlu = true;
}
}
if (!isAlu) {
AsmFragment asmFragment = new AsmFragment(assignment, symbols);
asm.addComment(statement + " // " + asmFragment.getSignature());
asmFragment.generate(asm);
}
} else if (statement instanceof StatementConditionalJump) {
AsmFragment asmFragment = new AsmFragment((StatementConditionalJump) statement, block, symbols, graph);
asm.addComment(statement + " // " + asmFragment.getSignature());
asmFragment.generate(asm);
} else {
throw new RuntimeException("Statement not supported " + statement);
}
}
}
}
private void genStatement(AsmProgram asm, Statement statement, ControlFlowBlock block) {
if (statement instanceof StatementAssignment) {
AsmFragment asmFragment = new AsmFragment((StatementAssignment) statement, symbols);
asm.addComment(statement + " // " + asmFragment.getSignature());
asmFragment.generate(asm);
} else if (statement instanceof StatementConditionalJump) {
AsmFragment asmFragment = new AsmFragment((StatementConditionalJump) statement, block, symbols, graph);
asm.addComment(statement + " // " + asmFragment.getSignature());
asmFragment.generate(asm);
} else {
throw new RuntimeException("Statement not supported "+statement);
}
}
private void genBlockEntryPoints(AsmProgram asm, ControlFlowBlock block) {
if(block.hasPhiStatements()) {
if (block.hasPhiStatements()) {
for (ControlFlowBlock predecessor : block.getPredecessors()) {
if(block.equals(predecessor.getConditionalSuccessor())) {
if (block.equals(predecessor.getConditionalSuccessor())) {
genBlockPhiTransition(asm, predecessor, block);
asm.addInstruction("JMP", AsmAddressingMode.ABS, block.getLabel().getName().replace('@', 'B'));
}
@ -87,7 +108,7 @@ public class Pass3CodeGeneration {
}
private RegisterAllocation.Register getRegister(RValue rValue) {
if(rValue instanceof Variable) {
if (rValue instanceof Variable) {
return symbols.getRegister((Variable) rValue);
} else {
return null;
@ -95,9 +116,9 @@ public class Pass3CodeGeneration {
}
private void genAsmMove(AsmProgram asm, LValue lValue, RValue rValue) {
if(getRegister(lValue).equals(getRegister(rValue))) {
if (getRegister(lValue).equals(getRegister(rValue))) {
// Do not move from register to itself
asm.addComment(lValue + " = " + rValue + " // register copy " );
asm.addComment(lValue + " = " + rValue + " // register copy ");
return;
}
AsmFragment asmFragment = new AsmFragment(lValue, rValue, symbols);

View File

@ -64,9 +64,13 @@ public class Pass3RegisterAllocation {
allocation.allocate(symbols.getVariable("v#4"), new RegisterAllocation.RegisterAByte());
allocation.allocate(symbols.getVariable("v#5"), new RegisterAllocation.RegisterAByte());
//allocation.allocate(symbols.getVariable("$0"), new RegisterAllocation.RegisterAByte());
//allocation.allocate(symbols.getVariable("$1"), new RegisterAllocation.RegisterAByte());
//allocation.allocate(symbols.getVariable("$2"), new RegisterAllocation.RegisterAByte());
//allocation.allocate(symbols.getVariable("$3"), new RegisterAllocation.RegisterAByte());
allocation.allocate(symbols.getVariable("$1"), new RegisterAllocation.RegisterAByte());
allocation.allocate(symbols.getVariable("$3"), new RegisterAllocation.RegisterALUByte());
allocation.allocate(symbols.getVariable("$4"), new RegisterAllocation.RegisterAByte());
allocation.allocate(symbols.getVariable("$6"), new RegisterAllocation.RegisterALUByte());
allocation.allocate(symbols.getVariable("$7"), new RegisterAllocation.RegisterAByte());
symbols.setAllocation(allocation);
}

View File

@ -36,7 +36,7 @@ public class RegisterAllocation {
/** The register type. */
public enum RegisterType {
ZP_BYTE, ZP_BOOL, REG_A_BYTE, REG_Y_BYTE, REG_X_BYTE, ZP_PTR_BYTE, ZP_WORD
ZP_BYTE, ZP_BOOL, REG_A_BYTE, REG_ALU_BYTE, REG_Y_BYTE, REG_X_BYTE, ZP_PTR_BYTE, ZP_WORD
}
/** A zero page address used as a register for a single byte variable. */
@ -247,6 +247,26 @@ public class RegisterAllocation {
}
}
/** The special ALU register. */
public static class RegisterALUByte implements Register {
@Override
public RegisterType getType() {
return RegisterType.REG_ALU_BYTE;
}
@Override
public String toString() {
return "reg byte alu";
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
return true;
}
}
public static Register getRegisterX() {
return new RegisterXByte();
}
@ -259,6 +279,10 @@ public class RegisterAllocation {
return new RegisterAByte();
}
public static Register getRegisterALU() {
return new RegisterALUByte();
}
@Override
public String toString() {
StringBuffer out = new StringBuffer();

View File

@ -1,8 +1,8 @@
byte[15] fibs = $1100;
fibs[0] = 0;
fibs[1] = 1;
byte i = 2;
byte i = 0;
do {
fibs[i] = fibs[i-2]+fibs[i-1];
fibs[i+2] = fibs[i]+fibs[i+1];
i = i + 1;
} while(i<15)