1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-08 17:54:40 +00:00

More fragments - a start at calculating value for ASM.

This commit is contained in:
jespergravgaard 2017-07-31 20:00:25 +02:00
parent 18bbde8a44
commit 47e8b6b2b9
12 changed files with 72 additions and 23 deletions

View File

@ -0,0 +1,2 @@
ldy #0
lda ({zpptrby1}),y

View File

@ -0,0 +1,2 @@
cpy #{coby1}
bcs {la1}

View File

@ -0,0 +1,3 @@
ldy #0
lda ({zpptrby1}),y
tax

View File

@ -0,0 +1,4 @@
txa
sec
sbc #{coby1}
tax

View File

@ -0,0 +1,4 @@
lda {zpby1}
clc
adc {zpby2}
tax

View File

@ -0,0 +1,3 @@
ldy #0
lda ({zpptrby1}),y
tay

View File

@ -0,0 +1,4 @@
lda {zpby1}
clc
adc {zpby2}
tay

View File

@ -0,0 +1,3 @@
tax
lda {cowo1},x
sta {zpby1}

View File

@ -0,0 +1,2 @@
lda {cowo1},y
sta {zpby1}

View File

@ -1,6 +1,8 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.CompileLog;
import dk.camelot64.kickc.asm.AsmInstruction;
import dk.camelot64.kickc.asm.AsmLine;
import dk.camelot64.kickc.asm.AsmProgram;
import dk.camelot64.kickc.asm.parser.AsmClobber;
import dk.camelot64.kickc.icl.*;
@ -30,7 +32,7 @@ public class Pass3AssertNoCpuClobber {
/** Check that no statement clobbers a CPU register used by an alive variable */
public void check() {
if(hasClobberProblem()) {
if(hasClobberProblem(true, null)) {
throw new RuntimeException("CLOBBER ERROR! See log for more info.");
}
}
@ -39,15 +41,18 @@ public class Pass3AssertNoCpuClobber {
* Determines whether any statement in the program clobbers a CPU register used by an alive variable
* @return true if there is a clobber problem in the program
*/
public boolean hasClobberProblem() {
public boolean hasClobberProblem(boolean verbose, RegisterAllocation.Register register) {
RegisterAllocation allocation = program.getScope().getAllocation();
LiveRangeVariables liveRangeVariables = program.getScope().getLiveRangeVariables();
boolean error = false;
boolean clobberProblem = false;
Pass4CodeGeneration.AsmCodegenAluState aluState = new Pass4CodeGeneration.AsmCodegenAluState();
int registerCycles = 0;
for (ControlFlowBlock block : program.getGraph().getAllBlocks()) {
for (Statement statement : block.getStatements()) {
// Generate ASM and find clobber
Collection<RegisterAllocation.Register> clobberRegisters = getClobberedRegisters(statement, block);
AsmProgram asm = getAsmProgram(statement, block, aluState);
Collection<RegisterAllocation.Register> clobberRegisters = getClobberedRegisters(asm);
// Find alive variables
List<VariableRef> aliveVars = new ArrayList<>(liveRangeVariables.getAlive(statement));
@ -61,20 +66,39 @@ public class Pass3AssertNoCpuClobber {
// No need to check a zp-register - here we are only interested in CPU registers
continue;
}
if(aliveVarRegister.equals(register)) {
registerCycles += countCycles(asm);
}
if(assignedVars.contains(aliveVar)) {
// No need to register that is assigned by the statement - it will be clobbered
continue;
}
// Alive and not assigned to - clobber not allowed!
if(clobberRegisters.contains(aliveVarRegister)) {
log.append("Error! Alive variable "+aliveVar+" register "+aliveVarRegister+" clobbered by the ASM generated by statement "+statement);
log.append(getAsmProgram(statement, block).toString(false));
error = true;
if(verbose) {
log.append("Error! Alive variable " + aliveVar + " register " + aliveVarRegister + " clobbered by the ASM generated by statement " + statement);
log.append(asm.toString(false));
}
clobberProblem = true;
}
}
}
}
return error;
if(!clobberProblem && register!=null) {
log.append("Register Cycles: "+register+" "+registerCycles);
}
return clobberProblem;
}
private int countCycles(AsmProgram asm) {
int instructionCycles = 0;
for (AsmLine asmLine : asm.getLines()) {
if(asmLine instanceof AsmInstruction) {
double lineCycles = ((AsmInstruction) asmLine).getType().getCycles();
instructionCycles += lineCycles;
}
}
return instructionCycles;
}
@ -103,12 +127,10 @@ public class Pass3AssertNoCpuClobber {
/**
* Get all CPU registers clobbered by the ASM generated from a specific statement in the program
*
* @param statement The statement
* @param block The block containing the statement
* @param asm The assembler to check
* @return The clobbered CPU registers
*/
private Collection<RegisterAllocation.Register> getClobberedRegisters(Statement statement, ControlFlowBlock block) {
AsmProgram asm = getAsmProgram(statement, block);
private Collection<RegisterAllocation.Register> getClobberedRegisters(AsmProgram asm) {
AsmClobber clobber = asm.getClobber();
List<RegisterAllocation.Register> clobberRegisters = new ArrayList<>();
if(clobber.isClobberA()) {
@ -130,10 +152,10 @@ public class Pass3AssertNoCpuClobber {
* @param block The block containing the statement
* @return The ASM code
*/
private AsmProgram getAsmProgram(Statement statement, ControlFlowBlock block) {
private AsmProgram getAsmProgram(Statement statement, ControlFlowBlock block, Pass4CodeGeneration.AsmCodegenAluState aluState) {
Pass4CodeGeneration codegen = new Pass4CodeGeneration(program);
AsmProgram asm = new AsmProgram();
codegen.generateStatementAsm(asm, block, statement, new Pass4CodeGeneration.AsmCodegenAluState());
codegen.generateStatementAsm(asm, block, statement, aluState);
return asm;
}

View File

@ -78,7 +78,7 @@ public class Pass3RegisterUplifting {
}
program.getScope().setAllocation(allocation);
Pass3AssertNoCpuClobber clobber = new Pass3AssertNoCpuClobber(program, log);
if (clobber.hasClobberProblem()) {
if (clobber.hasClobberProblem(false, register)) {
log.append("Uplift to " + register + " resulted in clobber.");
} else {
log.append("Uplift to " + register + " succesfull.");

View File

@ -31,12 +31,12 @@ public class Pass3ZeroPageAllocation {
}
// Coalesce over copy assignments
EquivalenceClassCopyCoalescer equivalenceClassCopyCoalescer = new EquivalenceClassCopyCoalescer(liveRangeEquivalenceClassSet);
equivalenceClassCopyCoalescer.visitGraph(program.getGraph());
log.append("Copy Coalesced equivalence classes");
for (LiveRangeEquivalenceClass liveRangeEquivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
log.append(liveRangeEquivalenceClass.toString());
}
//EquivalenceClassCopyCoalescer equivalenceClassCopyCoalescer = new EquivalenceClassCopyCoalescer(liveRangeEquivalenceClassSet);
//equivalenceClassCopyCoalescer.visitGraph(program.getGraph());
//log.append("Copy Coalesced equivalence classes");
//for (LiveRangeEquivalenceClass liveRangeEquivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
// log.append(liveRangeEquivalenceClass.toString());
//}
// Add all other variables one by one to an available equivalence class - or create a new one
EquivalenceClassAdder equivalenceClassAdder = new EquivalenceClassAdder(liveRangeEquivalenceClassSet);
@ -74,8 +74,8 @@ public class Pass3ZeroPageAllocation {
if (assignment.getlValue() instanceof VariableRef) {
VariableRef lValVar = (VariableRef) assignment.getlValue();
List<VariableRef> preferences = new ArrayList<>();
addPreference(preferences, assignment.getrValue1());
addPreference(preferences, assignment.getrValue2());
//addPreference(preferences, assignment.getrValue1());
//addPreference(preferences, assignment.getrValue2());
addToEquivalenceClassSet(lValVar, preferences);
}
return null;