diff --git a/src/main/java/dk/camelot64/kickc/asm/AsmFormat.java b/src/main/java/dk/camelot64/kickc/asm/AsmFormat.java index a44d2c77d..2162270c8 100644 --- a/src/main/java/dk/camelot64/kickc/asm/AsmFormat.java +++ b/src/main/java/dk/camelot64/kickc/asm/AsmFormat.java @@ -3,10 +3,7 @@ package dk.camelot64.kickc.asm; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.operators.*; -import dk.camelot64.kickc.model.symbols.ConstantVar; -import dk.camelot64.kickc.model.symbols.Procedure; -import dk.camelot64.kickc.model.symbols.Symbol; -import dk.camelot64.kickc.model.symbols.Variable; +import dk.camelot64.kickc.model.symbols.*; import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolTypeInference; import dk.camelot64.kickc.model.types.SymbolTypePointer; @@ -311,19 +308,7 @@ public class AsmFormat { * @param boundVar The variable * @return The ASM parameter to use in the ASM code */ - public static String getAsmParamName(Variable boundVar, ScopeRef codeScopeRef) { - ScopeRef varScopeRef = boundVar.getScope().getRef(); - String asmName = boundVar.getAsmName() == null ? boundVar.getLocalName() : boundVar.getAsmName(); - return getAsmParamName(varScopeRef, asmName, codeScopeRef); - } - - /** - * Get the ASM parameter for a specific bound constant - * - * @param boundVar The constant - * @return The ASM parameter to use in the ASM code - */ - public static String getAsmParamName(ConstantVar boundVar, ScopeRef codeScopeRef) { + public static String getAsmParamName(SymbolVariable boundVar, ScopeRef codeScopeRef) { ScopeRef varScopeRef = boundVar.getScope().getRef(); String asmName = boundVar.getAsmName() == null ? boundVar.getLocalName() : boundVar.getAsmName(); return getAsmParamName(varScopeRef, asmName, codeScopeRef); diff --git a/src/main/java/dk/camelot64/kickc/model/symbols/ConstantVar.java b/src/main/java/dk/camelot64/kickc/model/symbols/ConstantVar.java index 2dafafb21..182ee700e 100644 --- a/src/main/java/dk/camelot64/kickc/model/symbols/ConstantVar.java +++ b/src/main/java/dk/camelot64/kickc/model/symbols/ConstantVar.java @@ -1,6 +1,5 @@ package dk.camelot64.kickc.model.symbols; -import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.values.ConstantRef; import dk.camelot64.kickc.model.values.ConstantValue; @@ -18,20 +17,4 @@ public class ConstantVar extends SymbolVariable { return new ConstantRef(this); } - @Override - public String toString(Program program) { - String s = new StringBuilder() - .append("(") - .append("const" + " ") - .append(getType().getTypeName()) - .append(") ") - .append(getFullName()).toString(); - return s; - } - - @Override - public String toString() { - return toString(null); - } - } diff --git a/src/main/java/dk/camelot64/kickc/model/symbols/SymbolVariable.java b/src/main/java/dk/camelot64/kickc/model/symbols/SymbolVariable.java index a52deca8b..42740c24c 100644 --- a/src/main/java/dk/camelot64/kickc/model/symbols/SymbolVariable.java +++ b/src/main/java/dk/camelot64/kickc/model/symbols/SymbolVariable.java @@ -1,6 +1,7 @@ package dk.camelot64.kickc.model.symbols; import dk.camelot64.kickc.model.Comment; +import dk.camelot64.kickc.model.InternalError; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.Registers; import dk.camelot64.kickc.model.types.SymbolType; @@ -21,7 +22,7 @@ public abstract class SymbolVariable implements Symbol { /** The type of the variable. VAR means tha type is unknown, and has not been inferred yet. */ private SymbolType type; - /** true if the symbol type is infered (not declared) */ + /** true if the symbol type is inferred (not declared) */ private boolean inferredType; /** A short name used for the variable in ASM code. If possible variable names of variables are shortened in ASM code. This is possible, when several versions of the var use the same register. */ @@ -56,7 +57,8 @@ public abstract class SymbolVariable implements Symbol { /** Specifies that the variable must live in memory. */ private boolean declaredAsNotRegister; - /** Strategy being used for storing and accessing the variable. The value depends on the directives memory/register/volatile/const - and on the compilers optimization decisions. + /** + * Strategy being used for storing and accessing the variable. The value depends on the directives memory/register/volatile/const - and on the compilers optimization decisions. * **/ - public enum StorageStrategy { PHI_MASTER, PHI_VERSION, INTERMEDIATE, LOAD_STORE, CONSTANT } + public enum StorageStrategy { + PHI_MASTER, PHI_VERSION, INTERMEDIATE, LOAD_STORE, CONSTANT + } /** The storage strategy for the variable. */ private StorageStrategy storageStrategy; /** Memory area used for storing the variable (if is is stored in memory). */ - public enum MemoryArea { ZEROPAGE_MEMORY, MAIN_MEMORY } + public enum MemoryArea { + ZEROPAGE_MEMORY, MAIN_MEMORY + } /** The memory area where the variable lives (if stored in memory). */ private MemoryArea memoryArea; @@ -87,6 +93,12 @@ public abstract class SymbolVariable implements Symbol { /** The constant value if the variable is a constant. Null otherwise. */ private ConstantValue constantValue; + /** The number of the next version (only used for PHI masters) */ + private Integer nextPhiVersionNumber; + + /** If the variable is assigned to a specific "register", this contains the register. If null the variable has no allocation (yet). Constants are never assigned to registers. */ + private Registers.Register allocation; + public SymbolVariable(String name, Scope scope, SymbolType type, StorageStrategy storageStrategy, MemoryArea memoryArea, String dataSegment) { this.name = name; this.scope = scope; @@ -98,6 +110,9 @@ public abstract class SymbolVariable implements Symbol { this.memoryArea = memoryArea; this.constantDeclaration = ConstantDeclaration.MAYBE_CONST; setFullName(); + if(isStoragePhiMaster()) + this.nextPhiVersionNumber = 0; + } private void setFullName() { @@ -105,6 +120,41 @@ public abstract class SymbolVariable implements Symbol { fullName = (scopeName.length() > 0) ? scopeName + "::" + name : name; } + /** + * Creates a new PHI-version from a PHI-master + * + * @return The new version of the PHI master + */ + public Variable createVersion() { + if(!isStoragePhiMaster()) + throw new InternalError("Cannot version non-PHI variable " + this.toString()); + Variable version = new Variable(this, nextPhiVersionNumber++); + getScope().add(version); + return version; + } + + /** + * If the variable is a version of a variable returns the original variable. + * + * @return The original variable. Null if this is not a version. + */ + public Variable getVersionOf() { + if(!isStoragePhiVersion()) + throw new InternalError("Cannot get master for non-PHI version variable " + this.toString()); + String name = getName(); + String versionOfName = name.substring(0, name.indexOf("#")); + return getScope().getVariable(versionOfName); + } + + + public Registers.Register getAllocation() { + return allocation; + } + + public void setAllocation(Registers.Register allocation) { + this.allocation = allocation; + } + public ConstantValue getConstantValue() { return constantValue; } @@ -318,13 +368,13 @@ public abstract class SymbolVariable implements Symbol { @Override public String toString(Program program) { - String s = new StringBuilder() + return new StringBuilder() .append("(") - .append(type.getTypeName()) - .append(inferredType ? "~" : "") + .append((constantValue != null) ? "const " : "") + .append(getType().getTypeName()) + .append((constantValue==null&&inferredType) ? "~" : "") .append(") ") .append(getFullName()).toString(); - return s; } @Override diff --git a/src/main/java/dk/camelot64/kickc/model/symbols/Variable.java b/src/main/java/dk/camelot64/kickc/model/symbols/Variable.java index c0b1343b2..ba3a9f156 100644 --- a/src/main/java/dk/camelot64/kickc/model/symbols/Variable.java +++ b/src/main/java/dk/camelot64/kickc/model/symbols/Variable.java @@ -1,34 +1,15 @@ package dk.camelot64.kickc.model.symbols; -import dk.camelot64.kickc.model.InternalError; -import dk.camelot64.kickc.model.Registers; import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.values.VariableRef; -import java.util.Objects; - /** * A Variable in the program. - *

- * There are several types of variables - *

- * - Intermediate: A variable added by the compiler to hold some intermediate value. Intermediate variables are names $1, $2, ... - * - PHI-variable: A variable with storage strategy PHI is turned into versions. The variable itself is never used directly in the program. - * - PHI-versions: A variable with storage strategy PHI is turned into versions. Versions of the PHI-variable name are named name#1, name#2, name#3 - * - Memory: A variable with storage strategy memory is used directly in the program. */ public class Variable extends SymbolVariable { - /** The number of the next version (only used for PHI masters) */ - private Integer nextPhiVersionNumber; - - /** If the variable is assigned to a specific "register", this contains the register. If null the variable has no allocation (yet). Constants are never assigned to registers. */ - private Registers.Register allocation; - public Variable(String name, Scope scope, SymbolType type, String dataSegment, StorageStrategy storageStrategy, MemoryArea memoryArea) { super(name, scope, type, storageStrategy, memoryArea, dataSegment); - if(isStoragePhiMaster()) - this.nextPhiVersionNumber = 0; } /** @@ -37,7 +18,7 @@ public class Variable extends SymbolVariable { * @param phiMaster The PHI master variable. * @param version The version number */ - public Variable(Variable phiMaster, int version) { + public Variable(SymbolVariable phiMaster, int version) { super(phiMaster.getName() + "#" + version, phiMaster.getScope(), phiMaster.getType(), StorageStrategy.PHI_VERSION, phiMaster.getMemoryArea(), phiMaster.getDataSegment()); this.setDeclaredAlignment(phiMaster.getDeclaredAlignment()); this.setDeclaredAsRegister(phiMaster.isDeclaredAsRegister()); @@ -55,53 +36,4 @@ public class Variable extends SymbolVariable { return new VariableRef(this); } - public Registers.Register getAllocation() { - return allocation; - } - - public void setAllocation(Registers.Register allocation) { - this.allocation = allocation; - } - - - /** - * Creates a new PHI-version from a PHI-master - * - * @return The new version of the PHI master - */ - public Variable createVersion() { - if(!isStoragePhiMaster()) - throw new InternalError("Cannot version non-PHI variable " + this.toString()); - Variable version = new Variable(this, nextPhiVersionNumber++); - getScope().add(version); - return version; - } - - /** - * If the variable is a version of a variable returns the original variable. - * - * @return The original variable. Null if this is not a version. - */ - public Variable getVersionOf() { - if(!isStoragePhiVersion()) - throw new InternalError("Cannot get master for non-PHI version variable " + this.toString()); - String name = getName(); - String versionOfName = name.substring(0, name.indexOf("#")); - return getScope().getVariable(versionOfName); - } - - - @Override - public boolean equals(Object o) { - if(this == o) return true; - if(o == null || getClass() != o.getClass()) return false; - if(!super.equals(o)) return false; - Variable variable = (Variable) o; - return Objects.equals(allocation, variable.allocation); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), allocation); - } } diff --git a/src/test/ref/bitmap-line-anim-2.asm b/src/test/ref/bitmap-line-anim-2.asm index e4d053431..0853a2c7d 100644 --- a/src/test/ref/bitmap-line-anim-2.asm +++ b/src/test/ref/bitmap-line-anim-2.asm @@ -293,7 +293,6 @@ sgn_u16: { __b1: lda #<-1 sta.z return - lda #>-1 sta.z return+1 rts } diff --git a/src/test/ref/bitmap-line-anim-2.log b/src/test/ref/bitmap-line-anim-2.log index 84fe9c546..4ef5114ed 100644 --- a/src/test/ref/bitmap-line-anim-2.log +++ b/src/test/ref/bitmap-line-anim-2.log @@ -4279,6 +4279,7 @@ Removing instruction lda #>0 Removing instruction lda.z e+1 Removing instruction lda.z e1+1 Removing instruction ldy #0 +Removing instruction lda #>-1 Succesful ASM optimization Pass5UnnecesaryLoadElimination Replacing label __bbegin with __b1 Replacing label __b5_from___b4 with __b2 @@ -4617,7 +4618,7 @@ reg byte a [ bitmap_init::$6 ] FINAL ASSEMBLER -Score: 30190 +Score: 30188 // File Comments // Shows that bitmap2.kc line() does not have the same problem as bitmap-draw.kc @@ -5128,7 +5129,6 @@ sgn_u16: { // [78] phi (word) sgn_u16::return#4 = (byte) -1 [phi:sgn_u16::@1->sgn_u16::@return#0] -- vwuz1=vbuc1 lda #<-1 sta.z return - lda #>-1 sta.z return+1 // sgn_u16::@return // } diff --git a/src/test/ref/bitmap-plot-3.asm b/src/test/ref/bitmap-plot-3.asm index f1a022f6d..f45fd11cc 100644 --- a/src/test/ref/bitmap-plot-3.asm +++ b/src/test/ref/bitmap-plot-3.asm @@ -316,7 +316,6 @@ sgn_u16: { __b1: lda #<-1 sta.z return - lda #>-1 sta.z return+1 rts } diff --git a/src/test/ref/bitmap-plot-3.log b/src/test/ref/bitmap-plot-3.log index f12e8f50d..8f2da4fd6 100644 --- a/src/test/ref/bitmap-plot-3.log +++ b/src/test/ref/bitmap-plot-3.log @@ -4626,6 +4626,7 @@ Removing instruction ldy.z a Removing instruction lda.z e+1 Removing instruction lda.z e1+1 Removing instruction ldy #0 +Removing instruction lda #>-1 Succesful ASM optimization Pass5UnnecesaryLoadElimination Replacing label __bbegin with __b1 Replacing label __b7_from___b16 with __b7 @@ -4974,7 +4975,7 @@ reg byte a [ bitmap_init::$6 ] FINAL ASSEMBLER -Score: 27289 +Score: 27287 // File Comments // Tests the simple bitmap plotter @@ -5513,7 +5514,6 @@ sgn_u16: { // [86] phi (word) sgn_u16::return#4 = (byte) -1 [phi:sgn_u16::@1->sgn_u16::@return#0] -- vwuz1=vbuc1 lda #<-1 sta.z return - lda #>-1 sta.z return+1 // sgn_u16::@return // } diff --git a/src/test/ref/complex/splines/truetype-splines.asm b/src/test/ref/complex/splines/truetype-splines.asm index f92515aa5..a2008d465 100644 --- a/src/test/ref/complex/splines/truetype-splines.asm +++ b/src/test/ref/complex/splines/truetype-splines.asm @@ -505,7 +505,6 @@ sgn_u16: { __b1: lda #<-1 sta.z return - lda #>-1 sta.z return+1 rts } diff --git a/src/test/ref/complex/splines/truetype-splines.log b/src/test/ref/complex/splines/truetype-splines.log index 1b68221ba..136282417 100644 --- a/src/test/ref/complex/splines/truetype-splines.log +++ b/src/test/ref/complex/splines/truetype-splines.log @@ -12004,6 +12004,7 @@ Removing instruction lda #0 Removing instruction lda.z e+1 Removing instruction lda.z e1+1 Removing instruction ldy #0 +Removing instruction lda #>-1 Replacing instruction lda #<0 with TXA Removing instruction lda #>0 Removing instruction lda #0 @@ -12199,7 +12200,7 @@ Removing instruction __breturn: Removing instruction b1: Removing instruction __breturn: Succesful ASM optimization Pass5UnusedLabelElimination -Fixing long branch [770] bne __b1 to beq +Fixing long branch [769] bne __b1 to beq Fixing long branch [308] beq __b4 to bne FINAL SYMBOL TABLE @@ -12790,7 +12791,7 @@ reg byte a [ mulf_init::$13 ] FINAL ASSEMBLER -Score: 678158 +Score: 678156 // File Comments // Show a few simple splines using the splines library @@ -13681,7 +13682,6 @@ sgn_u16: { // [164] phi (word) sgn_u16::return#4 = (byte) -1 [phi:sgn_u16::@1->sgn_u16::@return#0] -- vwuz1=vbuc1 lda #<-1 sta.z return - lda #>-1 sta.z return+1 // sgn_u16::@return // } diff --git a/src/test/ref/problem-negative-word-const.asm b/src/test/ref/problem-negative-word-const.asm index 6e8c39c29..768dc07e5 100644 --- a/src/test/ref/problem-negative-word-const.asm +++ b/src/test/ref/problem-negative-word-const.asm @@ -13,7 +13,6 @@ main: { beq __b3 lda #<-1 sta.z w - lda #>-1 sta.z w+1 jmp __b2 __b3: diff --git a/src/test/ref/problem-negative-word-const.log b/src/test/ref/problem-negative-word-const.log index 54acf692a..b36370de0 100644 --- a/src/test/ref/problem-negative-word-const.log +++ b/src/test/ref/problem-negative-word-const.log @@ -419,6 +419,8 @@ Removing instruction jmp __b1 Removing instruction jmp __b2 Removing instruction jmp __breturn Succesful ASM optimization Pass5NextJumpElimination +Removing instruction lda #>-1 +Succesful ASM optimization Pass5UnnecesaryLoadElimination Replacing label __bbegin with __b1 Replacing label __b1_from___b2 with __b1 Removing instruction __bbegin: @@ -467,7 +469,7 @@ reg byte a [ main::$3 ] FINAL ASSEMBLER -Score: 626 +Score: 606 // File Comments // Problem with assigning negative word constant (vwuz1=vbuc1) @@ -506,7 +508,6 @@ main: { // [9] phi (word) main::w#2 = (byte) -1 [phi:main::@1->main::@2#0] -- vwuz1=vbuc1 lda #<-1 sta.z w - lda #>-1 sta.z w+1 jmp __b2 // main::@3