diff --git a/src/main/java/dk/camelot64/kickc/model/Registers.java b/src/main/java/dk/camelot64/kickc/model/Registers.java index 8c4d4bf49..d2c5ebc4a 100644 --- a/src/main/java/dk/camelot64/kickc/model/Registers.java +++ b/src/main/java/dk/camelot64/kickc/model/Registers.java @@ -20,6 +20,19 @@ public class Registers { return new RegisterALUByte(); } + public static Register getRegister(String name) { + switch(name.toUpperCase()) { + case "A": + return getRegisterA(); + case "X": + return getRegisterX(); + case "Y": + return getRegisterY(); + default: + return null; + } + } + /** The register type. */ public enum RegisterType { REG_A_BYTE, diff --git a/src/main/java/dk/camelot64/kickc/model/Scope.java b/src/main/java/dk/camelot64/kickc/model/Scope.java index 4280069ae..4b0d05a4b 100644 --- a/src/main/java/dk/camelot64/kickc/model/Scope.java +++ b/src/main/java/dk/camelot64/kickc/model/Scope.java @@ -323,31 +323,34 @@ public abstract class Scope implements Symbol { } else { if(symbolClass == null || symbolClass.isInstance(symbol)) { res.append(symbol.toString(program)); - if(symbol instanceof Variable) { - Variable var = (Variable) symbol; - String asmName = var.getAsmName(); + if(symbol instanceof SymbolVariable) { + SymbolVariable symVar = (SymbolVariable) symbol; + String asmName = symVar.getAsmName(); if(asmName != null) { res.append(" " + asmName); } - Registers.Register register = var.getAllocation(); - if(register != null) { - res.append(" " + register); + + Registers.Register declRegister = symVar.getDeclaredRegister(); + if(declRegister != null) { + res.append(" !" + declRegister); } - } - if(symbol instanceof Variable && registerWeights != null) { - Variable var = (Variable) symbol; - Double weight = registerWeights.getWeight(var.getRef()); - if(weight != null) { - res.append(" " + weight); + if(symbol instanceof Variable) { + Variable var = (Variable) symVar; + Registers.Register register = var.getAllocation(); + if(register != null && !register.equals(declRegister)) { + res.append(" " + register); + } + if(registerWeights != null) { + Double weight = registerWeights.getWeight(var.getRef()); + if(weight != null) { + res.append(" " + weight); + } + } } - } - if(symbol instanceof ConstantVar) { - ConstantVar constantVar = (ConstantVar) symbol; - String asmName = constantVar.getAsmName(); - if(asmName != null) { - res.append(" " + asmName); + if(symbol instanceof ConstantVar) { + ConstantVar constVar = (ConstantVar) symbol; + res.append(" = " + constVar.getValue().toString(program)); } - res.append(" = " + constantVar.getValue().toString(program)); } res.append("\n"); } diff --git a/src/main/java/dk/camelot64/kickc/model/SymbolVariable.java b/src/main/java/dk/camelot64/kickc/model/SymbolVariable.java index bbf834074..5a2ce6dcf 100644 --- a/src/main/java/dk/camelot64/kickc/model/SymbolVariable.java +++ b/src/main/java/dk/camelot64/kickc/model/SymbolVariable.java @@ -24,6 +24,9 @@ public abstract class SymbolVariable implements Symbol { /** Specifies that the variable must be aligned in memory. Only allowed for arrays & strings. */ private Integer declaredAlignment; + /** Specifies the register the variable must be put into during execution. */ + private Registers.Register declaredRegister; + public SymbolVariable(String name, Scope scope, SymbolType type) { this.name = name; this.scope = scope; @@ -111,6 +114,14 @@ public abstract class SymbolVariable implements Symbol { this.declaredAlignment = declaredAlignment; } + public Registers.Register getDeclaredRegister() { + return declaredRegister; + } + + public void setDeclaredRegister(Registers.Register declaredRegister) { + this.declaredRegister = declaredRegister; + } + @Override public String toString() { return toString(null); diff --git a/src/main/java/dk/camelot64/kickc/model/Variable.java b/src/main/java/dk/camelot64/kickc/model/Variable.java index 7cb2b3c39..2571fc0f6 100644 --- a/src/main/java/dk/camelot64/kickc/model/Variable.java +++ b/src/main/java/dk/camelot64/kickc/model/Variable.java @@ -29,9 +29,7 @@ public abstract class Variable extends SymbolVariable { if(this == o) return true; if(o == null || getClass() != o.getClass()) return false; if(!super.equals(o)) return false; - Variable variable = (Variable) o; - return allocation != null ? allocation.equals(variable.allocation) : variable.allocation == null; } diff --git a/src/main/java/dk/camelot64/kickc/model/VariableVersion.java b/src/main/java/dk/camelot64/kickc/model/VariableVersion.java index 68fbd2198..5afba2476 100644 --- a/src/main/java/dk/camelot64/kickc/model/VariableVersion.java +++ b/src/main/java/dk/camelot64/kickc/model/VariableVersion.java @@ -8,6 +8,7 @@ public class VariableVersion extends Variable { public VariableVersion(VariableUnversioned versionOf, int version) { super(versionOf.getLocalName() + "#" + version, versionOf.getScope(), versionOf.getType()); this.setDeclaredAlignment(versionOf.getDeclaredAlignment()); + this.setDeclaredRegister(versionOf.getDeclaredRegister()); this.versionOfName = versionOf.getLocalName(); } @@ -47,9 +48,7 @@ public class VariableVersion extends Variable { if(!super.equals(o)) { return false; } - VariableVersion that = (VariableVersion) o; - return versionOfName != null ? versionOfName.equals(that.versionOfName) : that.versionOfName == null; } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java index 6a43cdbae..5d00a4110 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java @@ -154,6 +154,13 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor { } else { throw new CompileError("Error! Cannot align variable that is not a string or an array " + lValue.toString(program)); } + } else if(directive instanceof DirectiveRegister) { + DirectiveRegister directiveRegister = (DirectiveRegister) directive; + Registers.Register register = Registers.getRegister(directiveRegister.getName()); + if(register==null) { + throw new CompileError("Error! Unknown register " + directiveRegister.getName()); + } + lValue.setDeclaredRegister(register); } else { throw new CompileError("Unknown directive " + directive); } @@ -198,6 +205,12 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor { return new DirectiveAlign(alignment.intValue()); } + @Override + public Directive visitDirectiveRegister(KickCParser.DirectiveRegisterContext ctx) { + String name = ctx.NAME().getText(); + return new DirectiveRegister(name); + } + @Override public Void visitStmtSeq(KickCParser.StmtSeqContext ctx) { for(int i = 0; i < ctx.getChildCount(); i++) { @@ -655,6 +668,24 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor { } } + /** Variable memory alignment. */ + private static class DirectiveRegister implements Directive { + private String name; + + public DirectiveRegister(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + + private static class PrePostModifierHandler extends KickCBaseVisitor { private List postMods; diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantIdentification.java b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantIdentification.java index c272760c3..367e39b22 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantIdentification.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantIdentification.java @@ -77,6 +77,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization { constType, constVal); constantVar.setDeclaredAlignment(variable.getDeclaredAlignment()); + constantVar.setDeclaredRegister(variable.getDeclaredRegister()); constScope.remove(variable); constScope.add(constantVar); constAliases.put(constRef, constantVar.getRef()); diff --git a/src/test/java/dk/camelot64/kickc/test/kc/var-register.kc b/src/test/java/dk/camelot64/kickc/test/kc/var-register.kc index 5d183f76c..eaa717683 100644 --- a/src/test/java/dk/camelot64/kickc/test/kc/var-register.kc +++ b/src/test/java/dk/camelot64/kickc/test/kc/var-register.kc @@ -4,13 +4,14 @@ void main() { for( register(X) byte x: 0..100 ) { for( byte y: 0..100 ) { for( byte a: 0..100 ) { - print(y, a+x); + register(A) byte val1 = a+x; + print(y, val1); } } } } -void print(byte idx, register(y) byte val) { +void print(byte idx, byte val) { byte* SCREEN = $0400; SCREEN[idx] = val; } \ No newline at end of file diff --git a/src/test/java/dk/camelot64/kickc/test/ref/var-register.asm b/src/test/java/dk/camelot64/kickc/test/ref/var-register.asm index fd0244d82..22bdd56fc 100644 --- a/src/test/java/dk/camelot64/kickc/test/ref/var-register.asm +++ b/src/test/java/dk/camelot64/kickc/test/ref/var-register.asm @@ -3,23 +3,27 @@ .pc = $80d "Program" jsr main main: { + .label y = 3 .label x = 2 lda #0 sta x b1: - ldy #0 + lda #0 + sta y b2: ldx #0 b3: txa clc adc x + tay jsr print inx cpx #$65 bne b3 - iny - cpy #$65 + inc y + lda y + cmp #$65 bne b2 inc x lda x @@ -29,6 +33,9 @@ main: { } print: { .const SCREEN = $400 + .label idx = 3 + tya + ldy idx sta SCREEN,y rts } diff --git a/src/test/java/dk/camelot64/kickc/test/ref/var-register.cfg b/src/test/java/dk/camelot64/kickc/test/ref/var-register.cfg index 5af912f2b..34af32aa6 100644 --- a/src/test/java/dk/camelot64/kickc/test/ref/var-register.cfg +++ b/src/test/java/dk/camelot64/kickc/test/ref/var-register.cfg @@ -18,28 +18,29 @@ main::@2: scope:[main] from main::@1 main::@4 to:main::@3 main::@3: scope:[main] from main::@2 main::@7 [7] (byte) main::a#2 ← phi( main::@2/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@7/(byte) main::a#1 ) [ main::x#7 main::y#4 main::a#2 ] ( main:2 [ main::x#7 main::y#4 main::a#2 ] ) - [8] (byte) print::val#0 ← (byte) main::a#2 + (byte) main::x#7 [ main::x#7 main::y#4 main::a#2 print::val#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 print::val#0 ] ) - [9] (byte) print::idx#0 ← (byte) main::y#4 [ main::x#7 main::y#4 main::a#2 print::val#0 print::idx#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 print::val#0 print::idx#0 ] ) - [10] call print param-assignment [ main::x#7 main::y#4 main::a#2 ] ( main:2 [ main::x#7 main::y#4 main::a#2 ] ) + [8] (byte) main::val1#0 ← (byte) main::a#2 + (byte) main::x#7 [ main::x#7 main::y#4 main::a#2 main::val1#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 main::val1#0 ] ) + [9] (byte) print::idx#0 ← (byte) main::y#4 [ main::x#7 main::y#4 main::a#2 main::val1#0 print::idx#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 main::val1#0 print::idx#0 ] ) + [10] (byte) print::val#0 ← (byte) main::val1#0 [ main::x#7 main::y#4 main::a#2 print::idx#0 print::val#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 print::idx#0 print::val#0 ] ) + [11] call print param-assignment [ main::x#7 main::y#4 main::a#2 ] ( main:2 [ main::x#7 main::y#4 main::a#2 ] ) to:main::@7 main::@7: scope:[main] from main::@3 - [11] (byte) main::a#1 ← ++ (byte) main::a#2 [ main::x#7 main::y#4 main::a#1 ] ( main:2 [ main::x#7 main::y#4 main::a#1 ] ) - [12] if((byte) main::a#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@3 [ main::x#7 main::y#4 main::a#1 ] ( main:2 [ main::x#7 main::y#4 main::a#1 ] ) + [12] (byte) main::a#1 ← ++ (byte) main::a#2 [ main::x#7 main::y#4 main::a#1 ] ( main:2 [ main::x#7 main::y#4 main::a#1 ] ) + [13] if((byte) main::a#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@3 [ main::x#7 main::y#4 main::a#1 ] ( main:2 [ main::x#7 main::y#4 main::a#1 ] ) to:main::@4 main::@4: scope:[main] from main::@7 - [13] (byte) main::y#1 ← ++ (byte) main::y#4 [ main::x#7 main::y#1 ] ( main:2 [ main::x#7 main::y#1 ] ) - [14] if((byte) main::y#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@2 [ main::x#7 main::y#1 ] ( main:2 [ main::x#7 main::y#1 ] ) + [14] (byte) main::y#1 ← ++ (byte) main::y#4 [ main::x#7 main::y#1 ] ( main:2 [ main::x#7 main::y#1 ] ) + [15] if((byte) main::y#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@2 [ main::x#7 main::y#1 ] ( main:2 [ main::x#7 main::y#1 ] ) to:main::@5 main::@5: scope:[main] from main::@4 - [15] (byte) main::x#1 ← ++ (byte) main::x#7 [ main::x#1 ] ( main:2 [ main::x#1 ] ) - [16] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@1 [ main::x#1 ] ( main:2 [ main::x#1 ] ) + [16] (byte) main::x#1 ← ++ (byte) main::x#7 [ main::x#1 ] ( main:2 [ main::x#1 ] ) + [17] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@1 [ main::x#1 ] ( main:2 [ main::x#1 ] ) to:main::@return main::@return: scope:[main] from main::@5 - [17] return [ ] ( main:2 [ ] ) + [18] return [ ] ( main:2 [ ] ) to:@return print: scope:[print] from main::@3 - [18] *((const byte*) print::SCREEN#0 + (byte) print::idx#0) ← (byte) print::val#0 [ ] ( main:2::print:10 [ main::x#7 main::y#4 main::a#2 ] ) + [19] *((const byte*) print::SCREEN#0 + (byte) print::idx#0) ← (byte) print::val#0 [ ] ( main:2::print:11 [ main::x#7 main::y#4 main::a#2 ] ) to:print::@return print::@return: scope:[print] from print - [19] return [ ] ( main:2::print:10 [ main::x#7 main::y#4 main::a#2 ] ) + [20] return [ ] ( main:2::print:11 [ main::x#7 main::y#4 main::a#2 ] ) to:@return diff --git a/src/test/java/dk/camelot64/kickc/test/ref/var-register.log b/src/test/java/dk/camelot64/kickc/test/ref/var-register.log index 45f6c6512..7e4485f09 100644 --- a/src/test/java/dk/camelot64/kickc/test/ref/var-register.log +++ b/src/test/java/dk/camelot64/kickc/test/ref/var-register.log @@ -5,13 +5,14 @@ void main() { for( register(X) byte x: 0..100 ) { for( byte y: 0..100 ) { for( byte a: 0..100 ) { - print(y, a+x); + register(A) byte val1 = a+x; + print(y, val1); } } } } -void print(byte idx, register(y) byte val) { +void print(byte idx, byte val) { byte* SCREEN = $0400; SCREEN[idx] = val; } @@ -25,7 +26,8 @@ main::@2: (byte) main::a ← (byte/signed byte/word/signed word/dword/signed dword) 0 main::@3: (byte/word~) main::$0 ← (byte) main::a + (byte) main::x - (void~) main::$1 ← call print (byte) main::y (byte/word~) main::$0 + (byte) main::val1 ← (byte/word~) main::$0 + (void~) main::$1 ← call print (byte) main::y (byte) main::val1 (byte) main::a ← ++ (byte) main::a (boolean~) main::$2 ← (byte) main::a != (byte/signed byte/word/signed word/dword/signed dword) 101 if((boolean~) main::$2) goto main::@3 @@ -58,6 +60,7 @@ SYMBOLS (label) main::@3 (label) main::@return (byte) main::a +(byte) main::val1 !reg byte a (byte) main::x (byte) main::y (void()) print((byte) print::idx , (byte) print::val) @@ -81,7 +84,8 @@ main::@2: scope:[main] from main::@1 main::@4 to:main::@3 main::@3: scope:[main] from main::@2 main::@3 (byte/word~) main::$0 ← (byte) main::a + (byte) main::x - (void~) main::$1 ← call print (byte) main::y (byte/word~) main::$0 + (byte) main::val1 ← (byte/word~) main::$0 + (void~) main::$1 ← call print (byte) main::y (byte) main::val1 (byte) main::a ← ++ (byte) main::a (boolean~) main::$2 ← (byte) main::a != (byte/signed byte/word/signed word/dword/signed dword) 101 if((boolean~) main::$2) goto main::@3 @@ -144,8 +148,9 @@ main::@3: scope:[main] from main::@2 main::@7 (byte) main::x#2 ← phi( main::@2/(byte) main::x#4 main::@7/(byte) main::x#5 ) (byte) main::a#2 ← phi( main::@2/(byte) main::a#0 main::@7/(byte) main::a#1 ) (byte/word~) main::$0 ← (byte) main::a#2 + (byte) main::x#2 + (byte) main::val1#0 ← (byte/word~) main::$0 (byte) print::idx#0 ← (byte) main::y#2 - (byte) print::val#0 ← (byte/word~) main::$0 + (byte) print::val#0 ← (byte) main::val1#0 call print param-assignment to:main::@7 main::@7: scope:[main] from main::@3 @@ -210,6 +215,8 @@ SYMBOL TABLE SSA (byte) main::a#1 (byte) main::a#2 (byte) main::a#3 +(byte) main::val1 !reg byte a +(byte) main::val1#0 !reg byte a (byte) main::x (byte) main::x#0 (byte) main::x#1 @@ -241,14 +248,16 @@ OPTIMIZING CONTROL FLOW GRAPH Culled Empty Block (label) @3 Succesful SSA optimization Pass2CullEmptyBlocks Not aliassing across scopes: print::idx#0 main::y#2 +Not aliassing across scopes: print::val#0 main::val1#0 Not aliassing across scopes: print::val#1 print::val#0 Not aliassing across scopes: print::idx#1 print::idx#0 -Alias (byte) print::val#0 = (byte/word~) main::$0 +Alias (byte) main::val1#0 = (byte/word~) main::$0 Alias (byte) main::a#2 = (byte) main::a#3 Alias (byte) main::x#2 = (byte) main::x#5 (byte) main::x#6 (byte) main::x#3 Alias (byte) main::y#2 = (byte) main::y#5 (byte) main::y#3 Succesful SSA optimization Pass2AliasElimination Not aliassing across scopes: print::idx#0 main::y#2 +Not aliassing across scopes: print::val#0 main::val1#0 Not aliassing across scopes: print::val#1 print::val#0 Not aliassing across scopes: print::idx#1 print::idx#0 Self Phi Eliminated (byte) main::x#2 @@ -269,11 +278,13 @@ Constant (const byte) main::a#0 = 0 Constant (const byte*) print::SCREEN#0 = ((byte*))1024 Succesful SSA optimization Pass2ConstantIdentification Not aliassing across scopes: print::idx#0 main::y#4 +Not aliassing across scopes: print::val#0 main::val1#0 Self Phi Eliminated (byte) main::x#4 Succesful SSA optimization Pass2SelfPhiElimination Redundant Phi (byte) main::x#4 (byte) main::x#7 Succesful SSA optimization Pass2RedundantPhiElimination Not aliassing across scopes: print::idx#0 main::y#4 +Not aliassing across scopes: print::val#0 main::val1#0 OPTIMIZING CONTROL FLOW GRAPH Inlining constant with var siblings (const byte) main::x#0 Inlining constant with var siblings (const byte) main::x#0 @@ -296,7 +307,7 @@ Adding NOP phi() at start of @end Adding NOP phi() at start of main CALL GRAPH Calls in [] to main:2 -Calls in [main] to print:10 +Calls in [main] to print:11 Propagating live ranges... Propagating live ranges... @@ -305,10 +316,11 @@ Propagating live ranges... Propagating live ranges... Propagating live ranges... Propagating live ranges... +Propagating live ranges... Created 3 initial phi equivalence classes -Coalesced [18] main::x#8 ← main::x#1 -Coalesced [19] main::y#6 ← main::y#1 -Coalesced [20] main::a#4 ← main::a#1 +Coalesced [19] main::x#8 ← main::x#1 +Coalesced [20] main::y#6 ← main::y#1 +Coalesced [21] main::a#4 ← main::a#1 Coalesced down to 3 phi equivalence classes Culled Empty Block (label) main::@8 Culled Empty Block (label) main::@9 @@ -324,6 +336,7 @@ Propagating live ranges... Propagating live ranges... Propagating live ranges... Propagating live ranges... +Propagating live ranges... FINAL CONTROL FLOW GRAPH @begin: scope:[] from @@ -346,30 +359,31 @@ main::@2: scope:[main] from main::@1 main::@4 to:main::@3 main::@3: scope:[main] from main::@2 main::@7 [7] (byte) main::a#2 ← phi( main::@2/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@7/(byte) main::a#1 ) [ main::x#7 main::y#4 main::a#2 ] ( main:2 [ main::x#7 main::y#4 main::a#2 ] ) - [8] (byte) print::val#0 ← (byte) main::a#2 + (byte) main::x#7 [ main::x#7 main::y#4 main::a#2 print::val#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 print::val#0 ] ) - [9] (byte) print::idx#0 ← (byte) main::y#4 [ main::x#7 main::y#4 main::a#2 print::val#0 print::idx#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 print::val#0 print::idx#0 ] ) - [10] call print param-assignment [ main::x#7 main::y#4 main::a#2 ] ( main:2 [ main::x#7 main::y#4 main::a#2 ] ) + [8] (byte) main::val1#0 ← (byte) main::a#2 + (byte) main::x#7 [ main::x#7 main::y#4 main::a#2 main::val1#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 main::val1#0 ] ) + [9] (byte) print::idx#0 ← (byte) main::y#4 [ main::x#7 main::y#4 main::a#2 main::val1#0 print::idx#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 main::val1#0 print::idx#0 ] ) + [10] (byte) print::val#0 ← (byte) main::val1#0 [ main::x#7 main::y#4 main::a#2 print::idx#0 print::val#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 print::idx#0 print::val#0 ] ) + [11] call print param-assignment [ main::x#7 main::y#4 main::a#2 ] ( main:2 [ main::x#7 main::y#4 main::a#2 ] ) to:main::@7 main::@7: scope:[main] from main::@3 - [11] (byte) main::a#1 ← ++ (byte) main::a#2 [ main::x#7 main::y#4 main::a#1 ] ( main:2 [ main::x#7 main::y#4 main::a#1 ] ) - [12] if((byte) main::a#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@3 [ main::x#7 main::y#4 main::a#1 ] ( main:2 [ main::x#7 main::y#4 main::a#1 ] ) + [12] (byte) main::a#1 ← ++ (byte) main::a#2 [ main::x#7 main::y#4 main::a#1 ] ( main:2 [ main::x#7 main::y#4 main::a#1 ] ) + [13] if((byte) main::a#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@3 [ main::x#7 main::y#4 main::a#1 ] ( main:2 [ main::x#7 main::y#4 main::a#1 ] ) to:main::@4 main::@4: scope:[main] from main::@7 - [13] (byte) main::y#1 ← ++ (byte) main::y#4 [ main::x#7 main::y#1 ] ( main:2 [ main::x#7 main::y#1 ] ) - [14] if((byte) main::y#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@2 [ main::x#7 main::y#1 ] ( main:2 [ main::x#7 main::y#1 ] ) + [14] (byte) main::y#1 ← ++ (byte) main::y#4 [ main::x#7 main::y#1 ] ( main:2 [ main::x#7 main::y#1 ] ) + [15] if((byte) main::y#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@2 [ main::x#7 main::y#1 ] ( main:2 [ main::x#7 main::y#1 ] ) to:main::@5 main::@5: scope:[main] from main::@4 - [15] (byte) main::x#1 ← ++ (byte) main::x#7 [ main::x#1 ] ( main:2 [ main::x#1 ] ) - [16] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@1 [ main::x#1 ] ( main:2 [ main::x#1 ] ) + [16] (byte) main::x#1 ← ++ (byte) main::x#7 [ main::x#1 ] ( main:2 [ main::x#1 ] ) + [17] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@1 [ main::x#1 ] ( main:2 [ main::x#1 ] ) to:main::@return main::@return: scope:[main] from main::@5 - [17] return [ ] ( main:2 [ ] ) + [18] return [ ] ( main:2 [ ] ) to:@return print: scope:[print] from main::@3 - [18] *((const byte*) print::SCREEN#0 + (byte) print::idx#0) ← (byte) print::val#0 [ ] ( main:2::print:10 [ main::x#7 main::y#4 main::a#2 ] ) + [19] *((const byte*) print::SCREEN#0 + (byte) print::idx#0) ← (byte) print::val#0 [ ] ( main:2::print:11 [ main::x#7 main::y#4 main::a#2 ] ) to:print::@return print::@return: scope:[print] from print - [19] return [ ] ( main:2::print:10 [ main::x#7 main::y#4 main::a#2 ] ) + [20] return [ ] ( main:2::print:11 [ main::x#7 main::y#4 main::a#2 ] ) to:@return DOMINATORS @@ -414,37 +428,42 @@ VARIABLE REGISTER WEIGHTS (void()) main() (byte) main::a (byte) main::a#1 1501.5 -(byte) main::a#2 750.75 +(byte) main::a#2 600.5999999999999 +(byte) main::val1 !reg byte a +(byte) main::val1#0 !reg byte a 1001.0 (byte) main::x (byte) main::x#1 16.5 -(byte) main::x#7 102.29999999999998 +(byte) main::x#7 93.0 (byte) main::y (byte) main::y#1 151.5 -(byte) main::y#4 171.85714285714283 +(byte) main::y#4 150.375 (void()) print((byte) print::idx , (byte) print::val) (byte*) print::SCREEN (byte) print::idx -(byte) print::idx#0 1003.0 +(byte) print::idx#0 501.5 (byte) print::val -(byte) print::val#0 501.5 +(byte) print::val#0 1003.0 Initial phi equivalence classes [ main::x#7 main::x#1 ] [ main::y#4 main::y#1 ] [ main::a#2 main::a#1 ] -Added variable print::val#0 to zero page equivalence class [ print::val#0 ] +Added variable main::val1#0 to zero page equivalence class [ main::val1#0 ] Added variable print::idx#0 to zero page equivalence class [ print::idx#0 ] +Added variable print::val#0 to zero page equivalence class [ print::val#0 ] Complete equivalence classes [ main::x#7 main::x#1 ] [ main::y#4 main::y#1 ] [ main::a#2 main::a#1 ] -[ print::val#0 ] +[ main::val1#0 ] [ print::idx#0 ] +[ print::val#0 ] Allocated zp ZP_BYTE:2 [ main::x#7 main::x#1 ] Allocated zp ZP_BYTE:3 [ main::y#4 main::y#1 ] Allocated zp ZP_BYTE:4 [ main::a#2 main::a#1 ] -Allocated zp ZP_BYTE:5 [ print::val#0 ] +Allocated zp ZP_BYTE:5 [ main::val1#0 ] Allocated zp ZP_BYTE:6 [ print::idx#0 ] +Allocated zp ZP_BYTE:7 [ print::val#0 ] INITIAL ASM //SEG0 Basic Upstart @@ -470,6 +489,7 @@ bend_from_b2: bend: //SEG9 main main: { + .label val1 = 5 .label a = 4 .label y = 3 .label x = 2 @@ -509,62 +529,65 @@ main: { jmp b3 //SEG24 main::@3 b3: - //SEG25 [8] (byte) print::val#0 ← (byte) main::a#2 + (byte) main::x#7 [ main::x#7 main::y#4 main::a#2 print::val#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 print::val#0 ] ) -- vbuz1=vbuz2_plus_vbuz3 + //SEG25 [8] (byte) main::val1#0 ← (byte) main::a#2 + (byte) main::x#7 [ main::x#7 main::y#4 main::a#2 main::val1#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 main::val1#0 ] ) -- vbuz1=vbuz2_plus_vbuz3 lda a clc adc x - sta print.val - //SEG26 [9] (byte) print::idx#0 ← (byte) main::y#4 [ main::x#7 main::y#4 main::a#2 print::val#0 print::idx#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 print::val#0 print::idx#0 ] ) -- vbuz1=vbuz2 + sta val1 + //SEG26 [9] (byte) print::idx#0 ← (byte) main::y#4 [ main::x#7 main::y#4 main::a#2 main::val1#0 print::idx#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 main::val1#0 print::idx#0 ] ) -- vbuz1=vbuz2 lda y sta print.idx - //SEG27 [10] call print param-assignment [ main::x#7 main::y#4 main::a#2 ] ( main:2 [ main::x#7 main::y#4 main::a#2 ] ) + //SEG27 [10] (byte) print::val#0 ← (byte) main::val1#0 [ main::x#7 main::y#4 main::a#2 print::idx#0 print::val#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 print::idx#0 print::val#0 ] ) -- vbuz1=vbuz2 + lda val1 + sta print.val + //SEG28 [11] call print param-assignment [ main::x#7 main::y#4 main::a#2 ] ( main:2 [ main::x#7 main::y#4 main::a#2 ] ) jsr print jmp b7 - //SEG28 main::@7 + //SEG29 main::@7 b7: - //SEG29 [11] (byte) main::a#1 ← ++ (byte) main::a#2 [ main::x#7 main::y#4 main::a#1 ] ( main:2 [ main::x#7 main::y#4 main::a#1 ] ) -- vbuz1=_inc_vbuz1 + //SEG30 [12] (byte) main::a#1 ← ++ (byte) main::a#2 [ main::x#7 main::y#4 main::a#1 ] ( main:2 [ main::x#7 main::y#4 main::a#1 ] ) -- vbuz1=_inc_vbuz1 inc a - //SEG30 [12] if((byte) main::a#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@3 [ main::x#7 main::y#4 main::a#1 ] ( main:2 [ main::x#7 main::y#4 main::a#1 ] ) -- vbuz1_neq_vbuc1_then_la1 + //SEG31 [13] if((byte) main::a#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@3 [ main::x#7 main::y#4 main::a#1 ] ( main:2 [ main::x#7 main::y#4 main::a#1 ] ) -- vbuz1_neq_vbuc1_then_la1 lda a cmp #$65 bne b3_from_b7 jmp b4 - //SEG31 main::@4 + //SEG32 main::@4 b4: - //SEG32 [13] (byte) main::y#1 ← ++ (byte) main::y#4 [ main::x#7 main::y#1 ] ( main:2 [ main::x#7 main::y#1 ] ) -- vbuz1=_inc_vbuz1 + //SEG33 [14] (byte) main::y#1 ← ++ (byte) main::y#4 [ main::x#7 main::y#1 ] ( main:2 [ main::x#7 main::y#1 ] ) -- vbuz1=_inc_vbuz1 inc y - //SEG33 [14] if((byte) main::y#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@2 [ main::x#7 main::y#1 ] ( main:2 [ main::x#7 main::y#1 ] ) -- vbuz1_neq_vbuc1_then_la1 + //SEG34 [15] if((byte) main::y#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@2 [ main::x#7 main::y#1 ] ( main:2 [ main::x#7 main::y#1 ] ) -- vbuz1_neq_vbuc1_then_la1 lda y cmp #$65 bne b2_from_b4 jmp b5 - //SEG34 main::@5 + //SEG35 main::@5 b5: - //SEG35 [15] (byte) main::x#1 ← ++ (byte) main::x#7 [ main::x#1 ] ( main:2 [ main::x#1 ] ) -- vbuz1=_inc_vbuz1 + //SEG36 [16] (byte) main::x#1 ← ++ (byte) main::x#7 [ main::x#1 ] ( main:2 [ main::x#1 ] ) -- vbuz1=_inc_vbuz1 inc x - //SEG36 [16] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@1 [ main::x#1 ] ( main:2 [ main::x#1 ] ) -- vbuz1_neq_vbuc1_then_la1 + //SEG37 [17] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@1 [ main::x#1 ] ( main:2 [ main::x#1 ] ) -- vbuz1_neq_vbuc1_then_la1 lda x cmp #$65 bne b1_from_b5 jmp breturn - //SEG37 main::@return + //SEG38 main::@return breturn: - //SEG38 [17] return [ ] ( main:2 [ ] ) + //SEG39 [18] return [ ] ( main:2 [ ] ) rts } -//SEG39 print +//SEG40 print print: { .const SCREEN = $400 .label idx = 6 - .label val = 5 - //SEG40 [18] *((const byte*) print::SCREEN#0 + (byte) print::idx#0) ← (byte) print::val#0 [ ] ( main:2::print:10 [ main::x#7 main::y#4 main::a#2 ] ) -- pbuc1_derefidx_vbuz1=vbuz2 + .label val = 7 + //SEG41 [19] *((const byte*) print::SCREEN#0 + (byte) print::idx#0) ← (byte) print::val#0 [ ] ( main:2::print:11 [ main::x#7 main::y#4 main::a#2 ] ) -- pbuc1_derefidx_vbuz1=vbuz2 lda val ldy idx sta SCREEN,y jmp breturn - //SEG41 print::@return + //SEG42 print::@return breturn: - //SEG42 [19] return [ ] ( main:2::print:10 [ main::x#7 main::y#4 main::a#2 ] ) + //SEG43 [20] return [ ] ( main:2::print:11 [ main::x#7 main::y#4 main::a#2 ] ) rts } @@ -572,21 +595,25 @@ REGISTER UPLIFT POTENTIAL REGISTERS Potential registers zp ZP_BYTE:2 [ main::x#7 main::x#1 ] : zp ZP_BYTE:2 , reg byte a , reg byte x , reg byte y , Potential registers zp ZP_BYTE:3 [ main::y#4 main::y#1 ] : zp ZP_BYTE:3 , reg byte a , reg byte x , reg byte y , Potential registers zp ZP_BYTE:4 [ main::a#2 main::a#1 ] : zp ZP_BYTE:4 , reg byte a , reg byte x , reg byte y , -Potential registers zp ZP_BYTE:5 [ print::val#0 ] : zp ZP_BYTE:5 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:5 [ main::val1#0 ] : zp ZP_BYTE:5 , reg byte a , reg byte x , reg byte y , Potential registers zp ZP_BYTE:6 [ print::idx#0 ] : zp ZP_BYTE:6 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:7 [ print::val#0 ] : zp ZP_BYTE:7 , reg byte a , reg byte x , reg byte y , REGISTER UPLIFT SCOPES -Uplift Scope [main] 2,252.25: zp ZP_BYTE:4 [ main::a#2 main::a#1 ] 323.36: zp ZP_BYTE:3 [ main::y#4 main::y#1 ] 118.8: zp ZP_BYTE:2 [ main::x#7 main::x#1 ] -Uplift Scope [print] 1,003: zp ZP_BYTE:6 [ print::idx#0 ] 501.5: zp ZP_BYTE:5 [ print::val#0 ] +Uplift Scope [main] 2,102.1: zp ZP_BYTE:4 [ main::a#2 main::a#1 ] 1,001: zp ZP_BYTE:5 [ main::val1#0 ] 301.88: zp ZP_BYTE:3 [ main::y#4 main::y#1 ] 109.5: zp ZP_BYTE:2 [ main::x#7 main::x#1 ] +Uplift Scope [print] 1,003: zp ZP_BYTE:7 [ print::val#0 ] 501.5: zp ZP_BYTE:6 [ print::idx#0 ] Uplift Scope [] -Uplifting [main] best 45453 combination reg byte x [ main::a#2 main::a#1 ] zp ZP_BYTE:3 [ main::y#4 main::y#1 ] zp ZP_BYTE:2 [ main::x#7 main::x#1 ] -Uplifting [print] best 39447 combination reg byte y [ print::idx#0 ] reg byte a [ print::val#0 ] -Uplifting [] best 39447 combination +Uplifting [main] best 47453 combination reg byte x [ main::a#2 main::a#1 ] reg byte y [ main::val1#0 ] zp ZP_BYTE:3 [ main::y#4 main::y#1 ] zp ZP_BYTE:2 [ main::x#7 main::x#1 ] +Uplifting [print] best 44452 combination reg byte y [ print::val#0 ] zp ZP_BYTE:6 [ print::idx#0 ] +Uplifting [] best 44452 combination +Attempting to uplift remaining variables inzp ZP_BYTE:6 [ print::idx#0 ] +Uplifting [print] best 44452 combination zp ZP_BYTE:6 [ print::idx#0 ] Attempting to uplift remaining variables inzp ZP_BYTE:3 [ main::y#4 main::y#1 ] -Uplifting [main] best 35547 combination reg byte y [ main::y#4 main::y#1 ] +Uplifting [main] best 44452 combination zp ZP_BYTE:3 [ main::y#4 main::y#1 ] Attempting to uplift remaining variables inzp ZP_BYTE:2 [ main::x#7 main::x#1 ] -Uplifting [main] best 35547 combination zp ZP_BYTE:2 [ main::x#7 main::x#1 ] +Uplifting [main] best 44452 combination zp ZP_BYTE:2 [ main::x#7 main::x#1 ] +Coalescing zero page register [ zp ZP_BYTE:3 [ main::y#4 main::y#1 ] ] with [ zp ZP_BYTE:6 [ print::idx#0 ] ] ASSEMBLER BEFORE OPTIMIZATION //SEG0 Basic Upstart @@ -612,6 +639,7 @@ bend_from_b2: bend: //SEG9 main main: { + .label y = 3 .label x = 2 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] b1_from_main: @@ -627,8 +655,9 @@ main: { b1: //SEG15 [6] phi from main::@1 to main::@2 [phi:main::@1->main::@2] b2_from_b1: - //SEG16 [6] phi (byte) main::y#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::@1->main::@2#0] -- vbuyy=vbuc1 - ldy #0 + //SEG16 [6] phi (byte) main::y#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::@1->main::@2#0] -- vbuz1=vbuc1 + lda #0 + sta y jmp b2 //SEG17 [6] phi from main::@4 to main::@2 [phi:main::@4->main::@2] b2_from_b4: @@ -647,54 +676,61 @@ main: { jmp b3 //SEG24 main::@3 b3: - //SEG25 [8] (byte) print::val#0 ← (byte) main::a#2 + (byte) main::x#7 [ main::x#7 main::y#4 main::a#2 print::val#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 print::val#0 ] ) -- vbuaa=vbuxx_plus_vbuz1 + //SEG25 [8] (byte) main::val1#0 ← (byte) main::a#2 + (byte) main::x#7 [ main::x#7 main::y#4 main::a#2 main::val1#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 main::val1#0 ] ) -- vbuyy=vbuxx_plus_vbuz1 txa clc adc x - //SEG26 [9] (byte) print::idx#0 ← (byte) main::y#4 [ main::x#7 main::y#4 main::a#2 print::val#0 print::idx#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 print::val#0 print::idx#0 ] ) - // (byte) print::idx#0 = (byte) main::y#4 // register copy reg byte y - //SEG27 [10] call print param-assignment [ main::x#7 main::y#4 main::a#2 ] ( main:2 [ main::x#7 main::y#4 main::a#2 ] ) + tay + //SEG26 [9] (byte) print::idx#0 ← (byte) main::y#4 [ main::x#7 main::y#4 main::a#2 main::val1#0 print::idx#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 main::val1#0 print::idx#0 ] ) + // (byte) print::idx#0 = (byte) main::y#4 // register copy zp ZP_BYTE:3 + //SEG27 [10] (byte) print::val#0 ← (byte) main::val1#0 [ main::x#7 main::y#4 main::a#2 print::idx#0 print::val#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 print::idx#0 print::val#0 ] ) + // (byte) print::val#0 = (byte) main::val1#0 // register copy reg byte y + //SEG28 [11] call print param-assignment [ main::x#7 main::y#4 main::a#2 ] ( main:2 [ main::x#7 main::y#4 main::a#2 ] ) jsr print jmp b7 - //SEG28 main::@7 + //SEG29 main::@7 b7: - //SEG29 [11] (byte) main::a#1 ← ++ (byte) main::a#2 [ main::x#7 main::y#4 main::a#1 ] ( main:2 [ main::x#7 main::y#4 main::a#1 ] ) -- vbuxx=_inc_vbuxx + //SEG30 [12] (byte) main::a#1 ← ++ (byte) main::a#2 [ main::x#7 main::y#4 main::a#1 ] ( main:2 [ main::x#7 main::y#4 main::a#1 ] ) -- vbuxx=_inc_vbuxx inx - //SEG30 [12] if((byte) main::a#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@3 [ main::x#7 main::y#4 main::a#1 ] ( main:2 [ main::x#7 main::y#4 main::a#1 ] ) -- vbuxx_neq_vbuc1_then_la1 + //SEG31 [13] if((byte) main::a#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@3 [ main::x#7 main::y#4 main::a#1 ] ( main:2 [ main::x#7 main::y#4 main::a#1 ] ) -- vbuxx_neq_vbuc1_then_la1 cpx #$65 bne b3_from_b7 jmp b4 - //SEG31 main::@4 + //SEG32 main::@4 b4: - //SEG32 [13] (byte) main::y#1 ← ++ (byte) main::y#4 [ main::x#7 main::y#1 ] ( main:2 [ main::x#7 main::y#1 ] ) -- vbuyy=_inc_vbuyy - iny - //SEG33 [14] if((byte) main::y#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@2 [ main::x#7 main::y#1 ] ( main:2 [ main::x#7 main::y#1 ] ) -- vbuyy_neq_vbuc1_then_la1 - cpy #$65 + //SEG33 [14] (byte) main::y#1 ← ++ (byte) main::y#4 [ main::x#7 main::y#1 ] ( main:2 [ main::x#7 main::y#1 ] ) -- vbuz1=_inc_vbuz1 + inc y + //SEG34 [15] if((byte) main::y#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@2 [ main::x#7 main::y#1 ] ( main:2 [ main::x#7 main::y#1 ] ) -- vbuz1_neq_vbuc1_then_la1 + lda y + cmp #$65 bne b2_from_b4 jmp b5 - //SEG34 main::@5 + //SEG35 main::@5 b5: - //SEG35 [15] (byte) main::x#1 ← ++ (byte) main::x#7 [ main::x#1 ] ( main:2 [ main::x#1 ] ) -- vbuz1=_inc_vbuz1 + //SEG36 [16] (byte) main::x#1 ← ++ (byte) main::x#7 [ main::x#1 ] ( main:2 [ main::x#1 ] ) -- vbuz1=_inc_vbuz1 inc x - //SEG36 [16] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@1 [ main::x#1 ] ( main:2 [ main::x#1 ] ) -- vbuz1_neq_vbuc1_then_la1 + //SEG37 [17] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@1 [ main::x#1 ] ( main:2 [ main::x#1 ] ) -- vbuz1_neq_vbuc1_then_la1 lda x cmp #$65 bne b1_from_b5 jmp breturn - //SEG37 main::@return + //SEG38 main::@return breturn: - //SEG38 [17] return [ ] ( main:2 [ ] ) + //SEG39 [18] return [ ] ( main:2 [ ] ) rts } -//SEG39 print +//SEG40 print print: { .const SCREEN = $400 - //SEG40 [18] *((const byte*) print::SCREEN#0 + (byte) print::idx#0) ← (byte) print::val#0 [ ] ( main:2::print:10 [ main::x#7 main::y#4 main::a#2 ] ) -- pbuc1_derefidx_vbuyy=vbuaa + .label idx = 3 + //SEG41 [19] *((const byte*) print::SCREEN#0 + (byte) print::idx#0) ← (byte) print::val#0 [ ] ( main:2::print:11 [ main::x#7 main::y#4 main::a#2 ] ) -- pbuc1_derefidx_vbuz1=vbuyy + tya + ldy idx sta SCREEN,y jmp breturn - //SEG41 print::@return + //SEG42 print::@return breturn: - //SEG42 [19] return [ ] ( main:2::print:10 [ main::x#7 main::y#4 main::a#2 ] ) + //SEG43 [20] return [ ] ( main:2::print:11 [ main::x#7 main::y#4 main::a#2 ] ) rts } @@ -751,31 +787,33 @@ FINAL SYMBOL TABLE (label) main::@return (byte) main::a (byte) main::a#1 reg byte x 1501.5 -(byte) main::a#2 reg byte x 750.75 +(byte) main::a#2 reg byte x 600.5999999999999 +(byte) main::val1 !reg byte a +(byte) main::val1#0 !reg byte a reg byte y 1001.0 (byte) main::x (byte) main::x#1 x zp ZP_BYTE:2 16.5 -(byte) main::x#7 x zp ZP_BYTE:2 102.29999999999998 +(byte) main::x#7 x zp ZP_BYTE:2 93.0 (byte) main::y -(byte) main::y#1 reg byte y 151.5 -(byte) main::y#4 reg byte y 171.85714285714283 +(byte) main::y#1 y zp ZP_BYTE:3 151.5 +(byte) main::y#4 y zp ZP_BYTE:3 150.375 (void()) print((byte) print::idx , (byte) print::val) (label) print::@return (byte*) print::SCREEN (const byte*) print::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) 1024 (byte) print::idx -(byte) print::idx#0 reg byte y 1003.0 +(byte) print::idx#0 idx zp ZP_BYTE:3 501.5 (byte) print::val -(byte) print::val#0 reg byte a 501.5 +(byte) print::val#0 reg byte y 1003.0 zp ZP_BYTE:2 [ main::x#7 main::x#1 ] -reg byte y [ main::y#4 main::y#1 ] +zp ZP_BYTE:3 [ main::y#4 main::y#1 print::idx#0 ] reg byte x [ main::a#2 main::a#1 ] -reg byte a [ print::val#0 ] -reg byte y [ print::idx#0 ] +reg byte y [ main::val1#0 ] +reg byte y [ print::val#0 ] FINAL ASSEMBLER -Score: 22548 +Score: 25453 //SEG0 Basic Upstart .pc = $801 "Basic" @@ -792,6 +830,7 @@ Score: 22548 //SEG8 @end //SEG9 main main: { + .label y = 3 .label x = 2 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] //SEG11 [5] phi (byte) main::x#7 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 @@ -802,8 +841,9 @@ main: { //SEG14 main::@1 b1: //SEG15 [6] phi from main::@1 to main::@2 [phi:main::@1->main::@2] - //SEG16 [6] phi (byte) main::y#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::@1->main::@2#0] -- vbuyy=vbuc1 - ldy #0 + //SEG16 [6] phi (byte) main::y#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::@1->main::@2#0] -- vbuz1=vbuc1 + lda #0 + sta y //SEG17 [6] phi from main::@4 to main::@2 [phi:main::@4->main::@2] //SEG18 [6] phi (byte) main::y#4 = (byte) main::y#1 [phi:main::@4->main::@2#0] -- register_copy //SEG19 main::@2 @@ -815,44 +855,51 @@ main: { //SEG23 [7] phi (byte) main::a#2 = (byte) main::a#1 [phi:main::@7->main::@3#0] -- register_copy //SEG24 main::@3 b3: - //SEG25 [8] (byte) print::val#0 ← (byte) main::a#2 + (byte) main::x#7 [ main::x#7 main::y#4 main::a#2 print::val#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 print::val#0 ] ) -- vbuaa=vbuxx_plus_vbuz1 + //SEG25 [8] (byte) main::val1#0 ← (byte) main::a#2 + (byte) main::x#7 [ main::x#7 main::y#4 main::a#2 main::val1#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 main::val1#0 ] ) -- vbuyy=vbuxx_plus_vbuz1 txa clc adc x - //SEG26 [9] (byte) print::idx#0 ← (byte) main::y#4 [ main::x#7 main::y#4 main::a#2 print::val#0 print::idx#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 print::val#0 print::idx#0 ] ) - // (byte) print::idx#0 = (byte) main::y#4 // register copy reg byte y - //SEG27 [10] call print param-assignment [ main::x#7 main::y#4 main::a#2 ] ( main:2 [ main::x#7 main::y#4 main::a#2 ] ) + tay + //SEG26 [9] (byte) print::idx#0 ← (byte) main::y#4 [ main::x#7 main::y#4 main::a#2 main::val1#0 print::idx#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 main::val1#0 print::idx#0 ] ) + // (byte) print::idx#0 = (byte) main::y#4 // register copy zp ZP_BYTE:3 + //SEG27 [10] (byte) print::val#0 ← (byte) main::val1#0 [ main::x#7 main::y#4 main::a#2 print::idx#0 print::val#0 ] ( main:2 [ main::x#7 main::y#4 main::a#2 print::idx#0 print::val#0 ] ) + // (byte) print::val#0 = (byte) main::val1#0 // register copy reg byte y + //SEG28 [11] call print param-assignment [ main::x#7 main::y#4 main::a#2 ] ( main:2 [ main::x#7 main::y#4 main::a#2 ] ) jsr print - //SEG28 main::@7 - //SEG29 [11] (byte) main::a#1 ← ++ (byte) main::a#2 [ main::x#7 main::y#4 main::a#1 ] ( main:2 [ main::x#7 main::y#4 main::a#1 ] ) -- vbuxx=_inc_vbuxx + //SEG29 main::@7 + //SEG30 [12] (byte) main::a#1 ← ++ (byte) main::a#2 [ main::x#7 main::y#4 main::a#1 ] ( main:2 [ main::x#7 main::y#4 main::a#1 ] ) -- vbuxx=_inc_vbuxx inx - //SEG30 [12] if((byte) main::a#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@3 [ main::x#7 main::y#4 main::a#1 ] ( main:2 [ main::x#7 main::y#4 main::a#1 ] ) -- vbuxx_neq_vbuc1_then_la1 + //SEG31 [13] if((byte) main::a#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@3 [ main::x#7 main::y#4 main::a#1 ] ( main:2 [ main::x#7 main::y#4 main::a#1 ] ) -- vbuxx_neq_vbuc1_then_la1 cpx #$65 bne b3 - //SEG31 main::@4 - //SEG32 [13] (byte) main::y#1 ← ++ (byte) main::y#4 [ main::x#7 main::y#1 ] ( main:2 [ main::x#7 main::y#1 ] ) -- vbuyy=_inc_vbuyy - iny - //SEG33 [14] if((byte) main::y#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@2 [ main::x#7 main::y#1 ] ( main:2 [ main::x#7 main::y#1 ] ) -- vbuyy_neq_vbuc1_then_la1 - cpy #$65 + //SEG32 main::@4 + //SEG33 [14] (byte) main::y#1 ← ++ (byte) main::y#4 [ main::x#7 main::y#1 ] ( main:2 [ main::x#7 main::y#1 ] ) -- vbuz1=_inc_vbuz1 + inc y + //SEG34 [15] if((byte) main::y#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@2 [ main::x#7 main::y#1 ] ( main:2 [ main::x#7 main::y#1 ] ) -- vbuz1_neq_vbuc1_then_la1 + lda y + cmp #$65 bne b2 - //SEG34 main::@5 - //SEG35 [15] (byte) main::x#1 ← ++ (byte) main::x#7 [ main::x#1 ] ( main:2 [ main::x#1 ] ) -- vbuz1=_inc_vbuz1 + //SEG35 main::@5 + //SEG36 [16] (byte) main::x#1 ← ++ (byte) main::x#7 [ main::x#1 ] ( main:2 [ main::x#1 ] ) -- vbuz1=_inc_vbuz1 inc x - //SEG36 [16] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@1 [ main::x#1 ] ( main:2 [ main::x#1 ] ) -- vbuz1_neq_vbuc1_then_la1 + //SEG37 [17] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 101) goto main::@1 [ main::x#1 ] ( main:2 [ main::x#1 ] ) -- vbuz1_neq_vbuc1_then_la1 lda x cmp #$65 bne b1 - //SEG37 main::@return - //SEG38 [17] return [ ] ( main:2 [ ] ) + //SEG38 main::@return + //SEG39 [18] return [ ] ( main:2 [ ] ) rts } -//SEG39 print +//SEG40 print print: { .const SCREEN = $400 - //SEG40 [18] *((const byte*) print::SCREEN#0 + (byte) print::idx#0) ← (byte) print::val#0 [ ] ( main:2::print:10 [ main::x#7 main::y#4 main::a#2 ] ) -- pbuc1_derefidx_vbuyy=vbuaa + .label idx = 3 + //SEG41 [19] *((const byte*) print::SCREEN#0 + (byte) print::idx#0) ← (byte) print::val#0 [ ] ( main:2::print:11 [ main::x#7 main::y#4 main::a#2 ] ) -- pbuc1_derefidx_vbuz1=vbuyy + tya + ldy idx sta SCREEN,y - //SEG41 print::@return - //SEG42 [19] return [ ] ( main:2::print:10 [ main::x#7 main::y#4 main::a#2 ] ) + //SEG42 print::@return + //SEG43 [20] return [ ] ( main:2::print:11 [ main::x#7 main::y#4 main::a#2 ] ) rts } diff --git a/src/test/java/dk/camelot64/kickc/test/ref/var-register.sym b/src/test/java/dk/camelot64/kickc/test/ref/var-register.sym index 5bb8a91b0..f1f9dae84 100644 --- a/src/test/java/dk/camelot64/kickc/test/ref/var-register.sym +++ b/src/test/java/dk/camelot64/kickc/test/ref/var-register.sym @@ -11,24 +11,26 @@ (label) main::@return (byte) main::a (byte) main::a#1 reg byte x 1501.5 -(byte) main::a#2 reg byte x 750.75 +(byte) main::a#2 reg byte x 600.5999999999999 +(byte) main::val1 !reg byte a +(byte) main::val1#0 !reg byte a reg byte y 1001.0 (byte) main::x (byte) main::x#1 x zp ZP_BYTE:2 16.5 -(byte) main::x#7 x zp ZP_BYTE:2 102.29999999999998 +(byte) main::x#7 x zp ZP_BYTE:2 93.0 (byte) main::y -(byte) main::y#1 reg byte y 151.5 -(byte) main::y#4 reg byte y 171.85714285714283 +(byte) main::y#1 y zp ZP_BYTE:3 151.5 +(byte) main::y#4 y zp ZP_BYTE:3 150.375 (void()) print((byte) print::idx , (byte) print::val) (label) print::@return (byte*) print::SCREEN (const byte*) print::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) 1024 (byte) print::idx -(byte) print::idx#0 reg byte y 1003.0 +(byte) print::idx#0 idx zp ZP_BYTE:3 501.5 (byte) print::val -(byte) print::val#0 reg byte a 501.5 +(byte) print::val#0 reg byte y 1003.0 zp ZP_BYTE:2 [ main::x#7 main::x#1 ] -reg byte y [ main::y#4 main::y#1 ] +zp ZP_BYTE:3 [ main::y#4 main::y#1 print::idx#0 ] reg byte x [ main::a#2 main::a#1 ] -reg byte a [ print::val#0 ] -reg byte y [ print::idx#0 ] +reg byte y [ main::val1#0 ] +reg byte y [ print::val#0 ]