From 47e8b6b2b9f7d79676195783fbb4e09956489660 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Mon, 31 Jul 2017 20:00:25 +0200 Subject: [PATCH] More fragments - a start at calculating value for ASM. --- .../kickc/asm/fragment/aby=_star_zpptrby1.asm | 2 + .../asm/fragment/coby1_lt_yby_then_la1.asm | 2 + .../kickc/asm/fragment/xby=_star_zpptrby1.asm | 3 ++ .../asm/fragment/xby=xby_minus_coby1.asm | 4 ++ .../asm/fragment/xby=zpby1_plus_zpby2.asm | 4 ++ .../kickc/asm/fragment/yby=_star_zpptrby1.asm | 3 ++ .../asm/fragment/yby=zpby1_plus_zpby2.asm | 4 ++ .../asm/fragment/zpby1=cowo1_staridx_aby.asm | 3 ++ .../asm/fragment/zpby1=cowo1_staridx_yby.asm | 2 + .../kickc/passes/Pass3AssertNoCpuClobber.java | 50 +++++++++++++------ .../kickc/passes/Pass3RegisterUplifting.java | 2 +- .../kickc/passes/Pass3ZeroPageAllocation.java | 16 +++--- 12 files changed, 72 insertions(+), 23 deletions(-) create mode 100644 src/main/java/dk/camelot64/kickc/asm/fragment/aby=_star_zpptrby1.asm create mode 100644 src/main/java/dk/camelot64/kickc/asm/fragment/coby1_lt_yby_then_la1.asm create mode 100644 src/main/java/dk/camelot64/kickc/asm/fragment/xby=_star_zpptrby1.asm create mode 100644 src/main/java/dk/camelot64/kickc/asm/fragment/xby=xby_minus_coby1.asm create mode 100644 src/main/java/dk/camelot64/kickc/asm/fragment/xby=zpby1_plus_zpby2.asm create mode 100644 src/main/java/dk/camelot64/kickc/asm/fragment/yby=_star_zpptrby1.asm create mode 100644 src/main/java/dk/camelot64/kickc/asm/fragment/yby=zpby1_plus_zpby2.asm create mode 100644 src/main/java/dk/camelot64/kickc/asm/fragment/zpby1=cowo1_staridx_aby.asm create mode 100644 src/main/java/dk/camelot64/kickc/asm/fragment/zpby1=cowo1_staridx_yby.asm diff --git a/src/main/java/dk/camelot64/kickc/asm/fragment/aby=_star_zpptrby1.asm b/src/main/java/dk/camelot64/kickc/asm/fragment/aby=_star_zpptrby1.asm new file mode 100644 index 000000000..b4b2a384b --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/asm/fragment/aby=_star_zpptrby1.asm @@ -0,0 +1,2 @@ +ldy #0 +lda ({zpptrby1}),y diff --git a/src/main/java/dk/camelot64/kickc/asm/fragment/coby1_lt_yby_then_la1.asm b/src/main/java/dk/camelot64/kickc/asm/fragment/coby1_lt_yby_then_la1.asm new file mode 100644 index 000000000..bd89b4333 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/asm/fragment/coby1_lt_yby_then_la1.asm @@ -0,0 +1,2 @@ +cpy #{coby1} +bcs {la1} \ No newline at end of file diff --git a/src/main/java/dk/camelot64/kickc/asm/fragment/xby=_star_zpptrby1.asm b/src/main/java/dk/camelot64/kickc/asm/fragment/xby=_star_zpptrby1.asm new file mode 100644 index 000000000..5fe2fdee6 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/asm/fragment/xby=_star_zpptrby1.asm @@ -0,0 +1,3 @@ +ldy #0 +lda ({zpptrby1}),y +tax diff --git a/src/main/java/dk/camelot64/kickc/asm/fragment/xby=xby_minus_coby1.asm b/src/main/java/dk/camelot64/kickc/asm/fragment/xby=xby_minus_coby1.asm new file mode 100644 index 000000000..a865f9a6f --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/asm/fragment/xby=xby_minus_coby1.asm @@ -0,0 +1,4 @@ +txa +sec +sbc #{coby1} +tax \ No newline at end of file diff --git a/src/main/java/dk/camelot64/kickc/asm/fragment/xby=zpby1_plus_zpby2.asm b/src/main/java/dk/camelot64/kickc/asm/fragment/xby=zpby1_plus_zpby2.asm new file mode 100644 index 000000000..ca6a66dea --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/asm/fragment/xby=zpby1_plus_zpby2.asm @@ -0,0 +1,4 @@ +lda {zpby1} +clc +adc {zpby2} +tax \ No newline at end of file diff --git a/src/main/java/dk/camelot64/kickc/asm/fragment/yby=_star_zpptrby1.asm b/src/main/java/dk/camelot64/kickc/asm/fragment/yby=_star_zpptrby1.asm new file mode 100644 index 000000000..ff753ae35 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/asm/fragment/yby=_star_zpptrby1.asm @@ -0,0 +1,3 @@ +ldy #0 +lda ({zpptrby1}),y +tay diff --git a/src/main/java/dk/camelot64/kickc/asm/fragment/yby=zpby1_plus_zpby2.asm b/src/main/java/dk/camelot64/kickc/asm/fragment/yby=zpby1_plus_zpby2.asm new file mode 100644 index 000000000..a44106784 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/asm/fragment/yby=zpby1_plus_zpby2.asm @@ -0,0 +1,4 @@ +lda {zpby1} +clc +adc {zpby2} +tay \ No newline at end of file diff --git a/src/main/java/dk/camelot64/kickc/asm/fragment/zpby1=cowo1_staridx_aby.asm b/src/main/java/dk/camelot64/kickc/asm/fragment/zpby1=cowo1_staridx_aby.asm new file mode 100644 index 000000000..22178ba8d --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/asm/fragment/zpby1=cowo1_staridx_aby.asm @@ -0,0 +1,3 @@ +tax +lda {cowo1},x +sta {zpby1} \ No newline at end of file diff --git a/src/main/java/dk/camelot64/kickc/asm/fragment/zpby1=cowo1_staridx_yby.asm b/src/main/java/dk/camelot64/kickc/asm/fragment/zpby1=cowo1_staridx_yby.asm new file mode 100644 index 000000000..620a8d8a1 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/asm/fragment/zpby1=cowo1_staridx_yby.asm @@ -0,0 +1,2 @@ +lda {cowo1},y +sta {zpby1} \ No newline at end of file diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass3AssertNoCpuClobber.java b/src/main/java/dk/camelot64/kickc/passes/Pass3AssertNoCpuClobber.java index 49c59b795..2c50a2f37 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass3AssertNoCpuClobber.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass3AssertNoCpuClobber.java @@ -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 clobberRegisters = getClobberedRegisters(statement, block); + AsmProgram asm = getAsmProgram(statement, block, aluState); + Collection clobberRegisters = getClobberedRegisters(asm); // Find alive variables List 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 getClobberedRegisters(Statement statement, ControlFlowBlock block) { - AsmProgram asm = getAsmProgram(statement, block); + private Collection getClobberedRegisters(AsmProgram asm) { AsmClobber clobber = asm.getClobber(); List 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; } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass3RegisterUplifting.java b/src/main/java/dk/camelot64/kickc/passes/Pass3RegisterUplifting.java index a16bb7505..9b9547557 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass3RegisterUplifting.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass3RegisterUplifting.java @@ -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."); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass3ZeroPageAllocation.java b/src/main/java/dk/camelot64/kickc/passes/Pass3ZeroPageAllocation.java index 5ab680c1f..1058d59aa 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass3ZeroPageAllocation.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass3ZeroPageAllocation.java @@ -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 preferences = new ArrayList<>(); - addPreference(preferences, assignment.getrValue1()); - addPreference(preferences, assignment.getrValue2()); + //addPreference(preferences, assignment.getrValue1()); + //addPreference(preferences, assignment.getrValue2()); addToEquivalenceClassSet(lValVar, preferences); } return null;