diff --git a/src/main/fragment/pbuz1=_deref_pptc1.asm b/src/main/fragment/pbuz1=_deref_pptc1.asm new file mode 100644 index 000000000..1f588b460 --- /dev/null +++ b/src/main/fragment/pbuz1=_deref_pptc1.asm @@ -0,0 +1,4 @@ +lda {c1} +sta {z1} +lda {c1}+1 +sta {z1}+1 \ No newline at end of file diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index 254a5ea4b..1ad60d1f4 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -247,6 +247,7 @@ public class Compiler { optimizations.add(new Pass2FixInlineConstructors(program)); optimizations.add(new Pass2TypeInference(program)); optimizations.add(new PassNEliminateUnusedVars(program)); + optimizations.add(new Pass2EliminateRedundantCasts(program)); optimizations.add(new Pass2NopCastElimination(program)); optimizations.add(new Pass2EliminateUnusedBlocks(program)); optimizations.add(new Pass2RangeResolving(program)); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2EliminateRedundantCasts.java b/src/main/java/dk/camelot64/kickc/passes/Pass2EliminateRedundantCasts.java new file mode 100644 index 000000000..40731c99a --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2EliminateRedundantCasts.java @@ -0,0 +1,75 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.ControlFlowBlock; +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.operators.OperatorCastPtr; +import dk.camelot64.kickc.model.operators.Operators; +import dk.camelot64.kickc.model.statements.Statement; +import dk.camelot64.kickc.model.statements.StatementAssignment; +import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.types.SymbolTypeInference; +import dk.camelot64.kickc.model.types.SymbolTypePointer; +import dk.camelot64.kickc.model.values.RValue; + +/** + * Eliminate casts that are not necessary + */ +public class Pass2EliminateRedundantCasts extends Pass2SsaOptimization { + + public Pass2EliminateRedundantCasts(Program program) { + super(program); + } + + @Override + public boolean step() { + boolean modified = false; + for(ControlFlowBlock block : getGraph().getAllBlocks()) { + for(Statement statement : block.getStatements()) { + if(statement instanceof StatementAssignment) { + StatementAssignment assignment = (StatementAssignment) statement; + if(isRedundantCast(assignment)) { + // Redundant cast + getLog().append("Removing redundant cast " + statement.toString(getProgram(), false)); + assignment.setOperator(null); + modified = true; + } + } + } + } + return modified; + } + + /** + * Determines if the assignment is a redundant cast + * + * @param assignment The assignment to examine + * @return true if is is a redundant cast + */ + private boolean isRedundantCast(StatementAssignment assignment) { + RValue rValue2 = assignment.getrValue2(); + SymbolType rValue2Type = SymbolTypeInference.inferType(getScope(), rValue2); + if(Operators.CAST_BYTE.equals(assignment.getOperator()) && SymbolType.BYTE.equals(rValue2Type)) { + return true; + } else if(Operators.CAST_SBYTE.equals(assignment.getOperator()) && SymbolType.SBYTE.equals(rValue2Type)) { + return true; + } else if(Operators.CAST_WORD.equals(assignment.getOperator()) && SymbolType.WORD.equals(rValue2Type)) { + return true; + } else if(Operators.CAST_SWORD.equals(assignment.getOperator()) && SymbolType.SWORD.equals(rValue2Type)) { + return true; + } else if(Operators.CAST_DWORD.equals(assignment.getOperator()) && SymbolType.DWORD.equals(rValue2Type)) { + return true; + } else if(Operators.CAST_SDWORD.equals(assignment.getOperator()) && SymbolType.SDWORD.equals(rValue2Type)) { + return true; + } else if(Operators.CAST_BOOL.equals(assignment.getOperator()) && SymbolType.BOOLEAN.equals(rValue2Type)) { + return true; + } else if(assignment.getOperator() instanceof OperatorCastPtr) { + // Casting to a pointer + OperatorCastPtr operatorCastPtr = (OperatorCastPtr) assignment.getOperator(); + if(rValue2Type.equals(new SymbolTypePointer(operatorCastPtr.getElementType()))) { + return true; + } + } + return false; + } + +} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java index 6c41d76ba..630581697 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java @@ -149,6 +149,7 @@ public class Pass4CodeGeneration { /** * Generate the end of a scope + * * @param asm The assembler program being generated * @param currentScope The current scope, which is ending here */ @@ -156,7 +157,7 @@ public class Pass4CodeGeneration { if(!ScopeRef.ROOT.equals(currentScope)) { // Generate any indirect calls pending for(String indirectCallAsmName : indirectCallAsmNames) { - asm.addLabel("bi_"+indirectCallAsmName); + asm.addLabel("bi_" + indirectCallAsmName); asm.addInstruction("jmp", AsmAddressingMode.IND, indirectCallAsmName, false); } indirectCallAsmNames = new ArrayList<>(); @@ -167,6 +168,7 @@ public class Pass4CodeGeneration { /** * Add an indirect call to the assembler program. Also queues ASM for the indirect jump to be added at the end of the block. + * * @param asm The ASM program being built * @param procedureVariable The variable containing the function pointer * @param codeScopeRef The scope containing the code being generated. Used for adding scope to the name when needed (eg. line.x1 when referencing x1 variable inside line scope from outside line scope). @@ -178,9 +180,9 @@ public class Pass4CodeGeneration { } - /** * Generate a comment that describes the procedure signature and parameter transfer + * * @param asm The assembler program being generated * @param procedure The procedure */ @@ -210,7 +212,7 @@ public class Pass4CodeGeneration { } } signature.append(")"); - if(i>0) { + if(i > 0) { asm.addComment(signature.toString(), false); } } @@ -395,12 +397,8 @@ public class Pass4CodeGeneration { asm.addDataNumeric(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.DWORD, asmElements); added.add(asmName); } else if(elementType instanceof SymbolTypePointer) { - if(((SymbolTypePointer) elementType).getElementType() instanceof SymbolTypeProcedure) { - asm.addDataNumeric(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.WORD, asmElements); - added.add(asmName); - } else { - throw new RuntimeException("Unhandled constant array element type " + constantArrayList.toString(program)); - } + asm.addDataNumeric(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.WORD, asmElements); + added.add(asmName); } else { throw new RuntimeException("Unhandled constant array element type " + constantArrayList.toString(program)); } @@ -493,7 +491,7 @@ public class Pass4CodeGeneration { try { generateStatementAsm(asm, block, statement, aluState, true); } catch(AsmFragmentTemplateSynthesizer.UnknownFragmentException e) { - throw new CompileError("Unknown fragment for statement " + statement.toString(program, false)+"\nMissing ASM fragment "+e.getFragmentSignature(), e); + throw new CompileError("Unknown fragment for statement " + statement.toString(program, false) + "\nMissing ASM fragment " + e.getFragmentSignature(), statement.getSource()); } } } @@ -585,7 +583,7 @@ public class Pass4CodeGeneration { asmFragmentInstance.generate(asm); AsmSegment currentSegment = asm.getCurrentSegment(); - if(statementAsm.getDeclaredClobber()!=null) { + if(statementAsm.getDeclaredClobber() != null) { currentSegment.setClobberOverwrite(statementAsm.getDeclaredClobber()); } else { for(AsmLine asmLine : currentSegment.getLines()) { @@ -634,7 +632,7 @@ public class Pass4CodeGeneration { if(procedureVariableType instanceof SymbolTypePointer) { if(((SymbolTypePointer) procedureVariableType).getElementType() instanceof SymbolTypeProcedure) { String varAsmName = AsmFormat.getAsmParamName(procedureVariable, block.getScope()); - asm.addInstruction("jsr", AsmAddressingMode.ABS, varAsmName,false); + asm.addInstruction("jsr", AsmAddressingMode.ABS, varAsmName, false); supported = true; } } @@ -653,6 +651,7 @@ public class Pass4CodeGeneration { /** * Generate ASM code for an ASM fragment instance + * * @param asm The ASM program to generate into * @param asmFragmentInstanceSpecFactory The ASM fragment instance specification factory */ @@ -661,7 +660,7 @@ public class Pass4CodeGeneration { AsmFragmentInstanceSpec asmFragmentInstanceSpec = asmFragmentInstanceSpecFactory.getAsmFragmentInstanceSpec(); AsmFragmentInstance asmFragmentInstance = null; StringBuffer fragmentVariationsTried = new StringBuffer(); - while(asmFragmentInstance==null) { + while(asmFragmentInstance == null) { try { asmFragmentInstance = AsmFragmentTemplateSynthesizer.getFragmentInstance(asmFragmentInstanceSpec, program.getLog()); } catch(AsmFragmentTemplateSynthesizer.UnknownFragmentException e) { @@ -671,11 +670,11 @@ public class Pass4CodeGeneration { if(asmFragmentInstanceSpec.hasNextVariation()) { asmFragmentInstanceSpec.nextVariation(); if(program.getLog().isVerboseFragmentLog()) { - program.getLog().append("Fragment not found "+signature+". Attempting another variation "+asmFragmentInstanceSpec.getSignature()); + program.getLog().append("Fragment not found " + signature + ". Attempting another variation " + asmFragmentInstanceSpec.getSignature()); } } else { // No more variations available - fail with an error - throw new AsmFragmentTemplateSynthesizer.UnknownFragmentException("Fragment not found "+initialSignature+". Attempted variations "+fragmentVariationsTried); + throw new AsmFragmentTemplateSynthesizer.UnknownFragmentException("Fragment not found " + initialSignature + ". Attempted variations " + fragmentVariationsTried); } } } diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 3cdcae9e0..727214ced 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -42,6 +42,11 @@ public class TestPrograms { compileAndCompare("semi-struct-2"); } + @Test + public void testSemiStruct1() throws IOException, URISyntaxException { + compileAndCompare("semi-struct-1"); + } + @Test public void testReserveZpGlobal() throws IOException, URISyntaxException { compileAndCompare("reserve-zp-global"); @@ -507,6 +512,16 @@ public class TestPrograms { compileAndCompare("inline-asm-optimized"); } + @Test + public void testCastNotNeeded2() throws IOException, URISyntaxException { + compileAndCompare("cast-not-needed-2"); + } + + @Test + public void testCastNotNeeded3() throws IOException, URISyntaxException { + compileAndCompare("cast-not-needed-3"); + } + @Test public void testCastNotNeeded() throws IOException, URISyntaxException { compileAndCompare("cast-not-needed"); diff --git a/src/test/kc/cast-not-needed-2.kc b/src/test/kc/cast-not-needed-2.kc new file mode 100644 index 000000000..47d42e83d --- /dev/null +++ b/src/test/kc/cast-not-needed-2.kc @@ -0,0 +1,17 @@ +// Tests a cast that is not needed + +byte*[] screens = { (byte*)$0400, (byte*)$1400 }; + +void main() { + byte* screen; + screen = getScreen(0); + *spritePtr(screen) = $22; +} + +inline byte* getScreen(byte id) { + return screens[id]; +} + +inline byte* spritePtr(byte* screen) { + return (byte*)(screen+$378); +} \ No newline at end of file diff --git a/src/test/kc/cast-not-needed-3.kc b/src/test/kc/cast-not-needed-3.kc new file mode 100644 index 000000000..53e3175d4 --- /dev/null +++ b/src/test/kc/cast-not-needed-3.kc @@ -0,0 +1,16 @@ +// Tests a cast that is not needed + +byte*[] screens = { (byte*)$0400, (byte*)$1400 }; + +void main() { + byte* DSP = $400; + DSP[0] = spritePtr(getScreen(0)); +} + +inline byte* getScreen(byte id) { + return screens[id]; +} + +inline byte spritePtr(byte* screen) { + return (byte)*(screen+$378); +} \ No newline at end of file diff --git a/src/test/kc/cast-not-needed.kc b/src/test/kc/cast-not-needed.kc index b3abf2d9d..f47e9af8d 100644 --- a/src/test/kc/cast-not-needed.kc +++ b/src/test/kc/cast-not-needed.kc @@ -1,4 +1,4 @@ -// +// Tests a cast that is not needed byte* sprite = $5000; byte* SCREEN = $4400; diff --git a/src/test/kc/semi-struct-1.kc b/src/test/kc/semi-struct-1.kc new file mode 100644 index 000000000..5f7bf5d85 --- /dev/null +++ b/src/test/kc/semi-struct-1.kc @@ -0,0 +1,64 @@ +// Implementing a semi-struct without the struct keyword by using pointer math and inline functions +// +// struct Point { +// byte xpos; // The x-position +// byte ypos; // The y-position +// }; +// Point[NUM_POINTS] points; + +import "print" + +// The size of a point +const byte SIZEOF_POINT = 2; + +// The number of points +const byte NUM_POINTS = 4; + +// All points +byte[NUM_POINTS*SIZEOF_POINT] points; + +// Get a point by index +inline byte* getPoint(byte idx) { + return points+idx*SIZEOF_POINT; +} + +// Get x-position of the point +inline byte* pointXpos(byte* point) { + return (byte*)(point+0); +} + +// Get y-position of the point +inline byte* pointYpos(byte* point) { + return (byte*)(point+1); +} + +// Initialize some points and print them +void main() { + init_points(); + print_points(); +} + +// Initialize points +void init_points() { + byte pos = 10; + for(byte i: 0..NUM_POINTS-1) { + byte* point = getPoint(i); + *pointXpos(point) = pos; + pos +=10; + *pointYpos(point) = pos; + pos +=10; + } +} + +// Print points +void print_points() { + print_cls(); + for(byte i: 0..NUM_POINTS-1) { + byte* point = getPoint(i); + print_byte(*pointXpos(point)); + print_str(" "); + print_byte(*pointYpos(point)); + print_ln(); + } +} + diff --git a/src/test/kc/semi-struct-2.kc b/src/test/kc/semi-struct-2.kc index 8640b8bad..8ead6dd67 100644 --- a/src/test/kc/semi-struct-2.kc +++ b/src/test/kc/semi-struct-2.kc @@ -23,17 +23,17 @@ import "print" import "keyboard" // The size of a file ENTRY -const byte ENTRY_SIZE = 18; +const byte SIZEOF_ENTRY = 18; // The maximal number of files const byte MAX_FILES = 144; // All files -byte[(word)MAX_FILES*ENTRY_SIZE] files; +byte[(word)MAX_FILES*SIZEOF_ENTRY] files; // Get pointer to a numbered file entry in the files-table inline byte* fileEntry(byte idx) { - return files+mul8u(idx, ENTRY_SIZE); + return files+mul8u(idx, SIZEOF_ENTRY); } // Get file position in disk buffer. diff --git a/src/test/ref/cast-not-needed-2.asm b/src/test/ref/cast-not-needed-2.asm new file mode 100644 index 000000000..c91a7229a --- /dev/null +++ b/src/test/ref/cast-not-needed-2.asm @@ -0,0 +1,26 @@ +// Tests a cast that is not needed +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .const SIZEOF_POINTER = 2 +main: { + .const getScreen1_id = 0 + .label getScreen1_return = 2 + .label spritePtr1_return = 2 + lda screens+getScreen1_id*SIZEOF_POINTER + sta getScreen1_return + lda screens+getScreen1_id*SIZEOF_POINTER+1 + sta getScreen1_return+1 + clc + lda spritePtr1_return + adc #<$378 + sta spritePtr1_return + lda spritePtr1_return+1 + adc #>$378 + sta spritePtr1_return+1 + lda #$22 + ldy #0 + sta (spritePtr1_return),y + rts +} + screens: .word $400, $1400 diff --git a/src/test/ref/cast-not-needed-2.cfg b/src/test/ref/cast-not-needed-2.cfg new file mode 100644 index 000000000..5a214506a --- /dev/null +++ b/src/test/ref/cast-not-needed-2.cfg @@ -0,0 +1,24 @@ +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() +main: scope:[main] from @1 + [4] phi() + to:main::getScreen1 +main::getScreen1: scope:[main] from main + [5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER) + to:main::spritePtr1 +main::spritePtr1: scope:[main] from main::getScreen1 + [6] (byte*) main::spritePtr1_return#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378 + to:main::@1 +main::@1: scope:[main] from main::spritePtr1 + [7] *((byte*) main::spritePtr1_return#0) ← (byte/signed byte/word/signed word/dword/signed dword) $22 + to:main::@return +main::@return: scope:[main] from main::@1 + [8] return + to:@return diff --git a/src/test/ref/cast-not-needed-2.log b/src/test/ref/cast-not-needed-2.log new file mode 100644 index 000000000..4af6fa92b --- /dev/null +++ b/src/test/ref/cast-not-needed-2.log @@ -0,0 +1,439 @@ +Fixing pointer array-indexing *((byte*[]) screens + (byte) getScreen::id) +Inlined call (byte*~) main::$0 ← call getScreen (byte/signed byte/word/signed word/dword/signed dword) 0 +Inlined call (byte*~) main::$1 ← call spritePtr (byte*) main::screen + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + (byte*~) $0 ← ((byte*)) (word/signed word/dword/signed dword) $400 + (byte*~) $1 ← ((byte*)) (word/signed word/dword/signed dword) $1400 + (byte*[]) screens#0 ← { (byte*~) $0, (byte*~) $1 } + to:@3 +main: scope:[main] from @3 + (byte*) main::screen#0 ← (byte*) 0 + (byte) main::getScreen1_id#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 + to:main::getScreen1 +main::getScreen1: scope:[main] from main + (byte) main::getScreen1_id#1 ← phi( main/(byte) main::getScreen1_id#0 ) + (byte) main::getScreen1_$0#0 ← (byte) main::getScreen1_id#1 * (const byte) SIZEOF_POINTER + (byte*) main::getScreen1_return#0 ← *((byte*[]) screens#0 + (byte) main::getScreen1_$0#0) + to:main::getScreen1_@return +main::getScreen1_@return: scope:[main] from main::getScreen1 + (byte*) main::getScreen1_return#2 ← phi( main::getScreen1/(byte*) main::getScreen1_return#0 ) + (byte*) main::getScreen1_return#1 ← (byte*) main::getScreen1_return#2 + to:main::@1 +main::@1: scope:[main] from main::getScreen1_@return + (byte*) main::getScreen1_return#3 ← phi( main::getScreen1_@return/(byte*) main::getScreen1_return#1 ) + (byte*~) main::$0 ← (byte*) main::getScreen1_return#3 + (byte*) main::screen#1 ← (byte*~) main::$0 + (byte*) main::spritePtr1_screen#0 ← (byte*) main::screen#1 + to:main::spritePtr1 +main::spritePtr1: scope:[main] from main::@1 + (byte*) main::spritePtr1_screen#1 ← phi( main::@1/(byte*) main::spritePtr1_screen#0 ) + (byte*) main::spritePtr1_$0#0 ← (byte*) main::spritePtr1_screen#1 + (word/signed word/dword/signed dword) $378 + (byte*) main::spritePtr1_$1#0 ← ((byte*)) (byte*) main::spritePtr1_$0#0 + (byte*) main::spritePtr1_return#0 ← (byte*) main::spritePtr1_$1#0 + to:main::spritePtr1_@return +main::spritePtr1_@return: scope:[main] from main::spritePtr1 + (byte*) main::spritePtr1_return#2 ← phi( main::spritePtr1/(byte*) main::spritePtr1_return#0 ) + (byte*) main::spritePtr1_return#1 ← (byte*) main::spritePtr1_return#2 + to:main::@2 +main::@2: scope:[main] from main::spritePtr1_@return + (byte*) main::spritePtr1_return#3 ← phi( main::spritePtr1_@return/(byte*) main::spritePtr1_return#1 ) + (byte*~) main::$1 ← (byte*) main::spritePtr1_return#3 + *((byte*~) main::$1) ← (byte/signed byte/word/signed word/dword/signed dword) $22 + to:main::@return +main::@return: scope:[main] from main::@2 + return + to:@return +@3: scope:[] from @begin + call main + to:@4 +@4: scope:[] from @3 + to:@end +@end: scope:[] from @4 + +SYMBOL TABLE SSA +(byte*~) $0 +(byte*~) $1 +(label) @3 +(label) @4 +(label) @begin +(label) @end +(const byte) SIZEOF_POINTER = (byte/signed byte/word/signed word/dword/signed dword) 2 +(void()) main() +(byte*~) main::$0 +(byte*~) main::$1 +(label) main::@1 +(label) main::@2 +(label) main::@return +(label) main::getScreen1 +(byte) main::getScreen1_$0 +(byte) main::getScreen1_$0#0 +(label) main::getScreen1_@return +(byte) main::getScreen1_id +(byte) main::getScreen1_id#0 +(byte) main::getScreen1_id#1 +(byte*) main::getScreen1_return +(byte*) main::getScreen1_return#0 +(byte*) main::getScreen1_return#1 +(byte*) main::getScreen1_return#2 +(byte*) main::getScreen1_return#3 +(byte*) main::screen +(byte*) main::screen#0 +(byte*) main::screen#1 +(label) main::spritePtr1 +(byte*~) main::spritePtr1_$0 +(byte*) main::spritePtr1_$0#0 +(byte*~) main::spritePtr1_$1 +(byte*) main::spritePtr1_$1#0 +(label) main::spritePtr1_@return +(byte*) main::spritePtr1_return +(byte*) main::spritePtr1_return#0 +(byte*) main::spritePtr1_return#1 +(byte*) main::spritePtr1_return#2 +(byte*) main::spritePtr1_return#3 +(byte*) main::spritePtr1_screen +(byte*) main::spritePtr1_screen#0 +(byte*) main::spritePtr1_screen#1 +(byte*[]) screens +(byte*[]) screens#0 + +Culled Empty Block (label) @4 +Successful SSA optimization Pass2CullEmptyBlocks +Alias (byte) main::getScreen1_id#0 = (byte) main::getScreen1_id#1 +Alias (byte*) main::getScreen1_return#0 = (byte*) main::getScreen1_return#2 (byte*) main::getScreen1_return#1 (byte*) main::getScreen1_return#3 (byte*~) main::$0 (byte*) main::screen#1 (byte*) main::spritePtr1_screen#0 (byte*) main::spritePtr1_screen#1 +Alias (byte*) main::spritePtr1_return#0 = (byte*) main::spritePtr1_$1#0 (byte*) main::spritePtr1_return#2 (byte*) main::spritePtr1_return#1 (byte*) main::spritePtr1_return#3 (byte*~) main::$1 +Successful SSA optimization Pass2AliasElimination +Constant (const byte*) $0 = ((byte*))$400 +Constant (const byte*) $1 = ((byte*))$1400 +Constant (const byte*) main::screen#0 = 0 +Constant (const byte) main::getScreen1_id#0 = 0 +Successful SSA optimization Pass2ConstantIdentification +Constant (const byte*[]) screens#0 = { $0, $1 } +Constant (const byte) main::getScreen1_$0#0 = main::getScreen1_id#0*SIZEOF_POINTER +Successful SSA optimization Pass2ConstantIdentification +Consolidated array index constant in *(screens#0+main::getScreen1_$0#0) +Successful SSA optimization Pass2ConstantAdditionElimination +Successful SSA optimization PassNEliminateUnusedVars +Removing redundant cast (byte*) main::spritePtr1_return#0 ← ((byte*)) (byte*) main::spritePtr1_$0#0 +Successful SSA optimization Pass2EliminateRedundantCasts +Culled Empty Block (label) main::getScreen1_@return +Culled Empty Block (label) main::@1 +Culled Empty Block (label) main::spritePtr1_@return +Successful SSA optimization Pass2CullEmptyBlocks +Alias (byte*) main::spritePtr1_return#0 = (byte*) main::spritePtr1_$0#0 +Successful SSA optimization Pass2AliasElimination +Constant inlined $0 = ((byte*))(word/signed word/dword/signed dword) $400 +Constant inlined $1 = ((byte*))(word/signed word/dword/signed dword) $1400 +Constant inlined main::getScreen1_$0#0 = (const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER +Successful SSA optimization Pass2ConstantInlining +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @3 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main +CALL GRAPH +Calls in [] to main:2 + +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes +Renumbering block @3 to @1 +Renumbering block main::@2 to main::@1 +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main + +FINAL CONTROL FLOW GRAPH +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() +main: scope:[main] from @1 + [4] phi() + to:main::getScreen1 +main::getScreen1: scope:[main] from main + [5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER) + to:main::spritePtr1 +main::spritePtr1: scope:[main] from main::getScreen1 + [6] (byte*) main::spritePtr1_return#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378 + to:main::@1 +main::@1: scope:[main] from main::spritePtr1 + [7] *((byte*) main::spritePtr1_return#0) ← (byte/signed byte/word/signed word/dword/signed dword) $22 + to:main::@return +main::@return: scope:[main] from main::@1 + [8] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(void()) main() +(byte) main::getScreen1_$0 +(byte) main::getScreen1_id +(byte*) main::getScreen1_return +(byte*) main::getScreen1_return#0 4.0 +(byte*) main::screen +(byte*~) main::spritePtr1_$0 +(byte*~) main::spritePtr1_$1 +(byte*) main::spritePtr1_return +(byte*) main::spritePtr1_return#0 4.0 +(byte*) main::spritePtr1_screen +(byte*[]) screens + +Initial phi equivalence classes +Added variable main::getScreen1_return#0 to zero page equivalence class [ main::getScreen1_return#0 ] +Added variable main::spritePtr1_return#0 to zero page equivalence class [ main::spritePtr1_return#0 ] +Complete equivalence classes +[ main::getScreen1_return#0 ] +[ main::spritePtr1_return#0 ] +Allocated zp ZP_WORD:2 [ main::getScreen1_return#0 ] +Allocated zp ZP_WORD:4 [ main::spritePtr1_return#0 ] + +INITIAL ASM +//SEG0 File Comments +// Tests a cast that is not needed +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const SIZEOF_POINTER = 2 +//SEG3 @begin +bbegin: +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 +//SEG5 @1 +b1: +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG9 @end +bend: +//SEG10 main +main: { + .const getScreen1_id = 0 + .label getScreen1_return = 2 + .label spritePtr1_return = 4 + jmp getScreen1 + //SEG11 main::getScreen1 + getScreen1: + //SEG12 [5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER) -- pbuz1=_deref_pptc1 + lda screens+getScreen1_id*SIZEOF_POINTER + sta getScreen1_return + lda screens+getScreen1_id*SIZEOF_POINTER+1 + sta getScreen1_return+1 + jmp spritePtr1 + //SEG13 main::spritePtr1 + spritePtr1: + //SEG14 [6] (byte*) main::spritePtr1_return#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378 -- pbuz1=pbuz2_plus_vwuc1 + lda getScreen1_return + clc + adc #<$378 + sta spritePtr1_return + lda getScreen1_return+1 + adc #>$378 + sta spritePtr1_return+1 + jmp b1 + //SEG15 main::@1 + b1: + //SEG16 [7] *((byte*) main::spritePtr1_return#0) ← (byte/signed byte/word/signed word/dword/signed dword) $22 -- _deref_pbuz1=vbuc1 + lda #$22 + ldy #0 + sta (spritePtr1_return),y + jmp breturn + //SEG17 main::@return + breturn: + //SEG18 [8] return + rts +} + screens: .word $400, $1400 + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER) [ main::getScreen1_return#0 ] ( main:2 [ main::getScreen1_return#0 ] ) always clobbers reg byte a +Statement [6] (byte*) main::spritePtr1_return#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378 [ main::spritePtr1_return#0 ] ( main:2 [ main::spritePtr1_return#0 ] ) always clobbers reg byte a +Statement [7] *((byte*) main::spritePtr1_return#0) ← (byte/signed byte/word/signed word/dword/signed dword) $22 [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y +Potential registers zp ZP_WORD:2 [ main::getScreen1_return#0 ] : zp ZP_WORD:2 , +Potential registers zp ZP_WORD:4 [ main::spritePtr1_return#0 ] : zp ZP_WORD:4 , + +REGISTER UPLIFT SCOPES +Uplift Scope [main] 4: zp ZP_WORD:2 [ main::getScreen1_return#0 ] 4: zp ZP_WORD:4 [ main::spritePtr1_return#0 ] +Uplift Scope [] + +Uplifting [main] best 99 combination zp ZP_WORD:2 [ main::getScreen1_return#0 ] zp ZP_WORD:4 [ main::spritePtr1_return#0 ] +Uplifting [] best 99 combination +Coalescing zero page register with common assignment [ zp ZP_WORD:2 [ main::getScreen1_return#0 ] ] with [ zp ZP_WORD:4 [ main::spritePtr1_return#0 ] ] - score: 1 + +ASSEMBLER BEFORE OPTIMIZATION +//SEG0 File Comments +// Tests a cast that is not needed +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const SIZEOF_POINTER = 2 +//SEG3 @begin +bbegin: +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 +//SEG5 @1 +b1: +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG9 @end +bend: +//SEG10 main +main: { + .const getScreen1_id = 0 + .label getScreen1_return = 2 + .label spritePtr1_return = 2 + jmp getScreen1 + //SEG11 main::getScreen1 + getScreen1: + //SEG12 [5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER) -- pbuz1=_deref_pptc1 + lda screens+getScreen1_id*SIZEOF_POINTER + sta getScreen1_return + lda screens+getScreen1_id*SIZEOF_POINTER+1 + sta getScreen1_return+1 + jmp spritePtr1 + //SEG13 main::spritePtr1 + spritePtr1: + //SEG14 [6] (byte*) main::spritePtr1_return#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378 -- pbuz1=pbuz1_plus_vwuc1 + clc + lda spritePtr1_return + adc #<$378 + sta spritePtr1_return + lda spritePtr1_return+1 + adc #>$378 + sta spritePtr1_return+1 + jmp b1 + //SEG15 main::@1 + b1: + //SEG16 [7] *((byte*) main::spritePtr1_return#0) ← (byte/signed byte/word/signed word/dword/signed dword) $22 -- _deref_pbuz1=vbuc1 + lda #$22 + ldy #0 + sta (spritePtr1_return),y + jmp breturn + //SEG17 main::@return + breturn: + //SEG18 [8] return + rts +} + screens: .word $400, $1400 + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp b1 +Removing instruction jmp bend +Removing instruction jmp getScreen1 +Removing instruction jmp spritePtr1 +Removing instruction jmp b1 +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction b1_from_bbegin: +Removing instruction b1: +Removing instruction main_from_b1: +Removing instruction bend_from_b1: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction bend: +Removing instruction getScreen1: +Removing instruction spritePtr1: +Removing instruction b1: +Removing instruction breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Updating BasicUpstart to call main directly +Removing instruction jsr main +Succesful ASM optimization Pass5SkipBegin +Removing instruction bbegin: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +(label) @1 +(label) @begin +(label) @end +(const byte) SIZEOF_POINTER SIZEOF_POINTER = (byte/signed byte/word/signed word/dword/signed dword) 2 +(void()) main() +(label) main::@1 +(label) main::@return +(label) main::getScreen1 +(byte) main::getScreen1_$0 +(byte) main::getScreen1_id +(const byte) main::getScreen1_id#0 getScreen1_id = (byte/signed byte/word/signed word/dword/signed dword) 0 +(byte*) main::getScreen1_return +(byte*) main::getScreen1_return#0 getScreen1_return zp ZP_WORD:2 4.0 +(byte*) main::screen +(label) main::spritePtr1 +(byte*~) main::spritePtr1_$0 +(byte*~) main::spritePtr1_$1 +(byte*) main::spritePtr1_return +(byte*) main::spritePtr1_return#0 spritePtr1_return zp ZP_WORD:2 4.0 +(byte*) main::spritePtr1_screen +(byte*[]) screens +(const byte*[]) screens#0 screens = { ((byte*))(word/signed word/dword/signed dword) $400, ((byte*))(word/signed word/dword/signed dword) $1400 } + +zp ZP_WORD:2 [ main::getScreen1_return#0 main::spritePtr1_return#0 ] + + +FINAL ASSEMBLER +Score: 48 + +//SEG0 File Comments +// Tests a cast that is not needed +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const SIZEOF_POINTER = 2 +//SEG3 @begin +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +//SEG5 @1 +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +//SEG9 @end +//SEG10 main +main: { + .const getScreen1_id = 0 + .label getScreen1_return = 2 + .label spritePtr1_return = 2 + //SEG11 main::getScreen1 + //SEG12 [5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER) -- pbuz1=_deref_pptc1 + lda screens+getScreen1_id*SIZEOF_POINTER + sta getScreen1_return + lda screens+getScreen1_id*SIZEOF_POINTER+1 + sta getScreen1_return+1 + //SEG13 main::spritePtr1 + //SEG14 [6] (byte*) main::spritePtr1_return#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378 -- pbuz1=pbuz1_plus_vwuc1 + clc + lda spritePtr1_return + adc #<$378 + sta spritePtr1_return + lda spritePtr1_return+1 + adc #>$378 + sta spritePtr1_return+1 + //SEG15 main::@1 + //SEG16 [7] *((byte*) main::spritePtr1_return#0) ← (byte/signed byte/word/signed word/dword/signed dword) $22 -- _deref_pbuz1=vbuc1 + lda #$22 + ldy #0 + sta (spritePtr1_return),y + //SEG17 main::@return + //SEG18 [8] return + rts +} + screens: .word $400, $1400 + diff --git a/src/test/ref/cast-not-needed-2.sym b/src/test/ref/cast-not-needed-2.sym new file mode 100644 index 000000000..005d5d1ae --- /dev/null +++ b/src/test/ref/cast-not-needed-2.sym @@ -0,0 +1,24 @@ +(label) @1 +(label) @begin +(label) @end +(const byte) SIZEOF_POINTER SIZEOF_POINTER = (byte/signed byte/word/signed word/dword/signed dword) 2 +(void()) main() +(label) main::@1 +(label) main::@return +(label) main::getScreen1 +(byte) main::getScreen1_$0 +(byte) main::getScreen1_id +(const byte) main::getScreen1_id#0 getScreen1_id = (byte/signed byte/word/signed word/dword/signed dword) 0 +(byte*) main::getScreen1_return +(byte*) main::getScreen1_return#0 getScreen1_return zp ZP_WORD:2 4.0 +(byte*) main::screen +(label) main::spritePtr1 +(byte*~) main::spritePtr1_$0 +(byte*~) main::spritePtr1_$1 +(byte*) main::spritePtr1_return +(byte*) main::spritePtr1_return#0 spritePtr1_return zp ZP_WORD:2 4.0 +(byte*) main::spritePtr1_screen +(byte*[]) screens +(const byte*[]) screens#0 screens = { ((byte*))(word/signed word/dword/signed dword) $400, ((byte*))(word/signed word/dword/signed dword) $1400 } + +zp ZP_WORD:2 [ main::getScreen1_return#0 main::spritePtr1_return#0 ] diff --git a/src/test/ref/cast-not-needed-3.asm b/src/test/ref/cast-not-needed-3.asm new file mode 100644 index 000000000..4a3ee07b6 --- /dev/null +++ b/src/test/ref/cast-not-needed-3.asm @@ -0,0 +1,27 @@ +// Tests a cast that is not needed +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .const SIZEOF_POINTER = 2 +main: { + .label DSP = $400 + .const getScreen1_id = 0 + .label getScreen1_return = 2 + .label spritePtr1__0 = 2 + lda screens+getScreen1_id*SIZEOF_POINTER + sta getScreen1_return + lda screens+getScreen1_id*SIZEOF_POINTER+1 + sta getScreen1_return+1 + clc + lda spritePtr1__0 + adc #<$378 + sta spritePtr1__0 + lda spritePtr1__0+1 + adc #>$378 + sta spritePtr1__0+1 + ldy #0 + lda (spritePtr1__0),y + sta DSP + rts +} + screens: .word $400, $1400 diff --git a/src/test/ref/cast-not-needed-3.cfg b/src/test/ref/cast-not-needed-3.cfg new file mode 100644 index 000000000..270ccf368 --- /dev/null +++ b/src/test/ref/cast-not-needed-3.cfg @@ -0,0 +1,25 @@ +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() +main: scope:[main] from @1 + [4] phi() + to:main::getScreen1 +main::getScreen1: scope:[main] from main + [5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER) + to:main::spritePtr1 +main::spritePtr1: scope:[main] from main::getScreen1 + [6] (byte*) main::spritePtr1_$0#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378 + [7] (byte) main::spritePtr1_return#0 ← *((byte*) main::spritePtr1_$0#0) + to:main::@1 +main::@1: scope:[main] from main::spritePtr1 + [8] *((const byte*) main::DSP#0) ← (byte) main::spritePtr1_return#0 + to:main::@return +main::@return: scope:[main] from main::@1 + [9] return + to:@return diff --git a/src/test/ref/cast-not-needed-3.log b/src/test/ref/cast-not-needed-3.log new file mode 100644 index 000000000..26d2ea08d --- /dev/null +++ b/src/test/ref/cast-not-needed-3.log @@ -0,0 +1,455 @@ +Fixing pointer array-indexing *((byte*[]) screens + (byte) getScreen::id) +Identified constant variable (byte*) main::DSP +Inlined call (byte*~) main::$0 ← call getScreen (byte/signed byte/word/signed word/dword/signed dword) 0 +Inlined call (byte~) main::$1 ← call spritePtr (byte*~) main::$0 + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + (byte*~) $0 ← ((byte*)) (word/signed word/dword/signed dword) $400 + (byte*~) $1 ← ((byte*)) (word/signed word/dword/signed dword) $1400 + (byte*[]) screens#0 ← { (byte*~) $0, (byte*~) $1 } + to:@3 +main: scope:[main] from @3 + (byte*) main::DSP#0 ← ((byte*)) (word/signed word/dword/signed dword) $400 + (byte) main::getScreen1_id#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 + to:main::getScreen1 +main::getScreen1: scope:[main] from main + (byte) main::getScreen1_id#1 ← phi( main/(byte) main::getScreen1_id#0 ) + (byte) main::getScreen1_$0#0 ← (byte) main::getScreen1_id#1 * (const byte) SIZEOF_POINTER + (byte*) main::getScreen1_return#0 ← *((byte*[]) screens#0 + (byte) main::getScreen1_$0#0) + to:main::getScreen1_@return +main::getScreen1_@return: scope:[main] from main::getScreen1 + (byte*) main::getScreen1_return#2 ← phi( main::getScreen1/(byte*) main::getScreen1_return#0 ) + (byte*) main::getScreen1_return#1 ← (byte*) main::getScreen1_return#2 + to:main::@1 +main::@1: scope:[main] from main::getScreen1_@return + (byte*) main::getScreen1_return#3 ← phi( main::getScreen1_@return/(byte*) main::getScreen1_return#1 ) + (byte*~) main::$0 ← (byte*) main::getScreen1_return#3 + (byte*) main::spritePtr1_screen#0 ← (byte*~) main::$0 + to:main::spritePtr1 +main::spritePtr1: scope:[main] from main::@1 + (byte*) main::spritePtr1_screen#1 ← phi( main::@1/(byte*) main::spritePtr1_screen#0 ) + (byte*) main::spritePtr1_$0#0 ← (byte*) main::spritePtr1_screen#1 + (word/signed word/dword/signed dword) $378 + (byte) main::spritePtr1_$1#0 ← ((byte)) *((byte*) main::spritePtr1_$0#0) + (byte) main::spritePtr1_return#0 ← (byte) main::spritePtr1_$1#0 + to:main::spritePtr1_@return +main::spritePtr1_@return: scope:[main] from main::spritePtr1 + (byte) main::spritePtr1_return#2 ← phi( main::spritePtr1/(byte) main::spritePtr1_return#0 ) + (byte) main::spritePtr1_return#1 ← (byte) main::spritePtr1_return#2 + to:main::@2 +main::@2: scope:[main] from main::spritePtr1_@return + (byte) main::spritePtr1_return#3 ← phi( main::spritePtr1_@return/(byte) main::spritePtr1_return#1 ) + (byte~) main::$1 ← (byte) main::spritePtr1_return#3 + *((byte*) main::DSP#0 + (byte/signed byte/word/signed word/dword/signed dword) 0) ← (byte~) main::$1 + to:main::@return +main::@return: scope:[main] from main::@2 + return + to:@return +@3: scope:[] from @begin + call main + to:@4 +@4: scope:[] from @3 + to:@end +@end: scope:[] from @4 + +SYMBOL TABLE SSA +(byte*~) $0 +(byte*~) $1 +(label) @3 +(label) @4 +(label) @begin +(label) @end +(const byte) SIZEOF_POINTER = (byte/signed byte/word/signed word/dword/signed dword) 2 +(void()) main() +(byte*~) main::$0 +(byte~) main::$1 +(label) main::@1 +(label) main::@2 +(label) main::@return +(byte*) main::DSP +(byte*) main::DSP#0 +(label) main::getScreen1 +(byte) main::getScreen1_$0 +(byte) main::getScreen1_$0#0 +(label) main::getScreen1_@return +(byte) main::getScreen1_id +(byte) main::getScreen1_id#0 +(byte) main::getScreen1_id#1 +(byte*) main::getScreen1_return +(byte*) main::getScreen1_return#0 +(byte*) main::getScreen1_return#1 +(byte*) main::getScreen1_return#2 +(byte*) main::getScreen1_return#3 +(label) main::spritePtr1 +(byte*~) main::spritePtr1_$0 +(byte*) main::spritePtr1_$0#0 +(byte~) main::spritePtr1_$1 +(byte) main::spritePtr1_$1#0 +(label) main::spritePtr1_@return +(byte) main::spritePtr1_return +(byte) main::spritePtr1_return#0 +(byte) main::spritePtr1_return#1 +(byte) main::spritePtr1_return#2 +(byte) main::spritePtr1_return#3 +(byte*) main::spritePtr1_screen +(byte*) main::spritePtr1_screen#0 +(byte*) main::spritePtr1_screen#1 +(byte*[]) screens +(byte*[]) screens#0 + +Culled Empty Block (label) @4 +Successful SSA optimization Pass2CullEmptyBlocks +Alias (byte) main::getScreen1_id#0 = (byte) main::getScreen1_id#1 +Alias (byte*) main::getScreen1_return#0 = (byte*) main::getScreen1_return#2 (byte*) main::getScreen1_return#1 (byte*) main::getScreen1_return#3 (byte*~) main::$0 (byte*) main::spritePtr1_screen#0 (byte*) main::spritePtr1_screen#1 +Alias (byte) main::spritePtr1_return#0 = (byte) main::spritePtr1_$1#0 (byte) main::spritePtr1_return#2 (byte) main::spritePtr1_return#1 (byte) main::spritePtr1_return#3 (byte~) main::$1 +Successful SSA optimization Pass2AliasElimination +Constant (const byte*) $0 = ((byte*))$400 +Constant (const byte*) $1 = ((byte*))$1400 +Constant (const byte*) main::DSP#0 = ((byte*))$400 +Constant (const byte) main::getScreen1_id#0 = 0 +Successful SSA optimization Pass2ConstantIdentification +Constant (const byte*[]) screens#0 = { $0, $1 } +Constant (const byte) main::getScreen1_$0#0 = main::getScreen1_id#0*SIZEOF_POINTER +Successful SSA optimization Pass2ConstantIdentification +Consolidated array index constant in *(screens#0+main::getScreen1_$0#0) +Consolidated array index constant in *(main::DSP#0+0) +Successful SSA optimization Pass2ConstantAdditionElimination +Removing redundant cast (byte) main::spritePtr1_return#0 ← ((byte)) *((byte*) main::spritePtr1_$0#0) +Successful SSA optimization Pass2EliminateRedundantCasts +Culled Empty Block (label) main::getScreen1_@return +Culled Empty Block (label) main::@1 +Culled Empty Block (label) main::spritePtr1_@return +Successful SSA optimization Pass2CullEmptyBlocks +Constant inlined $0 = ((byte*))(word/signed word/dword/signed dword) $400 +Constant inlined $1 = ((byte*))(word/signed word/dword/signed dword) $1400 +Constant inlined main::getScreen1_$0#0 = (const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER +Successful SSA optimization Pass2ConstantInlining +Simplifying constant plus zero main::DSP#0+0 +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @3 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main +CALL GRAPH +Calls in [] to main:2 + +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes +Renumbering block @3 to @1 +Renumbering block main::@2 to main::@1 +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main + +FINAL CONTROL FLOW GRAPH +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() +main: scope:[main] from @1 + [4] phi() + to:main::getScreen1 +main::getScreen1: scope:[main] from main + [5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER) + to:main::spritePtr1 +main::spritePtr1: scope:[main] from main::getScreen1 + [6] (byte*) main::spritePtr1_$0#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378 + [7] (byte) main::spritePtr1_return#0 ← *((byte*) main::spritePtr1_$0#0) + to:main::@1 +main::@1: scope:[main] from main::spritePtr1 + [8] *((const byte*) main::DSP#0) ← (byte) main::spritePtr1_return#0 + to:main::@return +main::@return: scope:[main] from main::@1 + [9] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(void()) main() +(byte*) main::DSP +(byte) main::getScreen1_$0 +(byte) main::getScreen1_id +(byte*) main::getScreen1_return +(byte*) main::getScreen1_return#0 4.0 +(byte*~) main::spritePtr1_$0 +(byte*) main::spritePtr1_$0#0 4.0 +(byte~) main::spritePtr1_$1 +(byte) main::spritePtr1_return +(byte) main::spritePtr1_return#0 4.0 +(byte*) main::spritePtr1_screen +(byte*[]) screens + +Initial phi equivalence classes +Added variable main::getScreen1_return#0 to zero page equivalence class [ main::getScreen1_return#0 ] +Added variable main::spritePtr1_$0#0 to zero page equivalence class [ main::spritePtr1_$0#0 ] +Added variable main::spritePtr1_return#0 to zero page equivalence class [ main::spritePtr1_return#0 ] +Complete equivalence classes +[ main::getScreen1_return#0 ] +[ main::spritePtr1_$0#0 ] +[ main::spritePtr1_return#0 ] +Allocated zp ZP_WORD:2 [ main::getScreen1_return#0 ] +Allocated zp ZP_WORD:4 [ main::spritePtr1_$0#0 ] +Allocated zp ZP_BYTE:6 [ main::spritePtr1_return#0 ] + +INITIAL ASM +//SEG0 File Comments +// Tests a cast that is not needed +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const SIZEOF_POINTER = 2 +//SEG3 @begin +bbegin: +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 +//SEG5 @1 +b1: +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG9 @end +bend: +//SEG10 main +main: { + .label DSP = $400 + .const getScreen1_id = 0 + .label getScreen1_return = 2 + .label spritePtr1__0 = 4 + .label spritePtr1_return = 6 + jmp getScreen1 + //SEG11 main::getScreen1 + getScreen1: + //SEG12 [5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER) -- pbuz1=_deref_pptc1 + lda screens+getScreen1_id*SIZEOF_POINTER + sta getScreen1_return + lda screens+getScreen1_id*SIZEOF_POINTER+1 + sta getScreen1_return+1 + jmp spritePtr1 + //SEG13 main::spritePtr1 + spritePtr1: + //SEG14 [6] (byte*) main::spritePtr1_$0#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378 -- pbuz1=pbuz2_plus_vwuc1 + lda getScreen1_return + clc + adc #<$378 + sta spritePtr1__0 + lda getScreen1_return+1 + adc #>$378 + sta spritePtr1__0+1 + //SEG15 [7] (byte) main::spritePtr1_return#0 ← *((byte*) main::spritePtr1_$0#0) -- vbuz1=_deref_pbuz2 + ldy #0 + lda (spritePtr1__0),y + sta spritePtr1_return + jmp b1 + //SEG16 main::@1 + b1: + //SEG17 [8] *((const byte*) main::DSP#0) ← (byte) main::spritePtr1_return#0 -- _deref_pbuc1=vbuz1 + lda spritePtr1_return + sta DSP + jmp breturn + //SEG18 main::@return + breturn: + //SEG19 [9] return + rts +} + screens: .word $400, $1400 + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER) [ main::getScreen1_return#0 ] ( main:2 [ main::getScreen1_return#0 ] ) always clobbers reg byte a +Statement [6] (byte*) main::spritePtr1_$0#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378 [ main::spritePtr1_$0#0 ] ( main:2 [ main::spritePtr1_$0#0 ] ) always clobbers reg byte a +Statement [7] (byte) main::spritePtr1_return#0 ← *((byte*) main::spritePtr1_$0#0) [ main::spritePtr1_return#0 ] ( main:2 [ main::spritePtr1_return#0 ] ) always clobbers reg byte a reg byte y +Potential registers zp ZP_WORD:2 [ main::getScreen1_return#0 ] : zp ZP_WORD:2 , +Potential registers zp ZP_WORD:4 [ main::spritePtr1_$0#0 ] : zp ZP_WORD:4 , +Potential registers zp ZP_BYTE:6 [ main::spritePtr1_return#0 ] : zp ZP_BYTE:6 , reg byte a , reg byte x , reg byte y , + +REGISTER UPLIFT SCOPES +Uplift Scope [main] 4: zp ZP_WORD:2 [ main::getScreen1_return#0 ] 4: zp ZP_WORD:4 [ main::spritePtr1_$0#0 ] 4: zp ZP_BYTE:6 [ main::spritePtr1_return#0 ] +Uplift Scope [] + +Uplifting [main] best 100 combination zp ZP_WORD:2 [ main::getScreen1_return#0 ] zp ZP_WORD:4 [ main::spritePtr1_$0#0 ] reg byte a [ main::spritePtr1_return#0 ] +Uplifting [] best 100 combination +Coalescing zero page register with common assignment [ zp ZP_WORD:2 [ main::getScreen1_return#0 ] ] with [ zp ZP_WORD:4 [ main::spritePtr1_$0#0 ] ] - score: 1 + +ASSEMBLER BEFORE OPTIMIZATION +//SEG0 File Comments +// Tests a cast that is not needed +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const SIZEOF_POINTER = 2 +//SEG3 @begin +bbegin: +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 +//SEG5 @1 +b1: +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG9 @end +bend: +//SEG10 main +main: { + .label DSP = $400 + .const getScreen1_id = 0 + .label getScreen1_return = 2 + .label spritePtr1__0 = 2 + jmp getScreen1 + //SEG11 main::getScreen1 + getScreen1: + //SEG12 [5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER) -- pbuz1=_deref_pptc1 + lda screens+getScreen1_id*SIZEOF_POINTER + sta getScreen1_return + lda screens+getScreen1_id*SIZEOF_POINTER+1 + sta getScreen1_return+1 + jmp spritePtr1 + //SEG13 main::spritePtr1 + spritePtr1: + //SEG14 [6] (byte*) main::spritePtr1_$0#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378 -- pbuz1=pbuz1_plus_vwuc1 + clc + lda spritePtr1__0 + adc #<$378 + sta spritePtr1__0 + lda spritePtr1__0+1 + adc #>$378 + sta spritePtr1__0+1 + //SEG15 [7] (byte) main::spritePtr1_return#0 ← *((byte*) main::spritePtr1_$0#0) -- vbuaa=_deref_pbuz1 + ldy #0 + lda (spritePtr1__0),y + jmp b1 + //SEG16 main::@1 + b1: + //SEG17 [8] *((const byte*) main::DSP#0) ← (byte) main::spritePtr1_return#0 -- _deref_pbuc1=vbuaa + sta DSP + jmp breturn + //SEG18 main::@return + breturn: + //SEG19 [9] return + rts +} + screens: .word $400, $1400 + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp b1 +Removing instruction jmp bend +Removing instruction jmp getScreen1 +Removing instruction jmp spritePtr1 +Removing instruction jmp b1 +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction b1_from_bbegin: +Removing instruction b1: +Removing instruction main_from_b1: +Removing instruction bend_from_b1: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction bend: +Removing instruction getScreen1: +Removing instruction spritePtr1: +Removing instruction b1: +Removing instruction breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Updating BasicUpstart to call main directly +Removing instruction jsr main +Succesful ASM optimization Pass5SkipBegin +Removing instruction bbegin: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +(label) @1 +(label) @begin +(label) @end +(const byte) SIZEOF_POINTER SIZEOF_POINTER = (byte/signed byte/word/signed word/dword/signed dword) 2 +(void()) main() +(label) main::@1 +(label) main::@return +(byte*) main::DSP +(const byte*) main::DSP#0 DSP = ((byte*))(word/signed word/dword/signed dword) $400 +(label) main::getScreen1 +(byte) main::getScreen1_$0 +(byte) main::getScreen1_id +(const byte) main::getScreen1_id#0 getScreen1_id = (byte/signed byte/word/signed word/dword/signed dword) 0 +(byte*) main::getScreen1_return +(byte*) main::getScreen1_return#0 getScreen1_return zp ZP_WORD:2 4.0 +(label) main::spritePtr1 +(byte*~) main::spritePtr1_$0 +(byte*) main::spritePtr1_$0#0 spritePtr1_$0 zp ZP_WORD:2 4.0 +(byte~) main::spritePtr1_$1 +(byte) main::spritePtr1_return +(byte) main::spritePtr1_return#0 reg byte a 4.0 +(byte*) main::spritePtr1_screen +(byte*[]) screens +(const byte*[]) screens#0 screens = { ((byte*))(word/signed word/dword/signed dword) $400, ((byte*))(word/signed word/dword/signed dword) $1400 } + +zp ZP_WORD:2 [ main::getScreen1_return#0 main::spritePtr1_$0#0 ] +reg byte a [ main::spritePtr1_return#0 ] + + +FINAL ASSEMBLER +Score: 49 + +//SEG0 File Comments +// Tests a cast that is not needed +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const SIZEOF_POINTER = 2 +//SEG3 @begin +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +//SEG5 @1 +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +//SEG9 @end +//SEG10 main +main: { + .label DSP = $400 + .const getScreen1_id = 0 + .label getScreen1_return = 2 + .label spritePtr1__0 = 2 + //SEG11 main::getScreen1 + //SEG12 [5] (byte*) main::getScreen1_return#0 ← *((const byte*[]) screens#0+(const byte) main::getScreen1_id#0*(const byte) SIZEOF_POINTER) -- pbuz1=_deref_pptc1 + lda screens+getScreen1_id*SIZEOF_POINTER + sta getScreen1_return + lda screens+getScreen1_id*SIZEOF_POINTER+1 + sta getScreen1_return+1 + //SEG13 main::spritePtr1 + //SEG14 [6] (byte*) main::spritePtr1_$0#0 ← (byte*) main::getScreen1_return#0 + (word/signed word/dword/signed dword) $378 -- pbuz1=pbuz1_plus_vwuc1 + clc + lda spritePtr1__0 + adc #<$378 + sta spritePtr1__0 + lda spritePtr1__0+1 + adc #>$378 + sta spritePtr1__0+1 + //SEG15 [7] (byte) main::spritePtr1_return#0 ← *((byte*) main::spritePtr1_$0#0) -- vbuaa=_deref_pbuz1 + ldy #0 + lda (spritePtr1__0),y + //SEG16 main::@1 + //SEG17 [8] *((const byte*) main::DSP#0) ← (byte) main::spritePtr1_return#0 -- _deref_pbuc1=vbuaa + sta DSP + //SEG18 main::@return + //SEG19 [9] return + rts +} + screens: .word $400, $1400 + diff --git a/src/test/ref/cast-not-needed-3.sym b/src/test/ref/cast-not-needed-3.sym new file mode 100644 index 000000000..65e83e2a7 --- /dev/null +++ b/src/test/ref/cast-not-needed-3.sym @@ -0,0 +1,27 @@ +(label) @1 +(label) @begin +(label) @end +(const byte) SIZEOF_POINTER SIZEOF_POINTER = (byte/signed byte/word/signed word/dword/signed dword) 2 +(void()) main() +(label) main::@1 +(label) main::@return +(byte*) main::DSP +(const byte*) main::DSP#0 DSP = ((byte*))(word/signed word/dword/signed dword) $400 +(label) main::getScreen1 +(byte) main::getScreen1_$0 +(byte) main::getScreen1_id +(const byte) main::getScreen1_id#0 getScreen1_id = (byte/signed byte/word/signed word/dword/signed dword) 0 +(byte*) main::getScreen1_return +(byte*) main::getScreen1_return#0 getScreen1_return zp ZP_WORD:2 4.0 +(label) main::spritePtr1 +(byte*~) main::spritePtr1_$0 +(byte*) main::spritePtr1_$0#0 spritePtr1_$0 zp ZP_WORD:2 4.0 +(byte~) main::spritePtr1_$1 +(byte) main::spritePtr1_return +(byte) main::spritePtr1_return#0 reg byte a 4.0 +(byte*) main::spritePtr1_screen +(byte*[]) screens +(const byte*[]) screens#0 screens = { ((byte*))(word/signed word/dword/signed dword) $400, ((byte*))(word/signed word/dword/signed dword) $1400 } + +zp ZP_WORD:2 [ main::getScreen1_return#0 main::spritePtr1_$0#0 ] +reg byte a [ main::spritePtr1_return#0 ] diff --git a/src/test/ref/cast-not-needed.asm b/src/test/ref/cast-not-needed.asm index 8f21f91a0..171d7ec07 100644 --- a/src/test/ref/cast-not-needed.asm +++ b/src/test/ref/cast-not-needed.asm @@ -1,4 +1,4 @@ -// +// Tests a cast that is not needed .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" diff --git a/src/test/ref/cast-not-needed.log b/src/test/ref/cast-not-needed.log index dfeffc2ce..7eb40b7dd 100644 --- a/src/test/ref/cast-not-needed.log +++ b/src/test/ref/cast-not-needed.log @@ -99,7 +99,7 @@ Complete equivalence classes INITIAL ASM //SEG0 File Comments -// +// Tests a cast that is not needed //SEG1 Basic Upstart .pc = $801 "Basic" :BasicUpstart(bbegin) @@ -146,7 +146,7 @@ Uplifting [] best 27 combination ASSEMBLER BEFORE OPTIMIZATION //SEG0 File Comments -// +// Tests a cast that is not needed //SEG1 Basic Upstart .pc = $801 "Basic" :BasicUpstart(bbegin) @@ -218,7 +218,7 @@ FINAL ASSEMBLER Score: 12 //SEG0 File Comments -// +// Tests a cast that is not needed //SEG1 Basic Upstart .pc = $801 "Basic" :BasicUpstart(main) diff --git a/src/test/ref/semi-struct-1.asm b/src/test/ref/semi-struct-1.asm new file mode 100644 index 000000000..b78bfc8fe --- /dev/null +++ b/src/test/ref/semi-struct-1.asm @@ -0,0 +1,212 @@ +// Implementing a semi-struct without the struct keyword by using pointer math and inline functions +// +// struct Point { +// byte xpos; // The x-position +// byte ypos; // The y-position +// }; +// Point[NUM_POINTS] points; +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // The size of a point + .const SIZEOF_POINT = 2 + // The number of points + .const NUM_POINTS = 4 + .label print_char_cursor = 5 + .label print_line_cursor = 2 +// Initialize some points and print them +main: { + jsr init_points + jsr print_points + rts +} +// Print points +print_points: { + .label pointXpos1__0 = 9 + .label pointYpos1_return = 9 + jsr print_cls + lda #<$400 + sta print_line_cursor + lda #>$400 + sta print_line_cursor+1 + lda #<$400 + sta print_char_cursor + lda #>$400 + sta print_char_cursor+1 + ldx #0 + b1: + txa + asl + clc + adc #points + adc #0 + sta pointXpos1__0+1 + ldy #0 + lda (pointXpos1__0),y + sta print_byte.b + jsr print_byte + jsr print_str + inc pointYpos1_return + bne !+ + inc pointYpos1_return+1 + !: + ldy #0 + lda (pointYpos1_return),y + sta print_byte.b + jsr print_byte + jsr print_ln + inx + cpx #NUM_POINTS-1+1 + bne b7 + rts + b7: + lda print_line_cursor + sta print_char_cursor + lda print_line_cursor+1 + sta print_char_cursor+1 + jmp b1 + str: .text " @" +} +// Print a newline +print_ln: { + b1: + lda #$28 + clc + adc print_line_cursor + sta print_line_cursor + bcc !+ + inc print_line_cursor+1 + !: + lda print_line_cursor+1 + cmp print_char_cursor+1 + bcc b1 + bne !+ + lda print_line_cursor + cmp print_char_cursor + bcc b1 + !: + rts +} +// Print a byte as HEX +// print_byte(byte zeropage(4) b) +print_byte: { + .label b = 4 + lda b + lsr + lsr + lsr + lsr + tay + lda print_hextab,y + jsr print_char + lda #$f + and b + tay + lda print_hextab,y + jsr print_char + rts +} +// Print a single char +// print_char(byte register(A) ch) +print_char: { + ldy #0 + sta (print_char_cursor),y + inc print_char_cursor + bne !+ + inc print_char_cursor+1 + !: + rts +} +// Print a zero-terminated string +// print_str(byte* zeropage(7) str) +print_str: { + .label str = 7 + lda #print_points.str + sta str+1 + b1: + ldy #0 + lda (str),y + cmp #'@' + bne b2 + rts + b2: + ldy #0 + lda (str),y + sta (print_char_cursor),y + inc print_char_cursor + bne !+ + inc print_char_cursor+1 + !: + inc str + bne !+ + inc str+1 + !: + jmp b1 +} +// Clear the screen. Also resets current line/char cursor. +print_cls: { + .label sc = 2 + lda #<$400 + sta sc + lda #>$400 + sta sc+1 + b1: + lda #' ' + ldy #0 + sta (sc),y + inc sc + bne !+ + inc sc+1 + !: + lda sc+1 + cmp #>$400+$3e8 + bne b1 + lda sc + cmp #<$400+$3e8 + bne b1 + rts +} +// Initialize points +init_points: { + .label pointXpos1__0 = 2 + .label pointYpos1_return = 2 + .label i = 4 + ldx #$a + lda #0 + sta i + b1: + lda i + asl + clc + adc #points + adc #0 + sta pointXpos1__0+1 + txa + ldy #0 + sta (pointXpos1__0),y + txa + axs #-[$a] + inc pointYpos1_return + bne !+ + inc pointYpos1_return+1 + !: + txa + ldy #0 + sta (pointYpos1_return),y + txa + axs #-[$a] + inc i + lda #NUM_POINTS-1+1 + cmp i + bne b1 + rts +} + print_hextab: .text "0123456789abcdef" + // All points + points: .fill NUM_POINTS*SIZEOF_POINT, 0 diff --git a/src/test/ref/semi-struct-1.cfg b/src/test/ref/semi-struct-1.cfg new file mode 100644 index 000000000..56dc1b522 --- /dev/null +++ b/src/test/ref/semi-struct-1.cfg @@ -0,0 +1,158 @@ +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() +main: scope:[main] from @1 + [4] phi() + [5] call init_points + to:main::@1 +main::@1: scope:[main] from main + [6] phi() + [7] call print_points + to:main::@return +main::@return: scope:[main] from main::@1 + [8] return + to:@return +print_points: scope:[print_points] from main::@1 + [9] phi() + [10] call print_cls + to:print_points::@1 +print_points::@1: scope:[print_points] from print_points print_points::@7 + [11] (byte*) print_line_cursor#24 ← phi( print_points::@7/(byte*) print_line_cursor#1 print_points/((byte*))(word/signed word/dword/signed dword) $400 ) + [11] (byte*) print_char_cursor#45 ← phi( print_points::@7/(byte*~) print_char_cursor#60 print_points/((byte*))(word/signed word/dword/signed dword) $400 ) + [11] (byte) print_points::i#10 ← phi( print_points::@7/(byte) print_points::i#1 print_points/(byte/signed byte/word/signed word/dword/signed dword) 0 ) + to:print_points::getPoint1 +print_points::getPoint1: scope:[print_points] from print_points::@1 + [12] (byte) print_points::getPoint1_$0#0 ← (byte) print_points::i#10 << (byte/signed byte/word/signed word/dword/signed dword) 1 + [13] (byte*) print_points::pointXpos1_$0#0 ← (const byte[NUM_POINTS#0*SIZEOF_POINT#0]) points#0 + (byte) print_points::getPoint1_$0#0 + to:print_points::pointXpos1 +print_points::pointXpos1: scope:[print_points] from print_points::getPoint1 + [14] phi() + to:print_points::@2 +print_points::@2: scope:[print_points] from print_points::pointXpos1 + [15] (byte) print_byte::b#0 ← *((byte*) print_points::pointXpos1_$0#0) + [16] call print_byte + to:print_points::@4 +print_points::@4: scope:[print_points] from print_points::@2 + [17] phi() + [18] call print_str + to:print_points::pointYpos1 +print_points::pointYpos1: scope:[print_points] from print_points::@4 + [19] (byte*) print_points::pointYpos1_return#0 ← (byte*) print_points::pointXpos1_$0#0 + (byte/signed byte/word/signed word/dword/signed dword) 1 + to:print_points::@3 +print_points::@3: scope:[print_points] from print_points::pointYpos1 + [20] (byte) print_byte::b#1 ← *((byte*) print_points::pointYpos1_return#0) + [21] call print_byte + to:print_points::@5 +print_points::@5: scope:[print_points] from print_points::@3 + [22] phi() + [23] call print_ln + to:print_points::@6 +print_points::@6: scope:[print_points] from print_points::@5 + [24] (byte) print_points::i#1 ← ++ (byte) print_points::i#10 + [25] if((byte) print_points::i#1!=(const byte) NUM_POINTS#0-(byte/signed byte/word/signed word/dword/signed dword) 1+(byte/signed byte/word/signed word/dword/signed dword) 1) goto print_points::@7 + to:print_points::@return +print_points::@return: scope:[print_points] from print_points::@6 + [26] return + to:@return +print_points::@7: scope:[print_points] from print_points::@6 + [27] (byte*~) print_char_cursor#60 ← (byte*) print_line_cursor#1 + to:print_points::@1 +print_ln: scope:[print_ln] from print_points::@5 + [28] phi() + to:print_ln::@1 +print_ln::@1: scope:[print_ln] from print_ln print_ln::@1 + [29] (byte*) print_line_cursor#11 ← phi( print_ln/(byte*) print_line_cursor#24 print_ln::@1/(byte*) print_line_cursor#1 ) + [30] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#11 + (byte/signed byte/word/signed word/dword/signed dword) $28 + [31] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#29) goto print_ln::@1 + to:print_ln::@return +print_ln::@return: scope:[print_ln] from print_ln::@1 + [32] return + to:@return +print_byte: scope:[print_byte] from print_points::@2 print_points::@3 + [33] (byte*) print_char_cursor#42 ← phi( print_points::@2/(byte*) print_char_cursor#45 print_points::@3/(byte*) print_char_cursor#2 ) + [33] (byte) print_byte::b#2 ← phi( print_points::@2/(byte) print_byte::b#0 print_points::@3/(byte) print_byte::b#1 ) + [34] (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4 + [35] (byte) print_char::ch#0 ← *((const byte[]) print_hextab#0 + (byte~) print_byte::$0) + [36] call print_char + to:print_byte::@1 +print_byte::@1: scope:[print_byte] from print_byte + [37] (byte~) print_byte::$2 ← (byte) print_byte::b#2 & (byte/signed byte/word/signed word/dword/signed dword) $f + [38] (byte) print_char::ch#1 ← *((const byte[]) print_hextab#0 + (byte~) print_byte::$2) + [39] call print_char + to:print_byte::@return +print_byte::@return: scope:[print_byte] from print_byte::@1 + [40] return + to:@return +print_char: scope:[print_char] from print_byte print_byte::@1 + [41] (byte*) print_char_cursor#28 ← phi( print_byte/(byte*) print_char_cursor#42 print_byte::@1/(byte*) print_char_cursor#29 ) + [41] (byte) print_char::ch#2 ← phi( print_byte/(byte) print_char::ch#0 print_byte::@1/(byte) print_char::ch#1 ) + [42] *((byte*) print_char_cursor#28) ← (byte) print_char::ch#2 + [43] (byte*) print_char_cursor#29 ← ++ (byte*) print_char_cursor#28 + to:print_char::@return +print_char::@return: scope:[print_char] from print_char + [44] return + to:@return +print_str: scope:[print_str] from print_points::@4 + [45] phi() + to:print_str::@1 +print_str::@1: scope:[print_str] from print_str print_str::@2 + [46] (byte*) print_char_cursor#2 ← phi( print_str/(byte*) print_char_cursor#29 print_str::@2/(byte*) print_char_cursor#1 ) + [46] (byte*) print_str::str#2 ← phi( print_str/(const string) print_points::str print_str::@2/(byte*) print_str::str#0 ) + [47] if(*((byte*) print_str::str#2)!=(byte) '@') goto print_str::@2 + to:print_str::@return +print_str::@return: scope:[print_str] from print_str::@1 + [48] return + to:@return +print_str::@2: scope:[print_str] from print_str::@1 + [49] *((byte*) print_char_cursor#2) ← *((byte*) print_str::str#2) + [50] (byte*) print_char_cursor#1 ← ++ (byte*) print_char_cursor#2 + [51] (byte*) print_str::str#0 ← ++ (byte*) print_str::str#2 + to:print_str::@1 +print_cls: scope:[print_cls] from print_points + [52] phi() + to:print_cls::@1 +print_cls::@1: scope:[print_cls] from print_cls print_cls::@1 + [53] (byte*) print_cls::sc#2 ← phi( print_cls/((byte*))(word/signed word/dword/signed dword) $400 print_cls::@1/(byte*) print_cls::sc#1 ) + [54] *((byte*) print_cls::sc#2) ← (byte) ' ' + [55] (byte*) print_cls::sc#1 ← ++ (byte*) print_cls::sc#2 + [56] if((byte*) print_cls::sc#1!=((byte*))(word/signed word/dword/signed dword) $400+(word/signed word/dword/signed dword) $3e8) goto print_cls::@1 + to:print_cls::@return +print_cls::@return: scope:[print_cls] from print_cls::@1 + [57] return + to:@return +init_points: scope:[init_points] from main + [58] phi() + to:init_points::@1 +init_points::@1: scope:[init_points] from init_points init_points::@3 + [59] (byte) init_points::pos#10 ← phi( init_points/(byte/signed byte/word/signed word/dword/signed dword) $a init_points::@3/(byte) init_points::pos#2 ) + [59] (byte) init_points::i#10 ← phi( init_points/(byte/signed byte/word/signed word/dword/signed dword) 0 init_points::@3/(byte) init_points::i#1 ) + to:init_points::getPoint1 +init_points::getPoint1: scope:[init_points] from init_points::@1 + [60] (byte) init_points::getPoint1_$0#0 ← (byte) init_points::i#10 << (byte/signed byte/word/signed word/dword/signed dword) 1 + [61] (byte*) init_points::pointXpos1_$0#0 ← (const byte[NUM_POINTS#0*SIZEOF_POINT#0]) points#0 + (byte) init_points::getPoint1_$0#0 + to:init_points::pointXpos1 +init_points::pointXpos1: scope:[init_points] from init_points::getPoint1 + [62] phi() + to:init_points::@2 +init_points::@2: scope:[init_points] from init_points::pointXpos1 + [63] *((byte*) init_points::pointXpos1_$0#0) ← (byte) init_points::pos#10 + [64] (byte) init_points::pos#1 ← (byte) init_points::pos#10 + (byte/signed byte/word/signed word/dword/signed dword) $a + to:init_points::pointYpos1 +init_points::pointYpos1: scope:[init_points] from init_points::@2 + [65] (byte*) init_points::pointYpos1_return#0 ← (byte*) init_points::pointXpos1_$0#0 + (byte/signed byte/word/signed word/dword/signed dword) 1 + to:init_points::@3 +init_points::@3: scope:[init_points] from init_points::pointYpos1 + [66] *((byte*) init_points::pointYpos1_return#0) ← (byte) init_points::pos#1 + [67] (byte) init_points::pos#2 ← (byte) init_points::pos#1 + (byte/signed byte/word/signed word/dword/signed dword) $a + [68] (byte) init_points::i#1 ← ++ (byte) init_points::i#10 + [69] if((byte) init_points::i#1!=(const byte) NUM_POINTS#0-(byte/signed byte/word/signed word/dword/signed dword) 1+(byte/signed byte/word/signed word/dword/signed dword) 1) goto init_points::@1 + to:init_points::@return +init_points::@return: scope:[init_points] from init_points::@3 + [70] return + to:@return diff --git a/src/test/ref/semi-struct-1.log b/src/test/ref/semi-struct-1.log new file mode 100644 index 000000000..cf88bd65a --- /dev/null +++ b/src/test/ref/semi-struct-1.log @@ -0,0 +1,2896 @@ +Inlined call (byte*~) init_points::$1 ← call getPoint (byte) init_points::i +Inlined call (byte*~) init_points::$2 ← call pointXpos (byte*) init_points::point +Inlined call (byte*~) init_points::$3 ← call pointYpos (byte*) init_points::point +Inlined call (byte*~) print_points::$2 ← call getPoint (byte) print_points::i +Inlined call (byte*~) print_points::$3 ← call pointXpos (byte*) print_points::point +Inlined call (byte*~) print_points::$6 ← call pointYpos (byte*) print_points::point + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + (byte*) print_screen#0 ← ((byte*)) (word/signed word/dword/signed dword) $400 + (byte*) print_line_cursor#0 ← (byte*) print_screen#0 + (byte*) print_char_cursor#0 ← (byte*) print_line_cursor#0 + to:@12 +print_str: scope:[print_str] from print_points::@7 + (byte*) print_char_cursor#48 ← phi( print_points::@7/(byte*) print_char_cursor#15 ) + (byte*) print_str::str#4 ← phi( print_points::@7/(byte*) print_str::str#1 ) + to:print_str::@1 +print_str::@1: scope:[print_str] from print_str print_str::@2 + (byte*) print_char_cursor#40 ← phi( print_str/(byte*) print_char_cursor#48 print_str::@2/(byte*) print_char_cursor#1 ) + (byte*) print_str::str#2 ← phi( print_str/(byte*) print_str::str#4 print_str::@2/(byte*) print_str::str#0 ) + (bool~) print_str::$0 ← *((byte*) print_str::str#2) != (byte) '@' + if((bool~) print_str::$0) goto print_str::@2 + to:print_str::@return +print_str::@2: scope:[print_str] from print_str::@1 + (byte*) print_char_cursor#21 ← phi( print_str::@1/(byte*) print_char_cursor#40 ) + (byte*) print_str::str#3 ← phi( print_str::@1/(byte*) print_str::str#2 ) + *((byte*) print_char_cursor#21) ← *((byte*) print_str::str#3) + (byte*) print_char_cursor#1 ← ++ (byte*) print_char_cursor#21 + (byte*) print_str::str#0 ← ++ (byte*) print_str::str#3 + to:print_str::@1 +print_str::@return: scope:[print_str] from print_str::@1 + (byte*) print_char_cursor#22 ← phi( print_str::@1/(byte*) print_char_cursor#40 ) + (byte*) print_char_cursor#2 ← (byte*) print_char_cursor#22 + return + to:@return +print_ln: scope:[print_ln] from print_points::@9 + (byte*) print_char_cursor#41 ← phi( print_points::@9/(byte*) print_char_cursor#17 ) + (byte*) print_line_cursor#21 ← phi( print_points::@9/(byte*) print_line_cursor#24 ) + to:print_ln::@1 +print_ln::@1: scope:[print_ln] from print_ln print_ln::@1 + (byte*) print_char_cursor#23 ← phi( print_ln/(byte*) print_char_cursor#41 print_ln::@1/(byte*) print_char_cursor#23 ) + (byte*) print_line_cursor#11 ← phi( print_ln/(byte*) print_line_cursor#21 print_ln::@1/(byte*) print_line_cursor#1 ) + (byte*~) print_ln::$0 ← (byte*) print_line_cursor#11 + (byte/signed byte/word/signed word/dword/signed dword) $28 + (byte*) print_line_cursor#1 ← (byte*~) print_ln::$0 + (bool~) print_ln::$1 ← (byte*) print_line_cursor#1 < (byte*) print_char_cursor#23 + if((bool~) print_ln::$1) goto print_ln::@1 + to:print_ln::@2 +print_ln::@2: scope:[print_ln] from print_ln::@1 + (byte*) print_line_cursor#12 ← phi( print_ln::@1/(byte*) print_line_cursor#1 ) + (byte*) print_char_cursor#3 ← (byte*) print_line_cursor#12 + to:print_ln::@return +print_ln::@return: scope:[print_ln] from print_ln::@2 + (byte*) print_char_cursor#24 ← phi( print_ln::@2/(byte*) print_char_cursor#3 ) + (byte*) print_line_cursor#13 ← phi( print_ln::@2/(byte*) print_line_cursor#12 ) + (byte*) print_line_cursor#2 ← (byte*) print_line_cursor#13 + (byte*) print_char_cursor#4 ← (byte*) print_char_cursor#24 + return + to:@return +@12: scope:[] from @begin + (byte*) print_screen#9 ← phi( @begin/(byte*) print_screen#0 ) + (byte*) print_char_cursor#53 ← phi( @begin/(byte*) print_char_cursor#0 ) + (byte*) print_line_cursor#29 ← phi( @begin/(byte*) print_line_cursor#0 ) + (byte[]) print_hextab#0 ← (const string) $1 + to:@19 +print_byte: scope:[print_byte] from print_points::@4 print_points::@5 + (byte*) print_char_cursor#42 ← phi( print_points::@4/(byte*) print_char_cursor#45 print_points::@5/(byte*) print_char_cursor#46 ) + (byte) print_byte::b#2 ← phi( print_points::@4/(byte) print_byte::b#0 print_points::@5/(byte) print_byte::b#1 ) + (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4 + (byte) print_char::ch#0 ← *((byte[]) print_hextab#0 + (byte~) print_byte::$0) + call print_char + to:print_byte::@1 +print_byte::@1: scope:[print_byte] from print_byte + (byte) print_byte::b#3 ← phi( print_byte/(byte) print_byte::b#2 ) + (byte*) print_char_cursor#25 ← phi( print_byte/(byte*) print_char_cursor#9 ) + (byte*) print_char_cursor#5 ← (byte*) print_char_cursor#25 + (byte~) print_byte::$2 ← (byte) print_byte::b#3 & (byte/signed byte/word/signed word/dword/signed dword) $f + (byte) print_char::ch#1 ← *((byte[]) print_hextab#0 + (byte~) print_byte::$2) + call print_char + to:print_byte::@2 +print_byte::@2: scope:[print_byte] from print_byte::@1 + (byte*) print_char_cursor#26 ← phi( print_byte::@1/(byte*) print_char_cursor#9 ) + (byte*) print_char_cursor#6 ← (byte*) print_char_cursor#26 + to:print_byte::@return +print_byte::@return: scope:[print_byte] from print_byte::@2 + (byte*) print_char_cursor#27 ← phi( print_byte::@2/(byte*) print_char_cursor#6 ) + (byte*) print_char_cursor#7 ← (byte*) print_char_cursor#27 + return + to:@return +print_char: scope:[print_char] from print_byte print_byte::@1 + (byte*) print_char_cursor#28 ← phi( print_byte/(byte*) print_char_cursor#42 print_byte::@1/(byte*) print_char_cursor#5 ) + (byte) print_char::ch#2 ← phi( print_byte/(byte) print_char::ch#0 print_byte::@1/(byte) print_char::ch#1 ) + *((byte*) print_char_cursor#28) ← (byte) print_char::ch#2 + (byte*) print_char_cursor#8 ← ++ (byte*) print_char_cursor#28 + to:print_char::@return +print_char::@return: scope:[print_char] from print_char + (byte*) print_char_cursor#29 ← phi( print_char/(byte*) print_char_cursor#8 ) + (byte*) print_char_cursor#9 ← (byte*) print_char_cursor#29 + return + to:@return +print_cls: scope:[print_cls] from print_points + (byte*) print_screen#1 ← phi( print_points/(byte*) print_screen#4 ) + (byte*) print_cls::sc#0 ← (byte*) print_screen#1 + to:print_cls::@1 +print_cls::@1: scope:[print_cls] from print_cls print_cls::@1 + (byte*) print_screen#2 ← phi( print_cls/(byte*) print_screen#1 print_cls::@1/(byte*) print_screen#2 ) + (byte*) print_cls::sc#2 ← phi( print_cls/(byte*) print_cls::sc#0 print_cls::@1/(byte*) print_cls::sc#1 ) + *((byte*) print_cls::sc#2) ← (byte) ' ' + (byte*) print_cls::sc#1 ← ++ (byte*) print_cls::sc#2 + (byte*~) print_cls::$0 ← (byte*) print_screen#2 + (word/signed word/dword/signed dword) $3e8 + (bool~) print_cls::$1 ← (byte*) print_cls::sc#1 != (byte*~) print_cls::$0 + if((bool~) print_cls::$1) goto print_cls::@1 + to:print_cls::@2 +print_cls::@2: scope:[print_cls] from print_cls::@1 + (byte*) print_screen#3 ← phi( print_cls::@1/(byte*) print_screen#2 ) + (byte*) print_line_cursor#3 ← (byte*) print_screen#3 + (byte*) print_char_cursor#10 ← (byte*) print_line_cursor#3 + to:print_cls::@return +print_cls::@return: scope:[print_cls] from print_cls::@2 + (byte*) print_char_cursor#30 ← phi( print_cls::@2/(byte*) print_char_cursor#10 ) + (byte*) print_line_cursor#14 ← phi( print_cls::@2/(byte*) print_line_cursor#3 ) + (byte*) print_line_cursor#4 ← (byte*) print_line_cursor#14 + (byte*) print_char_cursor#11 ← (byte*) print_char_cursor#30 + return + to:@return +@19: scope:[] from @12 + (byte*) print_screen#8 ← phi( @12/(byte*) print_screen#9 ) + (byte*) print_char_cursor#52 ← phi( @12/(byte*) print_char_cursor#53 ) + (byte*) print_line_cursor#28 ← phi( @12/(byte*) print_line_cursor#29 ) + (byte) SIZEOF_POINT#0 ← (byte/signed byte/word/signed word/dword/signed dword) 2 + (byte) NUM_POINTS#0 ← (byte/signed byte/word/signed word/dword/signed dword) 4 + (byte~) $0 ← (byte) NUM_POINTS#0 * (byte) SIZEOF_POINT#0 + (byte[$0]) points#0 ← { fill( $0, 0) } + to:@25 +main: scope:[main] from @25 + (byte*) print_screen#6 ← phi( @25/(byte*) print_screen#7 ) + (byte*) print_char_cursor#49 ← phi( @25/(byte*) print_char_cursor#47 ) + (byte*) print_line_cursor#26 ← phi( @25/(byte*) print_line_cursor#25 ) + call init_points + to:main::@1 +main::@1: scope:[main] from main + (byte*) print_screen#5 ← phi( main/(byte*) print_screen#6 ) + (byte*) print_char_cursor#43 ← phi( main/(byte*) print_char_cursor#49 ) + (byte*) print_line_cursor#22 ← phi( main/(byte*) print_line_cursor#26 ) + call print_points + to:main::@2 +main::@2: scope:[main] from main::@1 + (byte*) print_char_cursor#31 ← phi( main::@1/(byte*) print_char_cursor#19 ) + (byte*) print_line_cursor#15 ← phi( main::@1/(byte*) print_line_cursor#9 ) + (byte*) print_line_cursor#5 ← (byte*) print_line_cursor#15 + (byte*) print_char_cursor#12 ← (byte*) print_char_cursor#31 + to:main::@return +main::@return: scope:[main] from main::@2 + (byte*) print_char_cursor#32 ← phi( main::@2/(byte*) print_char_cursor#12 ) + (byte*) print_line_cursor#16 ← phi( main::@2/(byte*) print_line_cursor#5 ) + (byte*) print_line_cursor#6 ← (byte*) print_line_cursor#16 + (byte*) print_char_cursor#13 ← (byte*) print_char_cursor#32 + return + to:@return +init_points: scope:[init_points] from main + (byte) init_points::pos#0 ← (byte/signed byte/word/signed word/dword/signed dword) $a + (byte/signed word/word/dword/signed dword~) init_points::$0 ← (byte) NUM_POINTS#0 - (byte/signed byte/word/signed word/dword/signed dword) 1 + (byte) init_points::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 + to:init_points::@1 +init_points::@1: scope:[init_points] from init_points init_points::@5 + (byte) init_points::pos#12 ← phi( init_points/(byte) init_points::pos#0 init_points::@5/(byte) init_points::pos#2 ) + (byte) init_points::i#2 ← phi( init_points/(byte) init_points::i#0 init_points::@5/(byte) init_points::i#1 ) + (byte) init_points::getPoint1_idx#0 ← (byte) init_points::i#2 + to:init_points::getPoint1 +init_points::getPoint1: scope:[init_points] from init_points::@1 + (byte) init_points::i#11 ← phi( init_points::@1/(byte) init_points::i#2 ) + (byte) init_points::pos#11 ← phi( init_points::@1/(byte) init_points::pos#12 ) + (byte) init_points::getPoint1_idx#1 ← phi( init_points::@1/(byte) init_points::getPoint1_idx#0 ) + (byte) init_points::getPoint1_$0#0 ← (byte) init_points::getPoint1_idx#1 * (byte) SIZEOF_POINT#0 + (byte*) init_points::getPoint1_$1#0 ← (byte[$0]) points#0 + (byte) init_points::getPoint1_$0#0 + (byte*) init_points::getPoint1_return#0 ← (byte*) init_points::getPoint1_$1#0 + to:init_points::getPoint1_@return +init_points::getPoint1_@return: scope:[init_points] from init_points::getPoint1 + (byte) init_points::i#10 ← phi( init_points::getPoint1/(byte) init_points::i#11 ) + (byte) init_points::pos#10 ← phi( init_points::getPoint1/(byte) init_points::pos#11 ) + (byte*) init_points::getPoint1_return#2 ← phi( init_points::getPoint1/(byte*) init_points::getPoint1_return#0 ) + (byte*) init_points::getPoint1_return#1 ← (byte*) init_points::getPoint1_return#2 + to:init_points::@3 +init_points::@3: scope:[init_points] from init_points::getPoint1_@return + (byte) init_points::i#9 ← phi( init_points::getPoint1_@return/(byte) init_points::i#10 ) + (byte) init_points::pos#9 ← phi( init_points::getPoint1_@return/(byte) init_points::pos#10 ) + (byte*) init_points::getPoint1_return#3 ← phi( init_points::getPoint1_@return/(byte*) init_points::getPoint1_return#1 ) + (byte*~) init_points::$1 ← (byte*) init_points::getPoint1_return#3 + (byte*) init_points::point#0 ← (byte*~) init_points::$1 + (byte*) init_points::pointXpos1_point#0 ← (byte*) init_points::point#0 + to:init_points::pointXpos1 +init_points::pointXpos1: scope:[init_points] from init_points::@3 + (byte) init_points::i#8 ← phi( init_points::@3/(byte) init_points::i#9 ) + (byte*) init_points::point#3 ← phi( init_points::@3/(byte*) init_points::point#0 ) + (byte) init_points::pos#7 ← phi( init_points::@3/(byte) init_points::pos#9 ) + (byte*) init_points::pointXpos1_point#1 ← phi( init_points::@3/(byte*) init_points::pointXpos1_point#0 ) + (byte*) init_points::pointXpos1_$0#0 ← (byte*) init_points::pointXpos1_point#1 + (byte/signed byte/word/signed word/dword/signed dword) 0 + (byte*) init_points::pointXpos1_$1#0 ← ((byte*)) (byte*) init_points::pointXpos1_$0#0 + (byte*) init_points::pointXpos1_return#0 ← (byte*) init_points::pointXpos1_$1#0 + to:init_points::pointXpos1_@return +init_points::pointXpos1_@return: scope:[init_points] from init_points::pointXpos1 + (byte) init_points::i#7 ← phi( init_points::pointXpos1/(byte) init_points::i#8 ) + (byte*) init_points::point#2 ← phi( init_points::pointXpos1/(byte*) init_points::point#3 ) + (byte) init_points::pos#5 ← phi( init_points::pointXpos1/(byte) init_points::pos#7 ) + (byte*) init_points::pointXpos1_return#2 ← phi( init_points::pointXpos1/(byte*) init_points::pointXpos1_return#0 ) + (byte*) init_points::pointXpos1_return#1 ← (byte*) init_points::pointXpos1_return#2 + to:init_points::@4 +init_points::@4: scope:[init_points] from init_points::pointXpos1_@return + (byte) init_points::i#6 ← phi( init_points::pointXpos1_@return/(byte) init_points::i#7 ) + (byte*) init_points::point#1 ← phi( init_points::pointXpos1_@return/(byte*) init_points::point#2 ) + (byte) init_points::pos#3 ← phi( init_points::pointXpos1_@return/(byte) init_points::pos#5 ) + (byte*) init_points::pointXpos1_return#3 ← phi( init_points::pointXpos1_@return/(byte*) init_points::pointXpos1_return#1 ) + (byte*~) init_points::$2 ← (byte*) init_points::pointXpos1_return#3 + *((byte*~) init_points::$2) ← (byte) init_points::pos#3 + (byte) init_points::pos#1 ← (byte) init_points::pos#3 + (byte/signed byte/word/signed word/dword/signed dword) $a + (byte*) init_points::pointYpos1_point#0 ← (byte*) init_points::point#1 + to:init_points::pointYpos1 +init_points::pointYpos1: scope:[init_points] from init_points::@4 + (byte) init_points::i#5 ← phi( init_points::@4/(byte) init_points::i#6 ) + (byte) init_points::pos#8 ← phi( init_points::@4/(byte) init_points::pos#1 ) + (byte*) init_points::pointYpos1_point#1 ← phi( init_points::@4/(byte*) init_points::pointYpos1_point#0 ) + (byte*) init_points::pointYpos1_$0#0 ← (byte*) init_points::pointYpos1_point#1 + (byte/signed byte/word/signed word/dword/signed dword) 1 + (byte*) init_points::pointYpos1_$1#0 ← ((byte*)) (byte*) init_points::pointYpos1_$0#0 + (byte*) init_points::pointYpos1_return#0 ← (byte*) init_points::pointYpos1_$1#0 + to:init_points::pointYpos1_@return +init_points::pointYpos1_@return: scope:[init_points] from init_points::pointYpos1 + (byte) init_points::i#4 ← phi( init_points::pointYpos1/(byte) init_points::i#5 ) + (byte) init_points::pos#6 ← phi( init_points::pointYpos1/(byte) init_points::pos#8 ) + (byte*) init_points::pointYpos1_return#2 ← phi( init_points::pointYpos1/(byte*) init_points::pointYpos1_return#0 ) + (byte*) init_points::pointYpos1_return#1 ← (byte*) init_points::pointYpos1_return#2 + to:init_points::@5 +init_points::@5: scope:[init_points] from init_points::pointYpos1_@return + (byte) init_points::i#3 ← phi( init_points::pointYpos1_@return/(byte) init_points::i#4 ) + (byte) init_points::pos#4 ← phi( init_points::pointYpos1_@return/(byte) init_points::pos#6 ) + (byte*) init_points::pointYpos1_return#3 ← phi( init_points::pointYpos1_@return/(byte*) init_points::pointYpos1_return#1 ) + (byte*~) init_points::$3 ← (byte*) init_points::pointYpos1_return#3 + *((byte*~) init_points::$3) ← (byte) init_points::pos#4 + (byte) init_points::pos#2 ← (byte) init_points::pos#4 + (byte/signed byte/word/signed word/dword/signed dword) $a + (byte) init_points::i#1 ← (byte) init_points::i#3 + rangenext(0,init_points::$0) + (bool~) init_points::$4 ← (byte) init_points::i#1 != rangelast(0,init_points::$0) + if((bool~) init_points::$4) goto init_points::@1 + to:init_points::@return +init_points::@return: scope:[init_points] from init_points::@5 + return + to:@return +print_points: scope:[print_points] from main::@1 + (byte*) print_char_cursor#44 ← phi( main::@1/(byte*) print_char_cursor#43 ) + (byte*) print_line_cursor#23 ← phi( main::@1/(byte*) print_line_cursor#22 ) + (byte*) print_screen#4 ← phi( main::@1/(byte*) print_screen#5 ) + call print_cls + to:print_points::@6 +print_points::@6: scope:[print_points] from print_points + (byte*) print_char_cursor#33 ← phi( print_points/(byte*) print_char_cursor#11 ) + (byte*) print_line_cursor#17 ← phi( print_points/(byte*) print_line_cursor#4 ) + (byte*) print_line_cursor#7 ← (byte*) print_line_cursor#17 + (byte*) print_char_cursor#14 ← (byte*) print_char_cursor#33 + (byte/signed word/word/dword/signed dword~) print_points::$1 ← (byte) NUM_POINTS#0 - (byte/signed byte/word/signed word/dword/signed dword) 1 + (byte) print_points::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 + to:print_points::@1 +print_points::@1: scope:[print_points] from print_points::@10 print_points::@6 + (byte*) print_line_cursor#40 ← phi( print_points::@10/(byte*) print_line_cursor#8 print_points::@6/(byte*) print_line_cursor#7 ) + (byte*) print_char_cursor#59 ← phi( print_points::@10/(byte*) print_char_cursor#18 print_points::@6/(byte*) print_char_cursor#14 ) + (byte) print_points::i#2 ← phi( print_points::@10/(byte) print_points::i#1 print_points::@6/(byte) print_points::i#0 ) + (byte) print_points::getPoint1_idx#0 ← (byte) print_points::i#2 + to:print_points::getPoint1 +print_points::getPoint1: scope:[print_points] from print_points::@1 + (byte) print_points::i#15 ← phi( print_points::@1/(byte) print_points::i#2 ) + (byte*) print_line_cursor#39 ← phi( print_points::@1/(byte*) print_line_cursor#40 ) + (byte*) print_char_cursor#58 ← phi( print_points::@1/(byte*) print_char_cursor#59 ) + (byte) print_points::getPoint1_idx#1 ← phi( print_points::@1/(byte) print_points::getPoint1_idx#0 ) + (byte) print_points::getPoint1_$0#0 ← (byte) print_points::getPoint1_idx#1 * (byte) SIZEOF_POINT#0 + (byte*) print_points::getPoint1_$1#0 ← (byte[$0]) points#0 + (byte) print_points::getPoint1_$0#0 + (byte*) print_points::getPoint1_return#0 ← (byte*) print_points::getPoint1_$1#0 + to:print_points::getPoint1_@return +print_points::getPoint1_@return: scope:[print_points] from print_points::getPoint1 + (byte) print_points::i#14 ← phi( print_points::getPoint1/(byte) print_points::i#15 ) + (byte*) print_line_cursor#38 ← phi( print_points::getPoint1/(byte*) print_line_cursor#39 ) + (byte*) print_char_cursor#57 ← phi( print_points::getPoint1/(byte*) print_char_cursor#58 ) + (byte*) print_points::getPoint1_return#2 ← phi( print_points::getPoint1/(byte*) print_points::getPoint1_return#0 ) + (byte*) print_points::getPoint1_return#1 ← (byte*) print_points::getPoint1_return#2 + to:print_points::@3 +print_points::@3: scope:[print_points] from print_points::getPoint1_@return + (byte) print_points::i#13 ← phi( print_points::getPoint1_@return/(byte) print_points::i#14 ) + (byte*) print_line_cursor#37 ← phi( print_points::getPoint1_@return/(byte*) print_line_cursor#38 ) + (byte*) print_char_cursor#56 ← phi( print_points::getPoint1_@return/(byte*) print_char_cursor#57 ) + (byte*) print_points::getPoint1_return#3 ← phi( print_points::getPoint1_@return/(byte*) print_points::getPoint1_return#1 ) + (byte*~) print_points::$2 ← (byte*) print_points::getPoint1_return#3 + (byte*) print_points::point#0 ← (byte*~) print_points::$2 + (byte*) print_points::pointXpos1_point#0 ← (byte*) print_points::point#0 + to:print_points::pointXpos1 +print_points::pointXpos1: scope:[print_points] from print_points::@3 + (byte) print_points::i#12 ← phi( print_points::@3/(byte) print_points::i#13 ) + (byte*) print_line_cursor#36 ← phi( print_points::@3/(byte*) print_line_cursor#37 ) + (byte*) print_points::point#5 ← phi( print_points::@3/(byte*) print_points::point#0 ) + (byte*) print_char_cursor#54 ← phi( print_points::@3/(byte*) print_char_cursor#56 ) + (byte*) print_points::pointXpos1_point#1 ← phi( print_points::@3/(byte*) print_points::pointXpos1_point#0 ) + (byte*) print_points::pointXpos1_$0#0 ← (byte*) print_points::pointXpos1_point#1 + (byte/signed byte/word/signed word/dword/signed dword) 0 + (byte*) print_points::pointXpos1_$1#0 ← ((byte*)) (byte*) print_points::pointXpos1_$0#0 + (byte*) print_points::pointXpos1_return#0 ← (byte*) print_points::pointXpos1_$1#0 + to:print_points::pointXpos1_@return +print_points::pointXpos1_@return: scope:[print_points] from print_points::pointXpos1 + (byte) print_points::i#11 ← phi( print_points::pointXpos1/(byte) print_points::i#12 ) + (byte*) print_line_cursor#35 ← phi( print_points::pointXpos1/(byte*) print_line_cursor#36 ) + (byte*) print_points::point#4 ← phi( print_points::pointXpos1/(byte*) print_points::point#5 ) + (byte*) print_char_cursor#50 ← phi( print_points::pointXpos1/(byte*) print_char_cursor#54 ) + (byte*) print_points::pointXpos1_return#2 ← phi( print_points::pointXpos1/(byte*) print_points::pointXpos1_return#0 ) + (byte*) print_points::pointXpos1_return#1 ← (byte*) print_points::pointXpos1_return#2 + to:print_points::@4 +print_points::@4: scope:[print_points] from print_points::pointXpos1_@return + (byte) print_points::i#10 ← phi( print_points::pointXpos1_@return/(byte) print_points::i#11 ) + (byte*) print_line_cursor#34 ← phi( print_points::pointXpos1_@return/(byte*) print_line_cursor#35 ) + (byte*) print_points::point#3 ← phi( print_points::pointXpos1_@return/(byte*) print_points::point#4 ) + (byte*) print_char_cursor#45 ← phi( print_points::pointXpos1_@return/(byte*) print_char_cursor#50 ) + (byte*) print_points::pointXpos1_return#3 ← phi( print_points::pointXpos1_@return/(byte*) print_points::pointXpos1_return#1 ) + (byte*~) print_points::$3 ← (byte*) print_points::pointXpos1_return#3 + (byte) print_byte::b#0 ← *((byte*~) print_points::$3) + call print_byte + to:print_points::@7 +print_points::@7: scope:[print_points] from print_points::@4 + (byte) print_points::i#9 ← phi( print_points::@4/(byte) print_points::i#10 ) + (byte*) print_line_cursor#33 ← phi( print_points::@4/(byte*) print_line_cursor#34 ) + (byte*) print_points::point#2 ← phi( print_points::@4/(byte*) print_points::point#3 ) + (byte*) print_char_cursor#34 ← phi( print_points::@4/(byte*) print_char_cursor#7 ) + (byte*) print_char_cursor#15 ← (byte*) print_char_cursor#34 + (byte*) print_str::str#1 ← (const string) print_points::str + call print_str + to:print_points::@8 +print_points::@8: scope:[print_points] from print_points::@7 + (byte) print_points::i#8 ← phi( print_points::@7/(byte) print_points::i#9 ) + (byte*) print_line_cursor#32 ← phi( print_points::@7/(byte*) print_line_cursor#33 ) + (byte*) print_points::point#1 ← phi( print_points::@7/(byte*) print_points::point#2 ) + (byte*) print_char_cursor#35 ← phi( print_points::@7/(byte*) print_char_cursor#2 ) + (byte*) print_char_cursor#16 ← (byte*) print_char_cursor#35 + (byte*) print_points::pointYpos1_point#0 ← (byte*) print_points::point#1 + to:print_points::pointYpos1 +print_points::pointYpos1: scope:[print_points] from print_points::@8 + (byte) print_points::i#7 ← phi( print_points::@8/(byte) print_points::i#8 ) + (byte*) print_line_cursor#31 ← phi( print_points::@8/(byte*) print_line_cursor#32 ) + (byte*) print_char_cursor#55 ← phi( print_points::@8/(byte*) print_char_cursor#16 ) + (byte*) print_points::pointYpos1_point#1 ← phi( print_points::@8/(byte*) print_points::pointYpos1_point#0 ) + (byte*) print_points::pointYpos1_$0#0 ← (byte*) print_points::pointYpos1_point#1 + (byte/signed byte/word/signed word/dword/signed dword) 1 + (byte*) print_points::pointYpos1_$1#0 ← ((byte*)) (byte*) print_points::pointYpos1_$0#0 + (byte*) print_points::pointYpos1_return#0 ← (byte*) print_points::pointYpos1_$1#0 + to:print_points::pointYpos1_@return +print_points::pointYpos1_@return: scope:[print_points] from print_points::pointYpos1 + (byte) print_points::i#6 ← phi( print_points::pointYpos1/(byte) print_points::i#7 ) + (byte*) print_line_cursor#30 ← phi( print_points::pointYpos1/(byte*) print_line_cursor#31 ) + (byte*) print_char_cursor#51 ← phi( print_points::pointYpos1/(byte*) print_char_cursor#55 ) + (byte*) print_points::pointYpos1_return#2 ← phi( print_points::pointYpos1/(byte*) print_points::pointYpos1_return#0 ) + (byte*) print_points::pointYpos1_return#1 ← (byte*) print_points::pointYpos1_return#2 + to:print_points::@5 +print_points::@5: scope:[print_points] from print_points::pointYpos1_@return + (byte) print_points::i#5 ← phi( print_points::pointYpos1_@return/(byte) print_points::i#6 ) + (byte*) print_line_cursor#27 ← phi( print_points::pointYpos1_@return/(byte*) print_line_cursor#30 ) + (byte*) print_char_cursor#46 ← phi( print_points::pointYpos1_@return/(byte*) print_char_cursor#51 ) + (byte*) print_points::pointYpos1_return#3 ← phi( print_points::pointYpos1_@return/(byte*) print_points::pointYpos1_return#1 ) + (byte*~) print_points::$6 ← (byte*) print_points::pointYpos1_return#3 + (byte) print_byte::b#1 ← *((byte*~) print_points::$6) + call print_byte + to:print_points::@9 +print_points::@9: scope:[print_points] from print_points::@5 + (byte) print_points::i#4 ← phi( print_points::@5/(byte) print_points::i#5 ) + (byte*) print_line_cursor#24 ← phi( print_points::@5/(byte*) print_line_cursor#27 ) + (byte*) print_char_cursor#36 ← phi( print_points::@5/(byte*) print_char_cursor#7 ) + (byte*) print_char_cursor#17 ← (byte*) print_char_cursor#36 + call print_ln + to:print_points::@10 +print_points::@10: scope:[print_points] from print_points::@9 + (byte) print_points::i#3 ← phi( print_points::@9/(byte) print_points::i#4 ) + (byte*) print_char_cursor#37 ← phi( print_points::@9/(byte*) print_char_cursor#4 ) + (byte*) print_line_cursor#18 ← phi( print_points::@9/(byte*) print_line_cursor#2 ) + (byte*) print_line_cursor#8 ← (byte*) print_line_cursor#18 + (byte*) print_char_cursor#18 ← (byte*) print_char_cursor#37 + (byte) print_points::i#1 ← (byte) print_points::i#3 + rangenext(0,print_points::$1) + (bool~) print_points::$9 ← (byte) print_points::i#1 != rangelast(0,print_points::$1) + if((bool~) print_points::$9) goto print_points::@1 + to:print_points::@return +print_points::@return: scope:[print_points] from print_points::@10 + (byte*) print_char_cursor#38 ← phi( print_points::@10/(byte*) print_char_cursor#18 ) + (byte*) print_line_cursor#19 ← phi( print_points::@10/(byte*) print_line_cursor#8 ) + (byte*) print_line_cursor#9 ← (byte*) print_line_cursor#19 + (byte*) print_char_cursor#19 ← (byte*) print_char_cursor#38 + return + to:@return +@25: scope:[] from @19 + (byte*) print_screen#7 ← phi( @19/(byte*) print_screen#8 ) + (byte*) print_char_cursor#47 ← phi( @19/(byte*) print_char_cursor#52 ) + (byte*) print_line_cursor#25 ← phi( @19/(byte*) print_line_cursor#28 ) + call main + to:@26 +@26: scope:[] from @25 + (byte*) print_char_cursor#39 ← phi( @25/(byte*) print_char_cursor#13 ) + (byte*) print_line_cursor#20 ← phi( @25/(byte*) print_line_cursor#6 ) + (byte*) print_line_cursor#10 ← (byte*) print_line_cursor#20 + (byte*) print_char_cursor#20 ← (byte*) print_char_cursor#39 + to:@end +@end: scope:[] from @26 + +SYMBOL TABLE SSA +(byte~) $0 +(const string) $1 = (string) "0123456789abcdef" +(label) @12 +(label) @19 +(label) @25 +(label) @26 +(label) @begin +(label) @end +(byte) NUM_POINTS +(byte) NUM_POINTS#0 +(byte) SIZEOF_POINT +(byte) SIZEOF_POINT#0 +(void()) init_points() +(byte/signed word/word/dword/signed dword~) init_points::$0 +(byte*~) init_points::$1 +(byte*~) init_points::$2 +(byte*~) init_points::$3 +(bool~) init_points::$4 +(label) init_points::@1 +(label) init_points::@3 +(label) init_points::@4 +(label) init_points::@5 +(label) init_points::@return +(label) init_points::getPoint1 +(byte~) init_points::getPoint1_$0 +(byte) init_points::getPoint1_$0#0 +(byte*~) init_points::getPoint1_$1 +(byte*) init_points::getPoint1_$1#0 +(label) init_points::getPoint1_@return +(byte) init_points::getPoint1_idx +(byte) init_points::getPoint1_idx#0 +(byte) init_points::getPoint1_idx#1 +(byte*) init_points::getPoint1_return +(byte*) init_points::getPoint1_return#0 +(byte*) init_points::getPoint1_return#1 +(byte*) init_points::getPoint1_return#2 +(byte*) init_points::getPoint1_return#3 +(byte) init_points::i +(byte) init_points::i#0 +(byte) init_points::i#1 +(byte) init_points::i#10 +(byte) init_points::i#11 +(byte) init_points::i#2 +(byte) init_points::i#3 +(byte) init_points::i#4 +(byte) init_points::i#5 +(byte) init_points::i#6 +(byte) init_points::i#7 +(byte) init_points::i#8 +(byte) init_points::i#9 +(byte*) init_points::point +(byte*) init_points::point#0 +(byte*) init_points::point#1 +(byte*) init_points::point#2 +(byte*) init_points::point#3 +(label) init_points::pointXpos1 +(byte*~) init_points::pointXpos1_$0 +(byte*) init_points::pointXpos1_$0#0 +(byte*~) init_points::pointXpos1_$1 +(byte*) init_points::pointXpos1_$1#0 +(label) init_points::pointXpos1_@return +(byte*) init_points::pointXpos1_point +(byte*) init_points::pointXpos1_point#0 +(byte*) init_points::pointXpos1_point#1 +(byte*) init_points::pointXpos1_return +(byte*) init_points::pointXpos1_return#0 +(byte*) init_points::pointXpos1_return#1 +(byte*) init_points::pointXpos1_return#2 +(byte*) init_points::pointXpos1_return#3 +(label) init_points::pointYpos1 +(byte*~) init_points::pointYpos1_$0 +(byte*) init_points::pointYpos1_$0#0 +(byte*~) init_points::pointYpos1_$1 +(byte*) init_points::pointYpos1_$1#0 +(label) init_points::pointYpos1_@return +(byte*) init_points::pointYpos1_point +(byte*) init_points::pointYpos1_point#0 +(byte*) init_points::pointYpos1_point#1 +(byte*) init_points::pointYpos1_return +(byte*) init_points::pointYpos1_return#0 +(byte*) init_points::pointYpos1_return#1 +(byte*) init_points::pointYpos1_return#2 +(byte*) init_points::pointYpos1_return#3 +(byte) init_points::pos +(byte) init_points::pos#0 +(byte) init_points::pos#1 +(byte) init_points::pos#10 +(byte) init_points::pos#11 +(byte) init_points::pos#12 +(byte) init_points::pos#2 +(byte) init_points::pos#3 +(byte) init_points::pos#4 +(byte) init_points::pos#5 +(byte) init_points::pos#6 +(byte) init_points::pos#7 +(byte) init_points::pos#8 +(byte) init_points::pos#9 +(void()) main() +(label) main::@1 +(label) main::@2 +(label) main::@return +(byte[$0]) points +(byte[$0]) points#0 +(void()) print_byte((byte) print_byte::b) +(byte~) print_byte::$0 +(byte~) print_byte::$2 +(label) print_byte::@1 +(label) print_byte::@2 +(label) print_byte::@return +(byte) print_byte::b +(byte) print_byte::b#0 +(byte) print_byte::b#1 +(byte) print_byte::b#2 +(byte) print_byte::b#3 +(void()) print_char((byte) print_char::ch) +(label) print_char::@return +(byte) print_char::ch +(byte) print_char::ch#0 +(byte) print_char::ch#1 +(byte) print_char::ch#2 +(byte*) print_char_cursor +(byte*) print_char_cursor#0 +(byte*) print_char_cursor#1 +(byte*) print_char_cursor#10 +(byte*) print_char_cursor#11 +(byte*) print_char_cursor#12 +(byte*) print_char_cursor#13 +(byte*) print_char_cursor#14 +(byte*) print_char_cursor#15 +(byte*) print_char_cursor#16 +(byte*) print_char_cursor#17 +(byte*) print_char_cursor#18 +(byte*) print_char_cursor#19 +(byte*) print_char_cursor#2 +(byte*) print_char_cursor#20 +(byte*) print_char_cursor#21 +(byte*) print_char_cursor#22 +(byte*) print_char_cursor#23 +(byte*) print_char_cursor#24 +(byte*) print_char_cursor#25 +(byte*) print_char_cursor#26 +(byte*) print_char_cursor#27 +(byte*) print_char_cursor#28 +(byte*) print_char_cursor#29 +(byte*) print_char_cursor#3 +(byte*) print_char_cursor#30 +(byte*) print_char_cursor#31 +(byte*) print_char_cursor#32 +(byte*) print_char_cursor#33 +(byte*) print_char_cursor#34 +(byte*) print_char_cursor#35 +(byte*) print_char_cursor#36 +(byte*) print_char_cursor#37 +(byte*) print_char_cursor#38 +(byte*) print_char_cursor#39 +(byte*) print_char_cursor#4 +(byte*) print_char_cursor#40 +(byte*) print_char_cursor#41 +(byte*) print_char_cursor#42 +(byte*) print_char_cursor#43 +(byte*) print_char_cursor#44 +(byte*) print_char_cursor#45 +(byte*) print_char_cursor#46 +(byte*) print_char_cursor#47 +(byte*) print_char_cursor#48 +(byte*) print_char_cursor#49 +(byte*) print_char_cursor#5 +(byte*) print_char_cursor#50 +(byte*) print_char_cursor#51 +(byte*) print_char_cursor#52 +(byte*) print_char_cursor#53 +(byte*) print_char_cursor#54 +(byte*) print_char_cursor#55 +(byte*) print_char_cursor#56 +(byte*) print_char_cursor#57 +(byte*) print_char_cursor#58 +(byte*) print_char_cursor#59 +(byte*) print_char_cursor#6 +(byte*) print_char_cursor#7 +(byte*) print_char_cursor#8 +(byte*) print_char_cursor#9 +(void()) print_cls() +(byte*~) print_cls::$0 +(bool~) print_cls::$1 +(label) print_cls::@1 +(label) print_cls::@2 +(label) print_cls::@return +(byte*) print_cls::sc +(byte*) print_cls::sc#0 +(byte*) print_cls::sc#1 +(byte*) print_cls::sc#2 +(byte[]) print_hextab +(byte[]) print_hextab#0 +(byte*) print_line_cursor +(byte*) print_line_cursor#0 +(byte*) print_line_cursor#1 +(byte*) print_line_cursor#10 +(byte*) print_line_cursor#11 +(byte*) print_line_cursor#12 +(byte*) print_line_cursor#13 +(byte*) print_line_cursor#14 +(byte*) print_line_cursor#15 +(byte*) print_line_cursor#16 +(byte*) print_line_cursor#17 +(byte*) print_line_cursor#18 +(byte*) print_line_cursor#19 +(byte*) print_line_cursor#2 +(byte*) print_line_cursor#20 +(byte*) print_line_cursor#21 +(byte*) print_line_cursor#22 +(byte*) print_line_cursor#23 +(byte*) print_line_cursor#24 +(byte*) print_line_cursor#25 +(byte*) print_line_cursor#26 +(byte*) print_line_cursor#27 +(byte*) print_line_cursor#28 +(byte*) print_line_cursor#29 +(byte*) print_line_cursor#3 +(byte*) print_line_cursor#30 +(byte*) print_line_cursor#31 +(byte*) print_line_cursor#32 +(byte*) print_line_cursor#33 +(byte*) print_line_cursor#34 +(byte*) print_line_cursor#35 +(byte*) print_line_cursor#36 +(byte*) print_line_cursor#37 +(byte*) print_line_cursor#38 +(byte*) print_line_cursor#39 +(byte*) print_line_cursor#4 +(byte*) print_line_cursor#40 +(byte*) print_line_cursor#5 +(byte*) print_line_cursor#6 +(byte*) print_line_cursor#7 +(byte*) print_line_cursor#8 +(byte*) print_line_cursor#9 +(void()) print_ln() +(byte*~) print_ln::$0 +(bool~) print_ln::$1 +(label) print_ln::@1 +(label) print_ln::@2 +(label) print_ln::@return +(void()) print_points() +(byte/signed word/word/dword/signed dword~) print_points::$1 +(byte*~) print_points::$2 +(byte*~) print_points::$3 +(byte*~) print_points::$6 +(bool~) print_points::$9 +(label) print_points::@1 +(label) print_points::@10 +(label) print_points::@3 +(label) print_points::@4 +(label) print_points::@5 +(label) print_points::@6 +(label) print_points::@7 +(label) print_points::@8 +(label) print_points::@9 +(label) print_points::@return +(label) print_points::getPoint1 +(byte~) print_points::getPoint1_$0 +(byte) print_points::getPoint1_$0#0 +(byte*~) print_points::getPoint1_$1 +(byte*) print_points::getPoint1_$1#0 +(label) print_points::getPoint1_@return +(byte) print_points::getPoint1_idx +(byte) print_points::getPoint1_idx#0 +(byte) print_points::getPoint1_idx#1 +(byte*) print_points::getPoint1_return +(byte*) print_points::getPoint1_return#0 +(byte*) print_points::getPoint1_return#1 +(byte*) print_points::getPoint1_return#2 +(byte*) print_points::getPoint1_return#3 +(byte) print_points::i +(byte) print_points::i#0 +(byte) print_points::i#1 +(byte) print_points::i#10 +(byte) print_points::i#11 +(byte) print_points::i#12 +(byte) print_points::i#13 +(byte) print_points::i#14 +(byte) print_points::i#15 +(byte) print_points::i#2 +(byte) print_points::i#3 +(byte) print_points::i#4 +(byte) print_points::i#5 +(byte) print_points::i#6 +(byte) print_points::i#7 +(byte) print_points::i#8 +(byte) print_points::i#9 +(byte*) print_points::point +(byte*) print_points::point#0 +(byte*) print_points::point#1 +(byte*) print_points::point#2 +(byte*) print_points::point#3 +(byte*) print_points::point#4 +(byte*) print_points::point#5 +(label) print_points::pointXpos1 +(byte*~) print_points::pointXpos1_$0 +(byte*) print_points::pointXpos1_$0#0 +(byte*~) print_points::pointXpos1_$1 +(byte*) print_points::pointXpos1_$1#0 +(label) print_points::pointXpos1_@return +(byte*) print_points::pointXpos1_point +(byte*) print_points::pointXpos1_point#0 +(byte*) print_points::pointXpos1_point#1 +(byte*) print_points::pointXpos1_return +(byte*) print_points::pointXpos1_return#0 +(byte*) print_points::pointXpos1_return#1 +(byte*) print_points::pointXpos1_return#2 +(byte*) print_points::pointXpos1_return#3 +(label) print_points::pointYpos1 +(byte*~) print_points::pointYpos1_$0 +(byte*) print_points::pointYpos1_$0#0 +(byte*~) print_points::pointYpos1_$1 +(byte*) print_points::pointYpos1_$1#0 +(label) print_points::pointYpos1_@return +(byte*) print_points::pointYpos1_point +(byte*) print_points::pointYpos1_point#0 +(byte*) print_points::pointYpos1_point#1 +(byte*) print_points::pointYpos1_return +(byte*) print_points::pointYpos1_return#0 +(byte*) print_points::pointYpos1_return#1 +(byte*) print_points::pointYpos1_return#2 +(byte*) print_points::pointYpos1_return#3 +(const string) print_points::str = (string) " @" +(byte*) print_screen +(byte*) print_screen#0 +(byte*) print_screen#1 +(byte*) print_screen#2 +(byte*) print_screen#3 +(byte*) print_screen#4 +(byte*) print_screen#5 +(byte*) print_screen#6 +(byte*) print_screen#7 +(byte*) print_screen#8 +(byte*) print_screen#9 +(void()) print_str((byte*) print_str::str) +(bool~) print_str::$0 +(label) print_str::@1 +(label) print_str::@2 +(label) print_str::@return +(byte*) print_str::str +(byte*) print_str::str#0 +(byte*) print_str::str#1 +(byte*) print_str::str#2 +(byte*) print_str::str#3 +(byte*) print_str::str#4 + +Alias (byte*) print_line_cursor#0 = (byte*) print_screen#0 (byte*) print_char_cursor#0 (byte*) print_line_cursor#29 (byte*) print_char_cursor#53 (byte*) print_screen#9 (byte*) print_line_cursor#28 (byte*) print_char_cursor#52 (byte*) print_screen#8 (byte*) print_line_cursor#25 (byte*) print_char_cursor#47 (byte*) print_screen#7 +Alias (byte*) print_str::str#2 = (byte*) print_str::str#3 +Alias (byte*) print_char_cursor#2 = (byte*) print_char_cursor#21 (byte*) print_char_cursor#40 (byte*) print_char_cursor#22 +Alias (byte*) print_line_cursor#1 = (byte*~) print_ln::$0 (byte*) print_line_cursor#12 (byte*) print_char_cursor#3 (byte*) print_line_cursor#13 (byte*) print_char_cursor#24 (byte*) print_line_cursor#2 (byte*) print_char_cursor#4 +Alias (byte) print_byte::b#2 = (byte) print_byte::b#3 +Alias (byte*) print_char_cursor#25 = (byte*) print_char_cursor#5 +Alias (byte*) print_char_cursor#26 = (byte*) print_char_cursor#6 (byte*) print_char_cursor#27 (byte*) print_char_cursor#7 +Alias (byte*) print_char_cursor#29 = (byte*) print_char_cursor#8 (byte*) print_char_cursor#9 +Alias (byte*) print_line_cursor#14 = (byte*) print_screen#3 (byte*) print_screen#2 (byte*) print_line_cursor#3 (byte*) print_char_cursor#10 (byte*) print_char_cursor#30 (byte*) print_line_cursor#4 (byte*) print_char_cursor#11 +Alias (byte*) print_line_cursor#22 = (byte*) print_line_cursor#26 +Alias (byte*) print_char_cursor#43 = (byte*) print_char_cursor#49 +Alias (byte*) print_screen#5 = (byte*) print_screen#6 +Alias (byte*) print_line_cursor#15 = (byte*) print_line_cursor#5 (byte*) print_line_cursor#16 (byte*) print_line_cursor#6 +Alias (byte*) print_char_cursor#12 = (byte*) print_char_cursor#31 (byte*) print_char_cursor#32 (byte*) print_char_cursor#13 +Alias (byte) init_points::i#10 = (byte) init_points::getPoint1_idx#0 (byte) init_points::i#2 (byte) init_points::getPoint1_idx#1 (byte) init_points::i#11 (byte) init_points::i#9 (byte) init_points::i#8 (byte) init_points::i#7 (byte) init_points::i#6 (byte) init_points::i#5 (byte) init_points::i#4 (byte) init_points::i#3 +Alias (byte) init_points::pos#10 = (byte) init_points::pos#11 (byte) init_points::pos#12 (byte) init_points::pos#9 (byte) init_points::pos#7 (byte) init_points::pos#5 (byte) init_points::pos#3 +Alias (byte*) init_points::getPoint1_return#0 = (byte*) init_points::getPoint1_$1#0 (byte*) init_points::getPoint1_return#2 (byte*) init_points::getPoint1_return#1 (byte*) init_points::getPoint1_return#3 (byte*~) init_points::$1 (byte*) init_points::point#0 (byte*) init_points::pointXpos1_point#0 (byte*) init_points::pointXpos1_point#1 (byte*) init_points::point#3 (byte*) init_points::point#2 (byte*) init_points::point#1 (byte*) init_points::pointYpos1_point#0 (byte*) init_points::pointYpos1_point#1 +Alias (byte*) init_points::pointXpos1_return#0 = (byte*) init_points::pointXpos1_$1#0 (byte*) init_points::pointXpos1_return#2 (byte*) init_points::pointXpos1_return#1 (byte*) init_points::pointXpos1_return#3 (byte*~) init_points::$2 +Alias (byte) init_points::pos#1 = (byte) init_points::pos#8 (byte) init_points::pos#6 (byte) init_points::pos#4 +Alias (byte*) init_points::pointYpos1_return#0 = (byte*) init_points::pointYpos1_$1#0 (byte*) init_points::pointYpos1_return#2 (byte*) init_points::pointYpos1_return#1 (byte*) init_points::pointYpos1_return#3 (byte*~) init_points::$3 +Alias (byte*) print_line_cursor#17 = (byte*) print_line_cursor#7 +Alias (byte*) print_char_cursor#14 = (byte*) print_char_cursor#33 +Alias (byte) print_points::i#10 = (byte) print_points::getPoint1_idx#0 (byte) print_points::i#2 (byte) print_points::getPoint1_idx#1 (byte) print_points::i#15 (byte) print_points::i#14 (byte) print_points::i#13 (byte) print_points::i#12 (byte) print_points::i#11 (byte) print_points::i#9 (byte) print_points::i#8 (byte) print_points::i#7 (byte) print_points::i#6 (byte) print_points::i#5 (byte) print_points::i#4 (byte) print_points::i#3 +Alias (byte*) print_char_cursor#45 = (byte*) print_char_cursor#58 (byte*) print_char_cursor#59 (byte*) print_char_cursor#57 (byte*) print_char_cursor#56 (byte*) print_char_cursor#54 (byte*) print_char_cursor#50 +Alias (byte*) print_line_cursor#24 = (byte*) print_line_cursor#39 (byte*) print_line_cursor#40 (byte*) print_line_cursor#38 (byte*) print_line_cursor#37 (byte*) print_line_cursor#36 (byte*) print_line_cursor#35 (byte*) print_line_cursor#34 (byte*) print_line_cursor#33 (byte*) print_line_cursor#32 (byte*) print_line_cursor#31 (byte*) print_line_cursor#30 (byte*) print_line_cursor#27 +Alias (byte*) print_points::point#0 = (byte*) print_points::getPoint1_return#0 (byte*) print_points::getPoint1_$1#0 (byte*) print_points::getPoint1_return#2 (byte*) print_points::getPoint1_return#1 (byte*) print_points::getPoint1_return#3 (byte*~) print_points::$2 (byte*) print_points::pointXpos1_point#0 (byte*) print_points::pointXpos1_point#1 (byte*) print_points::point#5 (byte*) print_points::point#4 (byte*) print_points::point#3 (byte*) print_points::point#2 (byte*) print_points::point#1 (byte*) print_points::pointYpos1_point#0 (byte*) print_points::pointYpos1_point#1 +Alias (byte*) print_points::pointXpos1_return#0 = (byte*) print_points::pointXpos1_$1#0 (byte*) print_points::pointXpos1_return#2 (byte*) print_points::pointXpos1_return#1 (byte*) print_points::pointXpos1_return#3 (byte*~) print_points::$3 +Alias (byte*) print_char_cursor#15 = (byte*) print_char_cursor#34 +Alias (byte*) print_char_cursor#16 = (byte*) print_char_cursor#35 (byte*) print_char_cursor#55 (byte*) print_char_cursor#51 (byte*) print_char_cursor#46 +Alias (byte*) print_points::pointYpos1_return#0 = (byte*) print_points::pointYpos1_$1#0 (byte*) print_points::pointYpos1_return#2 (byte*) print_points::pointYpos1_return#1 (byte*) print_points::pointYpos1_return#3 (byte*~) print_points::$6 +Alias (byte*) print_char_cursor#17 = (byte*) print_char_cursor#36 +Alias (byte*) print_line_cursor#18 = (byte*) print_line_cursor#8 (byte*) print_line_cursor#19 (byte*) print_line_cursor#9 +Alias (byte*) print_char_cursor#18 = (byte*) print_char_cursor#37 (byte*) print_char_cursor#38 (byte*) print_char_cursor#19 +Alias (byte*) print_line_cursor#10 = (byte*) print_line_cursor#20 +Alias (byte*) print_char_cursor#20 = (byte*) print_char_cursor#39 +Successful SSA optimization Pass2AliasElimination +Self Phi Eliminated (byte*) print_char_cursor#23 +Self Phi Eliminated (byte*) print_line_cursor#14 +Successful SSA optimization Pass2SelfPhiElimination +Redundant Phi (byte*) print_str::str#4 (byte*) print_str::str#1 +Redundant Phi (byte*) print_char_cursor#48 (byte*) print_char_cursor#15 +Redundant Phi (byte*) print_line_cursor#21 (byte*) print_line_cursor#24 +Redundant Phi (byte*) print_char_cursor#41 (byte*) print_char_cursor#17 +Redundant Phi (byte*) print_char_cursor#23 (byte*) print_char_cursor#41 +Redundant Phi (byte*) print_char_cursor#25 (byte*) print_char_cursor#29 +Redundant Phi (byte*) print_char_cursor#26 (byte*) print_char_cursor#29 +Redundant Phi (byte*) print_screen#1 (byte*) print_screen#4 +Redundant Phi (byte*) print_line_cursor#14 (byte*) print_screen#1 +Redundant Phi (byte*) print_line_cursor#22 (byte*) print_line_cursor#0 +Redundant Phi (byte*) print_char_cursor#43 (byte*) print_line_cursor#0 +Redundant Phi (byte*) print_screen#5 (byte*) print_line_cursor#0 +Redundant Phi (byte*) print_line_cursor#15 (byte*) print_line_cursor#18 +Redundant Phi (byte*) print_char_cursor#12 (byte*) print_char_cursor#18 +Redundant Phi (byte*) print_screen#4 (byte*) print_screen#5 +Redundant Phi (byte*) print_line_cursor#23 (byte*) print_line_cursor#22 +Redundant Phi (byte*) print_char_cursor#44 (byte*) print_char_cursor#43 +Redundant Phi (byte*) print_line_cursor#17 (byte*) print_line_cursor#14 +Redundant Phi (byte*) print_char_cursor#14 (byte*) print_line_cursor#14 +Redundant Phi (byte*) print_char_cursor#15 (byte*) print_char_cursor#26 +Redundant Phi (byte*) print_char_cursor#16 (byte*) print_char_cursor#2 +Redundant Phi (byte*) print_char_cursor#17 (byte*) print_char_cursor#26 +Redundant Phi (byte*) print_line_cursor#18 (byte*) print_line_cursor#1 +Redundant Phi (byte*) print_char_cursor#18 (byte*) print_line_cursor#1 +Redundant Phi (byte*) print_line_cursor#10 (byte*) print_line_cursor#15 +Redundant Phi (byte*) print_char_cursor#20 (byte*) print_char_cursor#12 +Successful SSA optimization Pass2RedundantPhiElimination +Simple Condition (bool~) print_str::$0 [6] if(*((byte*) print_str::str#2)!=(byte) '@') goto print_str::@2 +Simple Condition (bool~) print_ln::$1 [19] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#29) goto print_ln::@1 +Simple Condition (bool~) print_cls::$1 [55] if((byte*) print_cls::sc#1!=(byte*~) print_cls::$0) goto print_cls::@1 +Simple Condition (bool~) init_points::$4 [117] if((byte) init_points::i#1!=rangelast(0,init_points::$0)) goto init_points::@1 +Simple Condition (bool~) print_points::$9 [173] if((byte) print_points::i#1!=rangelast(0,print_points::$1)) goto print_points::@1 +Successful SSA optimization Pass2ConditionalJumpSimplification +Constant (const byte*) print_line_cursor#0 = ((byte*))$400 +Constant (const byte[]) print_hextab#0 = $1 +Constant (const byte) SIZEOF_POINT#0 = 2 +Constant (const byte) NUM_POINTS#0 = 4 +Constant (const byte) init_points::pos#0 = $a +Constant (const byte) init_points::i#0 = 0 +Constant (const byte) print_points::i#0 = 0 +Constant (const byte*) print_str::str#1 = print_points::str +Successful SSA optimization Pass2ConstantIdentification +Constant (const byte*) print_cls::sc#0 = print_line_cursor#0 +Constant (const byte*) print_cls::$0 = print_line_cursor#0+$3e8 +Constant (const byte) $0 = NUM_POINTS#0*SIZEOF_POINT#0 +Constant (const byte/signed word/word/dword/signed dword) init_points::$0 = NUM_POINTS#0-1 +Constant (const byte/signed word/word/dword/signed dword) print_points::$1 = NUM_POINTS#0-1 +Successful SSA optimization Pass2ConstantIdentification +Constant (const byte[$0]) points#0 = { fill( $0, 0) } +Successful SSA optimization Pass2ConstantIdentification +Removed zero-constant in assignment init_points::pointXpos1_$0#0 +Removed zero-constant in assignment print_points::pointXpos1_$0#0 +Removing redundant cast (byte*) init_points::pointXpos1_return#0 ← ((byte*)) (byte*) init_points::pointXpos1_$0#0 +Removing redundant cast (byte*) init_points::pointYpos1_return#0 ← ((byte*)) (byte*) init_points::pointYpos1_$0#0 +Removing redundant cast (byte*) print_points::pointXpos1_return#0 ← ((byte*)) (byte*) print_points::pointXpos1_$0#0 +Removing redundant cast (byte*) print_points::pointYpos1_return#0 ← ((byte*)) (byte*) print_points::pointYpos1_$0#0 +Successful SSA optimization Pass2EliminateRedundantCasts +Resolved ranged next value init_points::i#1 ← ++ init_points::i#10 to ++ +Resolved ranged comparison value if(init_points::i#1!=rangelast(0,init_points::$0)) goto init_points::@1 to (const byte/signed word/word/dword/signed dword) init_points::$0+(byte/signed byte/word/signed word/dword/signed dword) 1 +Resolved ranged next value print_points::i#1 ← ++ print_points::i#10 to ++ +Resolved ranged comparison value if(print_points::i#1!=rangelast(0,print_points::$1)) goto print_points::@1 to (const byte/signed word/word/dword/signed dword) print_points::$1+(byte/signed byte/word/signed word/dword/signed dword) 1 +Rewriting multiplication to use shift (byte) init_points::getPoint1_$0#0 ← (byte) init_points::i#10 * (const byte) SIZEOF_POINT#0 +Rewriting multiplication to use shift (byte) print_points::getPoint1_$0#0 ← (byte) print_points::i#10 * (const byte) SIZEOF_POINT#0 +Successful SSA optimization Pass2MultiplyToShiftRewriting +Culled Empty Block (label) print_ln::@2 +Culled Empty Block (label) @12 +Culled Empty Block (label) print_byte::@2 +Culled Empty Block (label) print_cls::@2 +Culled Empty Block (label) @19 +Culled Empty Block (label) main::@2 +Culled Empty Block (label) init_points::getPoint1_@return +Culled Empty Block (label) init_points::@3 +Culled Empty Block (label) init_points::pointXpos1_@return +Culled Empty Block (label) init_points::pointYpos1_@return +Culled Empty Block (label) print_points::@6 +Culled Empty Block (label) print_points::getPoint1_@return +Culled Empty Block (label) print_points::@3 +Culled Empty Block (label) print_points::pointXpos1_@return +Culled Empty Block (label) print_points::@8 +Culled Empty Block (label) print_points::pointYpos1_@return +Culled Empty Block (label) @26 +Successful SSA optimization Pass2CullEmptyBlocks +Alias (byte*) init_points::pointXpos1_$0#0 = (byte*) init_points::getPoint1_return#0 (byte*) init_points::pointXpos1_return#0 +Alias (byte*) init_points::pointYpos1_return#0 = (byte*) init_points::pointYpos1_$0#0 +Alias (byte*) print_points::pointXpos1_$0#0 = (byte*) print_points::point#0 (byte*) print_points::pointXpos1_return#0 +Alias (byte*) print_points::pointYpos1_return#0 = (byte*) print_points::pointYpos1_$0#0 +Successful SSA optimization Pass2AliasElimination +Inlining constant with var siblings (const byte*) print_str::str#1 +Inlining constant with var siblings (const byte*) print_cls::sc#0 +Inlining constant with var siblings (const byte) init_points::pos#0 +Inlining constant with var siblings (const byte) init_points::i#0 +Inlining constant with var siblings (const byte) print_points::i#0 +Inlining constant with var siblings (const byte*) print_line_cursor#0 +Constant inlined init_points::$0 = (const byte) NUM_POINTS#0-(byte/signed byte/word/signed word/dword/signed dword) 1 +Constant inlined init_points::i#0 = (byte/signed byte/word/signed word/dword/signed dword) 0 +Constant inlined print_points::$1 = (const byte) NUM_POINTS#0-(byte/signed byte/word/signed word/dword/signed dword) 1 +Constant inlined print_points::i#0 = (byte/signed byte/word/signed word/dword/signed dword) 0 +Constant inlined print_cls::$0 = ((byte*))(word/signed word/dword/signed dword) $400+(word/signed word/dword/signed dword) $3e8 +Constant inlined print_line_cursor#0 = ((byte*))(word/signed word/dword/signed dword) $400 +Constant inlined print_str::str#1 = (const string) print_points::str +Constant inlined $0 = (const byte) NUM_POINTS#0*(const byte) SIZEOF_POINT#0 +Constant inlined print_cls::sc#0 = ((byte*))(word/signed word/dword/signed dword) $400 +Constant inlined $1 = (const byte[]) print_hextab#0 +Constant inlined init_points::pos#0 = (byte/signed byte/word/signed word/dword/signed dword) $a +Successful SSA optimization Pass2ConstantInlining +Added new block during phi lifting print_points::@11(between print_points::@10 and print_points::@1) +Added new block during phi lifting print_ln::@3(between print_ln::@1 and print_ln::@1) +Added new block during phi lifting print_cls::@3(between print_cls::@1 and print_cls::@1) +Added new block during phi lifting init_points::@6(between init_points::@5 and init_points::@1) +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @25 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main +Adding NOP phi() at start of main::@1 +Adding NOP phi() at start of print_points +Adding NOP phi() at start of print_points::pointXpos1 +Adding NOP phi() at start of print_points::@7 +Adding NOP phi() at start of print_points::@9 +Adding NOP phi() at start of print_cls +Adding NOP phi() at start of init_points +Adding NOP phi() at start of init_points::pointXpos1 +CALL GRAPH +Calls in [] to main:2 +Calls in [main] to init_points:5 print_points:7 +Calls in [print_points] to print_cls:10 print_byte:18 print_str:20 print_byte:25 print_ln:27 +Calls in [print_byte] to print_char:45 print_char:50 + +Created 13 initial phi equivalence classes +Coalesced [16] print_byte::b#4 ← print_byte::b#0 +Coalesced [17] print_char_cursor#61 ← print_char_cursor#45 +Coalesced [23] print_byte::b#5 ← print_byte::b#1 +Coalesced [24] print_char_cursor#62 ← print_char_cursor#2 +Coalesced [31] print_points::i#16 ← print_points::i#1 +Not coalescing [32] print_char_cursor#60 ← print_line_cursor#1 +Coalesced [33] print_line_cursor#41 ← print_line_cursor#1 +Coalesced [34] print_line_cursor#42 ← print_line_cursor#24 +Coalesced (already) [39] print_line_cursor#43 ← print_line_cursor#1 +Coalesced [43] print_char::ch#3 ← print_char::ch#0 +Coalesced [44] print_char_cursor#63 ← print_char_cursor#42 +Coalesced [48] print_char::ch#4 ← print_char::ch#1 +Coalesced [49] print_char_cursor#64 ← print_char_cursor#29 +Coalesced (already) [56] print_char_cursor#65 ← print_char_cursor#29 +Coalesced [63] print_str::str#5 ← print_str::str#0 +Coalesced [64] print_char_cursor#66 ← print_char_cursor#1 +Coalesced [71] print_cls::sc#3 ← print_cls::sc#1 +Coalesced [85] init_points::i#12 ← init_points::i#1 +Coalesced [86] init_points::pos#13 ← init_points::pos#2 +Coalesced down to 9 phi equivalence classes +Culled Empty Block (label) print_ln::@3 +Culled Empty Block (label) print_cls::@3 +Culled Empty Block (label) init_points::@6 +Renumbering block @25 to @1 +Renumbering block init_points::@4 to init_points::@2 +Renumbering block init_points::@5 to init_points::@3 +Renumbering block print_points::@4 to print_points::@2 +Renumbering block print_points::@5 to print_points::@3 +Renumbering block print_points::@7 to print_points::@4 +Renumbering block print_points::@9 to print_points::@5 +Renumbering block print_points::@10 to print_points::@6 +Renumbering block print_points::@11 to print_points::@7 +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main +Adding NOP phi() at start of main::@1 +Adding NOP phi() at start of print_points +Adding NOP phi() at start of print_points::pointXpos1 +Adding NOP phi() at start of print_points::@4 +Adding NOP phi() at start of print_points::@5 +Adding NOP phi() at start of print_ln +Adding NOP phi() at start of print_str +Adding NOP phi() at start of print_cls +Adding NOP phi() at start of init_points +Adding NOP phi() at start of init_points::pointXpos1 + +FINAL CONTROL FLOW GRAPH +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() +main: scope:[main] from @1 + [4] phi() + [5] call init_points + to:main::@1 +main::@1: scope:[main] from main + [6] phi() + [7] call print_points + to:main::@return +main::@return: scope:[main] from main::@1 + [8] return + to:@return +print_points: scope:[print_points] from main::@1 + [9] phi() + [10] call print_cls + to:print_points::@1 +print_points::@1: scope:[print_points] from print_points print_points::@7 + [11] (byte*) print_line_cursor#24 ← phi( print_points::@7/(byte*) print_line_cursor#1 print_points/((byte*))(word/signed word/dword/signed dword) $400 ) + [11] (byte*) print_char_cursor#45 ← phi( print_points::@7/(byte*~) print_char_cursor#60 print_points/((byte*))(word/signed word/dword/signed dword) $400 ) + [11] (byte) print_points::i#10 ← phi( print_points::@7/(byte) print_points::i#1 print_points/(byte/signed byte/word/signed word/dword/signed dword) 0 ) + to:print_points::getPoint1 +print_points::getPoint1: scope:[print_points] from print_points::@1 + [12] (byte) print_points::getPoint1_$0#0 ← (byte) print_points::i#10 << (byte/signed byte/word/signed word/dword/signed dword) 1 + [13] (byte*) print_points::pointXpos1_$0#0 ← (const byte[NUM_POINTS#0*SIZEOF_POINT#0]) points#0 + (byte) print_points::getPoint1_$0#0 + to:print_points::pointXpos1 +print_points::pointXpos1: scope:[print_points] from print_points::getPoint1 + [14] phi() + to:print_points::@2 +print_points::@2: scope:[print_points] from print_points::pointXpos1 + [15] (byte) print_byte::b#0 ← *((byte*) print_points::pointXpos1_$0#0) + [16] call print_byte + to:print_points::@4 +print_points::@4: scope:[print_points] from print_points::@2 + [17] phi() + [18] call print_str + to:print_points::pointYpos1 +print_points::pointYpos1: scope:[print_points] from print_points::@4 + [19] (byte*) print_points::pointYpos1_return#0 ← (byte*) print_points::pointXpos1_$0#0 + (byte/signed byte/word/signed word/dword/signed dword) 1 + to:print_points::@3 +print_points::@3: scope:[print_points] from print_points::pointYpos1 + [20] (byte) print_byte::b#1 ← *((byte*) print_points::pointYpos1_return#0) + [21] call print_byte + to:print_points::@5 +print_points::@5: scope:[print_points] from print_points::@3 + [22] phi() + [23] call print_ln + to:print_points::@6 +print_points::@6: scope:[print_points] from print_points::@5 + [24] (byte) print_points::i#1 ← ++ (byte) print_points::i#10 + [25] if((byte) print_points::i#1!=(const byte) NUM_POINTS#0-(byte/signed byte/word/signed word/dword/signed dword) 1+(byte/signed byte/word/signed word/dword/signed dword) 1) goto print_points::@7 + to:print_points::@return +print_points::@return: scope:[print_points] from print_points::@6 + [26] return + to:@return +print_points::@7: scope:[print_points] from print_points::@6 + [27] (byte*~) print_char_cursor#60 ← (byte*) print_line_cursor#1 + to:print_points::@1 +print_ln: scope:[print_ln] from print_points::@5 + [28] phi() + to:print_ln::@1 +print_ln::@1: scope:[print_ln] from print_ln print_ln::@1 + [29] (byte*) print_line_cursor#11 ← phi( print_ln/(byte*) print_line_cursor#24 print_ln::@1/(byte*) print_line_cursor#1 ) + [30] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#11 + (byte/signed byte/word/signed word/dword/signed dword) $28 + [31] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#29) goto print_ln::@1 + to:print_ln::@return +print_ln::@return: scope:[print_ln] from print_ln::@1 + [32] return + to:@return +print_byte: scope:[print_byte] from print_points::@2 print_points::@3 + [33] (byte*) print_char_cursor#42 ← phi( print_points::@2/(byte*) print_char_cursor#45 print_points::@3/(byte*) print_char_cursor#2 ) + [33] (byte) print_byte::b#2 ← phi( print_points::@2/(byte) print_byte::b#0 print_points::@3/(byte) print_byte::b#1 ) + [34] (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4 + [35] (byte) print_char::ch#0 ← *((const byte[]) print_hextab#0 + (byte~) print_byte::$0) + [36] call print_char + to:print_byte::@1 +print_byte::@1: scope:[print_byte] from print_byte + [37] (byte~) print_byte::$2 ← (byte) print_byte::b#2 & (byte/signed byte/word/signed word/dword/signed dword) $f + [38] (byte) print_char::ch#1 ← *((const byte[]) print_hextab#0 + (byte~) print_byte::$2) + [39] call print_char + to:print_byte::@return +print_byte::@return: scope:[print_byte] from print_byte::@1 + [40] return + to:@return +print_char: scope:[print_char] from print_byte print_byte::@1 + [41] (byte*) print_char_cursor#28 ← phi( print_byte/(byte*) print_char_cursor#42 print_byte::@1/(byte*) print_char_cursor#29 ) + [41] (byte) print_char::ch#2 ← phi( print_byte/(byte) print_char::ch#0 print_byte::@1/(byte) print_char::ch#1 ) + [42] *((byte*) print_char_cursor#28) ← (byte) print_char::ch#2 + [43] (byte*) print_char_cursor#29 ← ++ (byte*) print_char_cursor#28 + to:print_char::@return +print_char::@return: scope:[print_char] from print_char + [44] return + to:@return +print_str: scope:[print_str] from print_points::@4 + [45] phi() + to:print_str::@1 +print_str::@1: scope:[print_str] from print_str print_str::@2 + [46] (byte*) print_char_cursor#2 ← phi( print_str/(byte*) print_char_cursor#29 print_str::@2/(byte*) print_char_cursor#1 ) + [46] (byte*) print_str::str#2 ← phi( print_str/(const string) print_points::str print_str::@2/(byte*) print_str::str#0 ) + [47] if(*((byte*) print_str::str#2)!=(byte) '@') goto print_str::@2 + to:print_str::@return +print_str::@return: scope:[print_str] from print_str::@1 + [48] return + to:@return +print_str::@2: scope:[print_str] from print_str::@1 + [49] *((byte*) print_char_cursor#2) ← *((byte*) print_str::str#2) + [50] (byte*) print_char_cursor#1 ← ++ (byte*) print_char_cursor#2 + [51] (byte*) print_str::str#0 ← ++ (byte*) print_str::str#2 + to:print_str::@1 +print_cls: scope:[print_cls] from print_points + [52] phi() + to:print_cls::@1 +print_cls::@1: scope:[print_cls] from print_cls print_cls::@1 + [53] (byte*) print_cls::sc#2 ← phi( print_cls/((byte*))(word/signed word/dword/signed dword) $400 print_cls::@1/(byte*) print_cls::sc#1 ) + [54] *((byte*) print_cls::sc#2) ← (byte) ' ' + [55] (byte*) print_cls::sc#1 ← ++ (byte*) print_cls::sc#2 + [56] if((byte*) print_cls::sc#1!=((byte*))(word/signed word/dword/signed dword) $400+(word/signed word/dword/signed dword) $3e8) goto print_cls::@1 + to:print_cls::@return +print_cls::@return: scope:[print_cls] from print_cls::@1 + [57] return + to:@return +init_points: scope:[init_points] from main + [58] phi() + to:init_points::@1 +init_points::@1: scope:[init_points] from init_points init_points::@3 + [59] (byte) init_points::pos#10 ← phi( init_points/(byte/signed byte/word/signed word/dword/signed dword) $a init_points::@3/(byte) init_points::pos#2 ) + [59] (byte) init_points::i#10 ← phi( init_points/(byte/signed byte/word/signed word/dword/signed dword) 0 init_points::@3/(byte) init_points::i#1 ) + to:init_points::getPoint1 +init_points::getPoint1: scope:[init_points] from init_points::@1 + [60] (byte) init_points::getPoint1_$0#0 ← (byte) init_points::i#10 << (byte/signed byte/word/signed word/dword/signed dword) 1 + [61] (byte*) init_points::pointXpos1_$0#0 ← (const byte[NUM_POINTS#0*SIZEOF_POINT#0]) points#0 + (byte) init_points::getPoint1_$0#0 + to:init_points::pointXpos1 +init_points::pointXpos1: scope:[init_points] from init_points::getPoint1 + [62] phi() + to:init_points::@2 +init_points::@2: scope:[init_points] from init_points::pointXpos1 + [63] *((byte*) init_points::pointXpos1_$0#0) ← (byte) init_points::pos#10 + [64] (byte) init_points::pos#1 ← (byte) init_points::pos#10 + (byte/signed byte/word/signed word/dword/signed dword) $a + to:init_points::pointYpos1 +init_points::pointYpos1: scope:[init_points] from init_points::@2 + [65] (byte*) init_points::pointYpos1_return#0 ← (byte*) init_points::pointXpos1_$0#0 + (byte/signed byte/word/signed word/dword/signed dword) 1 + to:init_points::@3 +init_points::@3: scope:[init_points] from init_points::pointYpos1 + [66] *((byte*) init_points::pointYpos1_return#0) ← (byte) init_points::pos#1 + [67] (byte) init_points::pos#2 ← (byte) init_points::pos#1 + (byte/signed byte/word/signed word/dword/signed dword) $a + [68] (byte) init_points::i#1 ← ++ (byte) init_points::i#10 + [69] if((byte) init_points::i#1!=(const byte) NUM_POINTS#0-(byte/signed byte/word/signed word/dword/signed dword) 1+(byte/signed byte/word/signed word/dword/signed dword) 1) goto init_points::@1 + to:init_points::@return +init_points::@return: scope:[init_points] from init_points::@3 + [70] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(byte) NUM_POINTS +(byte) SIZEOF_POINT +(void()) init_points() +(byte~) init_points::getPoint1_$0 +(byte) init_points::getPoint1_$0#0 22.0 +(byte*~) init_points::getPoint1_$1 +(byte) init_points::getPoint1_idx +(byte*) init_points::getPoint1_return +(byte) init_points::i +(byte) init_points::i#1 16.5 +(byte) init_points::i#10 3.666666666666667 +(byte*) init_points::point +(byte*~) init_points::pointXpos1_$0 +(byte*) init_points::pointXpos1_$0#0 8.25 +(byte*~) init_points::pointXpos1_$1 +(byte*) init_points::pointXpos1_point +(byte*) init_points::pointXpos1_return +(byte*~) init_points::pointYpos1_$0 +(byte*~) init_points::pointYpos1_$1 +(byte*) init_points::pointYpos1_point +(byte*) init_points::pointYpos1_return +(byte*) init_points::pointYpos1_return#0 22.0 +(byte) init_points::pos +(byte) init_points::pos#1 11.0 +(byte) init_points::pos#10 6.6000000000000005 +(byte) init_points::pos#2 7.333333333333333 +(void()) main() +(byte[NUM_POINTS#0*SIZEOF_POINT#0]) points +(void()) print_byte((byte) print_byte::b) +(byte~) print_byte::$0 4.0 +(byte~) print_byte::$2 4.0 +(byte) print_byte::b +(byte) print_byte::b#0 22.0 +(byte) print_byte::b#1 22.0 +(byte) print_byte::b#2 6.5 +(void()) print_char((byte) print_char::ch) +(byte) print_char::ch +(byte) print_char::ch#0 4.0 +(byte) print_char::ch#1 4.0 +(byte) print_char::ch#2 6.0 +(byte*) print_char_cursor +(byte*) print_char_cursor#1 101.0 +(byte*) print_char_cursor#2 45.142857142857146 +(byte*) print_char_cursor#28 4.0 +(byte*) print_char_cursor#29 6.6875 +(byte*) print_char_cursor#42 8.0 +(byte*) print_char_cursor#45 4.4 +(byte*~) print_char_cursor#60 22.0 +(void()) print_cls() +(byte*) print_cls::sc +(byte*) print_cls::sc#1 16.5 +(byte*) print_cls::sc#2 16.5 +(byte[]) print_hextab +(byte*) print_line_cursor +(byte*) print_line_cursor#1 46.42857142857143 +(byte*) print_line_cursor#11 204.0 +(byte*) print_line_cursor#24 1.0 +(void()) print_ln() +(void()) print_points() +(byte~) print_points::getPoint1_$0 +(byte) print_points::getPoint1_$0#0 22.0 +(byte*~) print_points::getPoint1_$1 +(byte) print_points::getPoint1_idx +(byte*) print_points::getPoint1_return +(byte) print_points::i +(byte) print_points::i#1 11.0 +(byte) print_points::i#10 2.5384615384615383 +(byte*) print_points::point +(byte*~) print_points::pointXpos1_$0 +(byte*) print_points::pointXpos1_$0#0 5.5 +(byte*~) print_points::pointXpos1_$1 +(byte*) print_points::pointXpos1_point +(byte*) print_points::pointXpos1_return +(byte*~) print_points::pointYpos1_$0 +(byte*~) print_points::pointYpos1_$1 +(byte*) print_points::pointYpos1_point +(byte*) print_points::pointYpos1_return +(byte*) print_points::pointYpos1_return#0 22.0 +(byte*) print_screen +(void()) print_str((byte*) print_str::str) +(byte*) print_str::str +(byte*) print_str::str#0 202.0 +(byte*) print_str::str#2 101.0 + +Initial phi equivalence classes +[ print_points::i#10 print_points::i#1 ] +[ print_line_cursor#11 print_line_cursor#24 print_line_cursor#1 ] +[ print_byte::b#2 print_byte::b#0 print_byte::b#1 ] +[ print_char::ch#2 print_char::ch#0 print_char::ch#1 ] +[ print_char_cursor#28 print_char_cursor#42 print_char_cursor#45 print_char_cursor#60 print_char_cursor#2 print_char_cursor#29 print_char_cursor#1 ] +[ print_str::str#2 print_str::str#0 ] +[ print_cls::sc#2 print_cls::sc#1 ] +[ init_points::i#10 init_points::i#1 ] +[ init_points::pos#10 init_points::pos#2 ] +Added variable print_points::getPoint1_$0#0 to zero page equivalence class [ print_points::getPoint1_$0#0 ] +Added variable print_points::pointXpos1_$0#0 to zero page equivalence class [ print_points::pointXpos1_$0#0 ] +Added variable print_points::pointYpos1_return#0 to zero page equivalence class [ print_points::pointYpos1_return#0 ] +Added variable print_byte::$0 to zero page equivalence class [ print_byte::$0 ] +Added variable print_byte::$2 to zero page equivalence class [ print_byte::$2 ] +Added variable init_points::getPoint1_$0#0 to zero page equivalence class [ init_points::getPoint1_$0#0 ] +Added variable init_points::pointXpos1_$0#0 to zero page equivalence class [ init_points::pointXpos1_$0#0 ] +Added variable init_points::pos#1 to zero page equivalence class [ init_points::pos#1 ] +Added variable init_points::pointYpos1_return#0 to zero page equivalence class [ init_points::pointYpos1_return#0 ] +Complete equivalence classes +[ print_points::i#10 print_points::i#1 ] +[ print_line_cursor#11 print_line_cursor#24 print_line_cursor#1 ] +[ print_byte::b#2 print_byte::b#0 print_byte::b#1 ] +[ print_char::ch#2 print_char::ch#0 print_char::ch#1 ] +[ print_char_cursor#28 print_char_cursor#42 print_char_cursor#45 print_char_cursor#60 print_char_cursor#2 print_char_cursor#29 print_char_cursor#1 ] +[ print_str::str#2 print_str::str#0 ] +[ print_cls::sc#2 print_cls::sc#1 ] +[ init_points::i#10 init_points::i#1 ] +[ init_points::pos#10 init_points::pos#2 ] +[ print_points::getPoint1_$0#0 ] +[ print_points::pointXpos1_$0#0 ] +[ print_points::pointYpos1_return#0 ] +[ print_byte::$0 ] +[ print_byte::$2 ] +[ init_points::getPoint1_$0#0 ] +[ init_points::pointXpos1_$0#0 ] +[ init_points::pos#1 ] +[ init_points::pointYpos1_return#0 ] +Allocated zp ZP_BYTE:2 [ print_points::i#10 print_points::i#1 ] +Allocated zp ZP_WORD:3 [ print_line_cursor#11 print_line_cursor#24 print_line_cursor#1 ] +Allocated zp ZP_BYTE:5 [ print_byte::b#2 print_byte::b#0 print_byte::b#1 ] +Allocated zp ZP_BYTE:6 [ print_char::ch#2 print_char::ch#0 print_char::ch#1 ] +Allocated zp ZP_WORD:7 [ print_char_cursor#28 print_char_cursor#42 print_char_cursor#45 print_char_cursor#60 print_char_cursor#2 print_char_cursor#29 print_char_cursor#1 ] +Allocated zp ZP_WORD:9 [ print_str::str#2 print_str::str#0 ] +Allocated zp ZP_WORD:11 [ print_cls::sc#2 print_cls::sc#1 ] +Allocated zp ZP_BYTE:13 [ init_points::i#10 init_points::i#1 ] +Allocated zp ZP_BYTE:14 [ init_points::pos#10 init_points::pos#2 ] +Allocated zp ZP_BYTE:15 [ print_points::getPoint1_$0#0 ] +Allocated zp ZP_WORD:16 [ print_points::pointXpos1_$0#0 ] +Allocated zp ZP_WORD:18 [ print_points::pointYpos1_return#0 ] +Allocated zp ZP_BYTE:20 [ print_byte::$0 ] +Allocated zp ZP_BYTE:21 [ print_byte::$2 ] +Allocated zp ZP_BYTE:22 [ init_points::getPoint1_$0#0 ] +Allocated zp ZP_WORD:23 [ init_points::pointXpos1_$0#0 ] +Allocated zp ZP_BYTE:25 [ init_points::pos#1 ] +Allocated zp ZP_WORD:26 [ init_points::pointYpos1_return#0 ] + +INITIAL ASM +//SEG0 File Comments +// Implementing a semi-struct without the struct keyword by using pointer math and inline functions +// +// struct Point { +// byte xpos; // The x-position +// byte ypos; // The y-position +// }; +// Point[NUM_POINTS] points; +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels + // The size of a point + .const SIZEOF_POINT = 2 + // The number of points + .const NUM_POINTS = 4 + .label print_char_cursor = 7 + .label print_line_cursor = 3 +//SEG3 @begin +bbegin: +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 +//SEG5 @1 +b1: +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG9 @end +bend: +//SEG10 main +// Initialize some points and print them +main: { + //SEG11 [5] call init_points + //SEG12 [58] phi from main to init_points [phi:main->init_points] + init_points_from_main: + jsr init_points + //SEG13 [6] phi from main to main::@1 [phi:main->main::@1] + b1_from_main: + jmp b1 + //SEG14 main::@1 + b1: + //SEG15 [7] call print_points + //SEG16 [9] phi from main::@1 to print_points [phi:main::@1->print_points] + print_points_from_b1: + jsr print_points + jmp breturn + //SEG17 main::@return + breturn: + //SEG18 [8] return + rts +} +//SEG19 print_points +// Print points +print_points: { + .label getPoint1__0 = $f + .label pointXpos1__0 = $10 + .label pointYpos1_return = $12 + .label i = 2 + //SEG20 [10] call print_cls + //SEG21 [52] phi from print_points to print_cls [phi:print_points->print_cls] + print_cls_from_print_points: + jsr print_cls + //SEG22 [11] phi from print_points to print_points::@1 [phi:print_points->print_points::@1] + b1_from_print_points: + //SEG23 [11] phi (byte*) print_line_cursor#24 = ((byte*))(word/signed word/dword/signed dword) $400 [phi:print_points->print_points::@1#0] -- pbuz1=pbuc1 + lda #<$400 + sta print_line_cursor + lda #>$400 + sta print_line_cursor+1 + //SEG24 [11] phi (byte*) print_char_cursor#45 = ((byte*))(word/signed word/dword/signed dword) $400 [phi:print_points->print_points::@1#1] -- pbuz1=pbuc1 + lda #<$400 + sta print_char_cursor + lda #>$400 + sta print_char_cursor+1 + //SEG25 [11] phi (byte) print_points::i#10 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:print_points->print_points::@1#2] -- vbuz1=vbuc1 + lda #0 + sta i + jmp b1 + //SEG26 print_points::@1 + b1: + jmp getPoint1 + //SEG27 print_points::getPoint1 + getPoint1: + //SEG28 [12] (byte) print_points::getPoint1_$0#0 ← (byte) print_points::i#10 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuz1=vbuz2_rol_1 + lda i + asl + sta getPoint1__0 + //SEG29 [13] (byte*) print_points::pointXpos1_$0#0 ← (const byte[NUM_POINTS#0*SIZEOF_POINT#0]) points#0 + (byte) print_points::getPoint1_$0#0 -- pbuz1=pbuc1_plus_vbuz2 + lda getPoint1__0 + clc + adc #points + adc #0 + sta pointXpos1__0+1 + //SEG30 [14] phi from print_points::getPoint1 to print_points::pointXpos1 [phi:print_points::getPoint1->print_points::pointXpos1] + pointXpos1_from_getPoint1: + jmp pointXpos1 + //SEG31 print_points::pointXpos1 + pointXpos1: + jmp b2 + //SEG32 print_points::@2 + b2: + //SEG33 [15] (byte) print_byte::b#0 ← *((byte*) print_points::pointXpos1_$0#0) -- vbuz1=_deref_pbuz2 + ldy #0 + lda (pointXpos1__0),y + sta print_byte.b + //SEG34 [16] call print_byte + //SEG35 [33] phi from print_points::@2 to print_byte [phi:print_points::@2->print_byte] + print_byte_from_b2: + //SEG36 [33] phi (byte*) print_char_cursor#42 = (byte*) print_char_cursor#45 [phi:print_points::@2->print_byte#0] -- register_copy + //SEG37 [33] phi (byte) print_byte::b#2 = (byte) print_byte::b#0 [phi:print_points::@2->print_byte#1] -- register_copy + jsr print_byte + //SEG38 [17] phi from print_points::@2 to print_points::@4 [phi:print_points::@2->print_points::@4] + b4_from_b2: + jmp b4 + //SEG39 print_points::@4 + b4: + //SEG40 [18] call print_str + //SEG41 [45] phi from print_points::@4 to print_str [phi:print_points::@4->print_str] + print_str_from_b4: + jsr print_str + jmp pointYpos1 + //SEG42 print_points::pointYpos1 + pointYpos1: + //SEG43 [19] (byte*) print_points::pointYpos1_return#0 ← (byte*) print_points::pointXpos1_$0#0 + (byte/signed byte/word/signed word/dword/signed dword) 1 -- pbuz1=pbuz2_plus_1 + lda pointXpos1__0 + clc + adc #1 + sta pointYpos1_return + lda pointXpos1__0+1 + adc #0 + sta pointYpos1_return+1 + jmp b3 + //SEG44 print_points::@3 + b3: + //SEG45 [20] (byte) print_byte::b#1 ← *((byte*) print_points::pointYpos1_return#0) -- vbuz1=_deref_pbuz2 + ldy #0 + lda (pointYpos1_return),y + sta print_byte.b + //SEG46 [21] call print_byte + //SEG47 [33] phi from print_points::@3 to print_byte [phi:print_points::@3->print_byte] + print_byte_from_b3: + //SEG48 [33] phi (byte*) print_char_cursor#42 = (byte*) print_char_cursor#2 [phi:print_points::@3->print_byte#0] -- register_copy + //SEG49 [33] phi (byte) print_byte::b#2 = (byte) print_byte::b#1 [phi:print_points::@3->print_byte#1] -- register_copy + jsr print_byte + //SEG50 [22] phi from print_points::@3 to print_points::@5 [phi:print_points::@3->print_points::@5] + b5_from_b3: + jmp b5 + //SEG51 print_points::@5 + b5: + //SEG52 [23] call print_ln + //SEG53 [28] phi from print_points::@5 to print_ln [phi:print_points::@5->print_ln] + print_ln_from_b5: + jsr print_ln + jmp b6 + //SEG54 print_points::@6 + b6: + //SEG55 [24] (byte) print_points::i#1 ← ++ (byte) print_points::i#10 -- vbuz1=_inc_vbuz1 + inc i + //SEG56 [25] if((byte) print_points::i#1!=(const byte) NUM_POINTS#0-(byte/signed byte/word/signed word/dword/signed dword) 1+(byte/signed byte/word/signed word/dword/signed dword) 1) goto print_points::@7 -- vbuz1_neq_vbuc1_then_la1 + lda #NUM_POINTS-1+1 + cmp i + bne b7 + jmp breturn + //SEG57 print_points::@return + breturn: + //SEG58 [26] return + rts + //SEG59 print_points::@7 + b7: + //SEG60 [27] (byte*~) print_char_cursor#60 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 + lda print_line_cursor + sta print_char_cursor + lda print_line_cursor+1 + sta print_char_cursor+1 + //SEG61 [11] phi from print_points::@7 to print_points::@1 [phi:print_points::@7->print_points::@1] + b1_from_b7: + //SEG62 [11] phi (byte*) print_line_cursor#24 = (byte*) print_line_cursor#1 [phi:print_points::@7->print_points::@1#0] -- register_copy + //SEG63 [11] phi (byte*) print_char_cursor#45 = (byte*~) print_char_cursor#60 [phi:print_points::@7->print_points::@1#1] -- register_copy + //SEG64 [11] phi (byte) print_points::i#10 = (byte) print_points::i#1 [phi:print_points::@7->print_points::@1#2] -- register_copy + jmp b1 + str: .text " @" +} +//SEG65 print_ln +// Print a newline +print_ln: { + //SEG66 [29] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] + b1_from_print_ln: + b1_from_b1: + //SEG67 [29] phi (byte*) print_line_cursor#11 = (byte*) print_line_cursor#24 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy + jmp b1 + //SEG68 print_ln::@1 + b1: + //SEG69 [30] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#11 + (byte/signed byte/word/signed word/dword/signed dword) $28 -- pbuz1=pbuz1_plus_vbuc1 + lda #$28 + clc + adc print_line_cursor + sta print_line_cursor + bcc !+ + inc print_line_cursor+1 + !: + //SEG70 [31] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#29) goto print_ln::@1 -- pbuz1_lt_pbuz2_then_la1 + lda print_line_cursor+1 + cmp print_char_cursor+1 + bcc b1_from_b1 + bne !+ + lda print_line_cursor + cmp print_char_cursor + bcc b1_from_b1 + !: + jmp breturn + //SEG71 print_ln::@return + breturn: + //SEG72 [32] return + rts +} +//SEG73 print_byte +// Print a byte as HEX +// print_byte(byte zeropage(5) b) +print_byte: { + .label _0 = $14 + .label _2 = $15 + .label b = 5 + //SEG74 [34] (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuz1=vbuz2_ror_4 + lda b + lsr + lsr + lsr + lsr + sta _0 + //SEG75 [35] (byte) print_char::ch#0 ← *((const byte[]) print_hextab#0 + (byte~) print_byte::$0) -- vbuz1=pbuc1_derefidx_vbuz2 + ldy _0 + lda print_hextab,y + sta print_char.ch + //SEG76 [36] call print_char + //SEG77 [41] phi from print_byte to print_char [phi:print_byte->print_char] + print_char_from_print_byte: + //SEG78 [41] phi (byte*) print_char_cursor#28 = (byte*) print_char_cursor#42 [phi:print_byte->print_char#0] -- register_copy + //SEG79 [41] phi (byte) print_char::ch#2 = (byte) print_char::ch#0 [phi:print_byte->print_char#1] -- register_copy + jsr print_char + jmp b1 + //SEG80 print_byte::@1 + b1: + //SEG81 [37] (byte~) print_byte::$2 ← (byte) print_byte::b#2 & (byte/signed byte/word/signed word/dword/signed dword) $f -- vbuz1=vbuz2_band_vbuc1 + lda #$f + and b + sta _2 + //SEG82 [38] (byte) print_char::ch#1 ← *((const byte[]) print_hextab#0 + (byte~) print_byte::$2) -- vbuz1=pbuc1_derefidx_vbuz2 + ldy _2 + lda print_hextab,y + sta print_char.ch + //SEG83 [39] call print_char + //SEG84 [41] phi from print_byte::@1 to print_char [phi:print_byte::@1->print_char] + print_char_from_b1: + //SEG85 [41] phi (byte*) print_char_cursor#28 = (byte*) print_char_cursor#29 [phi:print_byte::@1->print_char#0] -- register_copy + //SEG86 [41] phi (byte) print_char::ch#2 = (byte) print_char::ch#1 [phi:print_byte::@1->print_char#1] -- register_copy + jsr print_char + jmp breturn + //SEG87 print_byte::@return + breturn: + //SEG88 [40] return + rts +} +//SEG89 print_char +// Print a single char +// print_char(byte zeropage(6) ch) +print_char: { + .label ch = 6 + //SEG90 [42] *((byte*) print_char_cursor#28) ← (byte) print_char::ch#2 -- _deref_pbuz1=vbuz2 + lda ch + ldy #0 + sta (print_char_cursor),y + //SEG91 [43] (byte*) print_char_cursor#29 ← ++ (byte*) print_char_cursor#28 -- pbuz1=_inc_pbuz1 + inc print_char_cursor + bne !+ + inc print_char_cursor+1 + !: + jmp breturn + //SEG92 print_char::@return + breturn: + //SEG93 [44] return + rts +} +//SEG94 print_str +// Print a zero-terminated string +// print_str(byte* zeropage(9) str) +print_str: { + .label str = 9 + //SEG95 [46] phi from print_str to print_str::@1 [phi:print_str->print_str::@1] + b1_from_print_str: + //SEG96 [46] phi (byte*) print_char_cursor#2 = (byte*) print_char_cursor#29 [phi:print_str->print_str::@1#0] -- register_copy + //SEG97 [46] phi (byte*) print_str::str#2 = (const string) print_points::str [phi:print_str->print_str::@1#1] -- pbuz1=pbuc1 + lda #print_points.str + sta str+1 + jmp b1 + //SEG98 print_str::@1 + b1: + //SEG99 [47] if(*((byte*) print_str::str#2)!=(byte) '@') goto print_str::@2 -- _deref_pbuz1_neq_vbuc1_then_la1 + ldy #0 + lda (str),y + cmp #'@' + bne b2 + jmp breturn + //SEG100 print_str::@return + breturn: + //SEG101 [48] return + rts + //SEG102 print_str::@2 + b2: + //SEG103 [49] *((byte*) print_char_cursor#2) ← *((byte*) print_str::str#2) -- _deref_pbuz1=_deref_pbuz2 + ldy #0 + lda (str),y + ldy #0 + sta (print_char_cursor),y + //SEG104 [50] (byte*) print_char_cursor#1 ← ++ (byte*) print_char_cursor#2 -- pbuz1=_inc_pbuz1 + inc print_char_cursor + bne !+ + inc print_char_cursor+1 + !: + //SEG105 [51] (byte*) print_str::str#0 ← ++ (byte*) print_str::str#2 -- pbuz1=_inc_pbuz1 + inc str + bne !+ + inc str+1 + !: + //SEG106 [46] phi from print_str::@2 to print_str::@1 [phi:print_str::@2->print_str::@1] + b1_from_b2: + //SEG107 [46] phi (byte*) print_char_cursor#2 = (byte*) print_char_cursor#1 [phi:print_str::@2->print_str::@1#0] -- register_copy + //SEG108 [46] phi (byte*) print_str::str#2 = (byte*) print_str::str#0 [phi:print_str::@2->print_str::@1#1] -- register_copy + jmp b1 +} +//SEG109 print_cls +// Clear the screen. Also resets current line/char cursor. +print_cls: { + .label sc = $b + //SEG110 [53] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] + b1_from_print_cls: + //SEG111 [53] phi (byte*) print_cls::sc#2 = ((byte*))(word/signed word/dword/signed dword) $400 [phi:print_cls->print_cls::@1#0] -- pbuz1=pbuc1 + lda #<$400 + sta sc + lda #>$400 + sta sc+1 + jmp b1 + //SEG112 [53] phi from print_cls::@1 to print_cls::@1 [phi:print_cls::@1->print_cls::@1] + b1_from_b1: + //SEG113 [53] phi (byte*) print_cls::sc#2 = (byte*) print_cls::sc#1 [phi:print_cls::@1->print_cls::@1#0] -- register_copy + jmp b1 + //SEG114 print_cls::@1 + b1: + //SEG115 [54] *((byte*) print_cls::sc#2) ← (byte) ' ' -- _deref_pbuz1=vbuc1 + lda #' ' + ldy #0 + sta (sc),y + //SEG116 [55] (byte*) print_cls::sc#1 ← ++ (byte*) print_cls::sc#2 -- pbuz1=_inc_pbuz1 + inc sc + bne !+ + inc sc+1 + !: + //SEG117 [56] if((byte*) print_cls::sc#1!=((byte*))(word/signed word/dword/signed dword) $400+(word/signed word/dword/signed dword) $3e8) goto print_cls::@1 -- pbuz1_neq_pbuc1_then_la1 + lda sc+1 + cmp #>$400+$3e8 + bne b1_from_b1 + lda sc + cmp #<$400+$3e8 + bne b1_from_b1 + jmp breturn + //SEG118 print_cls::@return + breturn: + //SEG119 [57] return + rts +} +//SEG120 init_points +// Initialize points +init_points: { + .label getPoint1__0 = $16 + .label pointXpos1__0 = $17 + .label pos = $19 + .label pointYpos1_return = $1a + .label pos_2 = $e + .label i = $d + .label pos_10 = $e + //SEG121 [59] phi from init_points to init_points::@1 [phi:init_points->init_points::@1] + b1_from_init_points: + //SEG122 [59] phi (byte) init_points::pos#10 = (byte/signed byte/word/signed word/dword/signed dword) $a [phi:init_points->init_points::@1#0] -- vbuz1=vbuc1 + lda #$a + sta pos_10 + //SEG123 [59] phi (byte) init_points::i#10 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:init_points->init_points::@1#1] -- vbuz1=vbuc1 + lda #0 + sta i + jmp b1 + //SEG124 [59] phi from init_points::@3 to init_points::@1 [phi:init_points::@3->init_points::@1] + b1_from_b3: + //SEG125 [59] phi (byte) init_points::pos#10 = (byte) init_points::pos#2 [phi:init_points::@3->init_points::@1#0] -- register_copy + //SEG126 [59] phi (byte) init_points::i#10 = (byte) init_points::i#1 [phi:init_points::@3->init_points::@1#1] -- register_copy + jmp b1 + //SEG127 init_points::@1 + b1: + jmp getPoint1 + //SEG128 init_points::getPoint1 + getPoint1: + //SEG129 [60] (byte) init_points::getPoint1_$0#0 ← (byte) init_points::i#10 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuz1=vbuz2_rol_1 + lda i + asl + sta getPoint1__0 + //SEG130 [61] (byte*) init_points::pointXpos1_$0#0 ← (const byte[NUM_POINTS#0*SIZEOF_POINT#0]) points#0 + (byte) init_points::getPoint1_$0#0 -- pbuz1=pbuc1_plus_vbuz2 + lda getPoint1__0 + clc + adc #points + adc #0 + sta pointXpos1__0+1 + //SEG131 [62] phi from init_points::getPoint1 to init_points::pointXpos1 [phi:init_points::getPoint1->init_points::pointXpos1] + pointXpos1_from_getPoint1: + jmp pointXpos1 + //SEG132 init_points::pointXpos1 + pointXpos1: + jmp b2 + //SEG133 init_points::@2 + b2: + //SEG134 [63] *((byte*) init_points::pointXpos1_$0#0) ← (byte) init_points::pos#10 -- _deref_pbuz1=vbuz2 + lda pos_10 + ldy #0 + sta (pointXpos1__0),y + //SEG135 [64] (byte) init_points::pos#1 ← (byte) init_points::pos#10 + (byte/signed byte/word/signed word/dword/signed dword) $a -- vbuz1=vbuz2_plus_vbuc1 + lax pos_10 + axs #-[$a] + stx pos + jmp pointYpos1 + //SEG136 init_points::pointYpos1 + pointYpos1: + //SEG137 [65] (byte*) init_points::pointYpos1_return#0 ← (byte*) init_points::pointXpos1_$0#0 + (byte/signed byte/word/signed word/dword/signed dword) 1 -- pbuz1=pbuz2_plus_1 + lda pointXpos1__0 + clc + adc #1 + sta pointYpos1_return + lda pointXpos1__0+1 + adc #0 + sta pointYpos1_return+1 + jmp b3 + //SEG138 init_points::@3 + b3: + //SEG139 [66] *((byte*) init_points::pointYpos1_return#0) ← (byte) init_points::pos#1 -- _deref_pbuz1=vbuz2 + lda pos + ldy #0 + sta (pointYpos1_return),y + //SEG140 [67] (byte) init_points::pos#2 ← (byte) init_points::pos#1 + (byte/signed byte/word/signed word/dword/signed dword) $a -- vbuz1=vbuz2_plus_vbuc1 + lax pos + axs #-[$a] + stx pos_2 + //SEG141 [68] (byte) init_points::i#1 ← ++ (byte) init_points::i#10 -- vbuz1=_inc_vbuz1 + inc i + //SEG142 [69] if((byte) init_points::i#1!=(const byte) NUM_POINTS#0-(byte/signed byte/word/signed word/dword/signed dword) 1+(byte/signed byte/word/signed word/dword/signed dword) 1) goto init_points::@1 -- vbuz1_neq_vbuc1_then_la1 + lda #NUM_POINTS-1+1 + cmp i + bne b1_from_b3 + jmp breturn + //SEG143 init_points::@return + breturn: + //SEG144 [70] return + rts +} + print_hextab: .text "0123456789abcdef" + // All points + points: .fill NUM_POINTS*SIZEOF_POINT, 0 + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [12] (byte) print_points::getPoint1_$0#0 ← (byte) print_points::i#10 << (byte/signed byte/word/signed word/dword/signed dword) 1 [ print_points::i#10 print_char_cursor#45 print_line_cursor#24 print_points::getPoint1_$0#0 ] ( main:2::print_points:7 [ print_points::i#10 print_char_cursor#45 print_line_cursor#24 print_points::getPoint1_$0#0 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ print_points::i#10 print_points::i#1 ] +Statement [13] (byte*) print_points::pointXpos1_$0#0 ← (const byte[NUM_POINTS#0*SIZEOF_POINT#0]) points#0 + (byte) print_points::getPoint1_$0#0 [ print_points::i#10 print_char_cursor#45 print_line_cursor#24 print_points::pointXpos1_$0#0 ] ( main:2::print_points:7 [ print_points::i#10 print_char_cursor#45 print_line_cursor#24 print_points::pointXpos1_$0#0 ] ) always clobbers reg byte a +Statement [15] (byte) print_byte::b#0 ← *((byte*) print_points::pointXpos1_$0#0) [ print_points::i#10 print_char_cursor#45 print_line_cursor#24 print_points::pointXpos1_$0#0 print_byte::b#0 ] ( main:2::print_points:7 [ print_points::i#10 print_char_cursor#45 print_line_cursor#24 print_points::pointXpos1_$0#0 print_byte::b#0 ] ) always clobbers reg byte a reg byte y +Removing always clobbered register reg byte y as potential for zp ZP_BYTE:2 [ print_points::i#10 print_points::i#1 ] +Statement [19] (byte*) print_points::pointYpos1_return#0 ← (byte*) print_points::pointXpos1_$0#0 + (byte/signed byte/word/signed word/dword/signed dword) 1 [ print_points::i#10 print_line_cursor#24 print_points::pointYpos1_return#0 print_char_cursor#2 ] ( main:2::print_points:7 [ print_points::i#10 print_line_cursor#24 print_points::pointYpos1_return#0 print_char_cursor#2 ] ) always clobbers reg byte a +Statement [20] (byte) print_byte::b#1 ← *((byte*) print_points::pointYpos1_return#0) [ print_points::i#10 print_line_cursor#24 print_byte::b#1 print_char_cursor#2 ] ( main:2::print_points:7 [ print_points::i#10 print_line_cursor#24 print_byte::b#1 print_char_cursor#2 ] ) always clobbers reg byte a reg byte y +Statement [27] (byte*~) print_char_cursor#60 ← (byte*) print_line_cursor#1 [ print_points::i#1 print_char_cursor#60 print_line_cursor#1 ] ( main:2::print_points:7 [ print_points::i#1 print_char_cursor#60 print_line_cursor#1 ] ) always clobbers reg byte a +Statement [30] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#11 + (byte/signed byte/word/signed word/dword/signed dword) $28 [ print_line_cursor#1 print_char_cursor#29 ] ( main:2::print_points:7::print_ln:23 [ print_points::i#10 print_line_cursor#1 print_char_cursor#29 ] ) always clobbers reg byte a +Statement [31] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#29) goto print_ln::@1 [ print_line_cursor#1 print_char_cursor#29 ] ( main:2::print_points:7::print_ln:23 [ print_points::i#10 print_line_cursor#1 print_char_cursor#29 ] ) always clobbers reg byte a +Statement [34] (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4 [ print_byte::b#2 print_char_cursor#42 print_byte::$0 ] ( main:2::print_points:7::print_byte:16 [ print_points::i#10 print_line_cursor#24 print_points::pointXpos1_$0#0 print_byte::b#2 print_char_cursor#42 print_byte::$0 ] main:2::print_points:7::print_byte:21 [ print_points::i#10 print_line_cursor#24 print_byte::b#2 print_char_cursor#42 print_byte::$0 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:5 [ print_byte::b#2 print_byte::b#0 print_byte::b#1 ] +Statement [37] (byte~) print_byte::$2 ← (byte) print_byte::b#2 & (byte/signed byte/word/signed word/dword/signed dword) $f [ print_char_cursor#29 print_byte::$2 ] ( main:2::print_points:7::print_byte:16 [ print_points::i#10 print_line_cursor#24 print_points::pointXpos1_$0#0 print_char_cursor#29 print_byte::$2 ] main:2::print_points:7::print_byte:21 [ print_points::i#10 print_line_cursor#24 print_char_cursor#29 print_byte::$2 ] ) always clobbers reg byte a +Statement [42] *((byte*) print_char_cursor#28) ← (byte) print_char::ch#2 [ print_char_cursor#28 ] ( main:2::print_points:7::print_byte:16::print_char:36 [ print_points::i#10 print_line_cursor#24 print_points::pointXpos1_$0#0 print_byte::b#2 print_char_cursor#28 ] main:2::print_points:7::print_byte:21::print_char:36 [ print_points::i#10 print_line_cursor#24 print_byte::b#2 print_char_cursor#28 ] main:2::print_points:7::print_byte:16::print_char:39 [ print_points::i#10 print_line_cursor#24 print_points::pointXpos1_$0#0 print_char_cursor#28 ] main:2::print_points:7::print_byte:21::print_char:39 [ print_points::i#10 print_line_cursor#24 print_char_cursor#28 ] ) always clobbers reg byte y +Removing always clobbered register reg byte y as potential for zp ZP_BYTE:5 [ print_byte::b#2 print_byte::b#0 print_byte::b#1 ] +Statement [47] if(*((byte*) print_str::str#2)!=(byte) '@') goto print_str::@2 [ print_char_cursor#2 print_str::str#2 ] ( main:2::print_points:7::print_str:18 [ print_points::i#10 print_line_cursor#24 print_points::pointXpos1_$0#0 print_char_cursor#2 print_str::str#2 ] ) always clobbers reg byte a reg byte y +Statement [49] *((byte*) print_char_cursor#2) ← *((byte*) print_str::str#2) [ print_char_cursor#2 print_str::str#2 ] ( main:2::print_points:7::print_str:18 [ print_points::i#10 print_line_cursor#24 print_points::pointXpos1_$0#0 print_char_cursor#2 print_str::str#2 ] ) always clobbers reg byte a reg byte y +Statement [54] *((byte*) print_cls::sc#2) ← (byte) ' ' [ print_cls::sc#2 ] ( main:2::print_points:7::print_cls:10 [ print_cls::sc#2 ] ) always clobbers reg byte a reg byte y +Statement [56] if((byte*) print_cls::sc#1!=((byte*))(word/signed word/dword/signed dword) $400+(word/signed word/dword/signed dword) $3e8) goto print_cls::@1 [ print_cls::sc#1 ] ( main:2::print_points:7::print_cls:10 [ print_cls::sc#1 ] ) always clobbers reg byte a +Statement [60] (byte) init_points::getPoint1_$0#0 ← (byte) init_points::i#10 << (byte/signed byte/word/signed word/dword/signed dword) 1 [ init_points::i#10 init_points::pos#10 init_points::getPoint1_$0#0 ] ( main:2::init_points:5 [ init_points::i#10 init_points::pos#10 init_points::getPoint1_$0#0 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:13 [ init_points::i#10 init_points::i#1 ] +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:14 [ init_points::pos#10 init_points::pos#2 ] +Statement [61] (byte*) init_points::pointXpos1_$0#0 ← (const byte[NUM_POINTS#0*SIZEOF_POINT#0]) points#0 + (byte) init_points::getPoint1_$0#0 [ init_points::i#10 init_points::pos#10 init_points::pointXpos1_$0#0 ] ( main:2::init_points:5 [ init_points::i#10 init_points::pos#10 init_points::pointXpos1_$0#0 ] ) always clobbers reg byte a +Statement [63] *((byte*) init_points::pointXpos1_$0#0) ← (byte) init_points::pos#10 [ init_points::i#10 init_points::pos#10 init_points::pointXpos1_$0#0 ] ( main:2::init_points:5 [ init_points::i#10 init_points::pos#10 init_points::pointXpos1_$0#0 ] ) always clobbers reg byte a reg byte y +Removing always clobbered register reg byte y as potential for zp ZP_BYTE:13 [ init_points::i#10 init_points::i#1 ] +Removing always clobbered register reg byte y as potential for zp ZP_BYTE:14 [ init_points::pos#10 init_points::pos#2 ] +Statement [64] (byte) init_points::pos#1 ← (byte) init_points::pos#10 + (byte/signed byte/word/signed word/dword/signed dword) $a [ init_points::i#10 init_points::pointXpos1_$0#0 init_points::pos#1 ] ( main:2::init_points:5 [ init_points::i#10 init_points::pointXpos1_$0#0 init_points::pos#1 ] ) always clobbers reg byte a +Statement [65] (byte*) init_points::pointYpos1_return#0 ← (byte*) init_points::pointXpos1_$0#0 + (byte/signed byte/word/signed word/dword/signed dword) 1 [ init_points::i#10 init_points::pos#1 init_points::pointYpos1_return#0 ] ( main:2::init_points:5 [ init_points::i#10 init_points::pos#1 init_points::pointYpos1_return#0 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:25 [ init_points::pos#1 ] +Statement [66] *((byte*) init_points::pointYpos1_return#0) ← (byte) init_points::pos#1 [ init_points::i#10 init_points::pos#1 ] ( main:2::init_points:5 [ init_points::i#10 init_points::pos#1 ] ) always clobbers reg byte a reg byte y +Removing always clobbered register reg byte y as potential for zp ZP_BYTE:25 [ init_points::pos#1 ] +Statement [67] (byte) init_points::pos#2 ← (byte) init_points::pos#1 + (byte/signed byte/word/signed word/dword/signed dword) $a [ init_points::i#10 init_points::pos#2 ] ( main:2::init_points:5 [ init_points::i#10 init_points::pos#2 ] ) always clobbers reg byte a reg byte x +Removing always clobbered register reg byte x as potential for zp ZP_BYTE:13 [ init_points::i#10 init_points::i#1 ] +Statement [69] if((byte) init_points::i#1!=(const byte) NUM_POINTS#0-(byte/signed byte/word/signed word/dword/signed dword) 1+(byte/signed byte/word/signed word/dword/signed dword) 1) goto init_points::@1 [ init_points::i#1 init_points::pos#2 ] ( main:2::init_points:5 [ init_points::i#1 init_points::pos#2 ] ) always clobbers reg byte a +Statement [12] (byte) print_points::getPoint1_$0#0 ← (byte) print_points::i#10 << (byte/signed byte/word/signed word/dword/signed dword) 1 [ print_points::i#10 print_char_cursor#45 print_line_cursor#24 print_points::getPoint1_$0#0 ] ( main:2::print_points:7 [ print_points::i#10 print_char_cursor#45 print_line_cursor#24 print_points::getPoint1_$0#0 ] ) always clobbers reg byte a +Statement [13] (byte*) print_points::pointXpos1_$0#0 ← (const byte[NUM_POINTS#0*SIZEOF_POINT#0]) points#0 + (byte) print_points::getPoint1_$0#0 [ print_points::i#10 print_char_cursor#45 print_line_cursor#24 print_points::pointXpos1_$0#0 ] ( main:2::print_points:7 [ print_points::i#10 print_char_cursor#45 print_line_cursor#24 print_points::pointXpos1_$0#0 ] ) always clobbers reg byte a +Statement [15] (byte) print_byte::b#0 ← *((byte*) print_points::pointXpos1_$0#0) [ print_points::i#10 print_char_cursor#45 print_line_cursor#24 print_points::pointXpos1_$0#0 print_byte::b#0 ] ( main:2::print_points:7 [ print_points::i#10 print_char_cursor#45 print_line_cursor#24 print_points::pointXpos1_$0#0 print_byte::b#0 ] ) always clobbers reg byte a reg byte y +Statement [19] (byte*) print_points::pointYpos1_return#0 ← (byte*) print_points::pointXpos1_$0#0 + (byte/signed byte/word/signed word/dword/signed dword) 1 [ print_points::i#10 print_line_cursor#24 print_points::pointYpos1_return#0 print_char_cursor#2 ] ( main:2::print_points:7 [ print_points::i#10 print_line_cursor#24 print_points::pointYpos1_return#0 print_char_cursor#2 ] ) always clobbers reg byte a +Statement [20] (byte) print_byte::b#1 ← *((byte*) print_points::pointYpos1_return#0) [ print_points::i#10 print_line_cursor#24 print_byte::b#1 print_char_cursor#2 ] ( main:2::print_points:7 [ print_points::i#10 print_line_cursor#24 print_byte::b#1 print_char_cursor#2 ] ) always clobbers reg byte a reg byte y +Statement [27] (byte*~) print_char_cursor#60 ← (byte*) print_line_cursor#1 [ print_points::i#1 print_char_cursor#60 print_line_cursor#1 ] ( main:2::print_points:7 [ print_points::i#1 print_char_cursor#60 print_line_cursor#1 ] ) always clobbers reg byte a +Statement [30] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#11 + (byte/signed byte/word/signed word/dword/signed dword) $28 [ print_line_cursor#1 print_char_cursor#29 ] ( main:2::print_points:7::print_ln:23 [ print_points::i#10 print_line_cursor#1 print_char_cursor#29 ] ) always clobbers reg byte a +Statement [31] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#29) goto print_ln::@1 [ print_line_cursor#1 print_char_cursor#29 ] ( main:2::print_points:7::print_ln:23 [ print_points::i#10 print_line_cursor#1 print_char_cursor#29 ] ) always clobbers reg byte a +Statement [34] (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4 [ print_byte::b#2 print_char_cursor#42 print_byte::$0 ] ( main:2::print_points:7::print_byte:16 [ print_points::i#10 print_line_cursor#24 print_points::pointXpos1_$0#0 print_byte::b#2 print_char_cursor#42 print_byte::$0 ] main:2::print_points:7::print_byte:21 [ print_points::i#10 print_line_cursor#24 print_byte::b#2 print_char_cursor#42 print_byte::$0 ] ) always clobbers reg byte a +Statement [37] (byte~) print_byte::$2 ← (byte) print_byte::b#2 & (byte/signed byte/word/signed word/dword/signed dword) $f [ print_char_cursor#29 print_byte::$2 ] ( main:2::print_points:7::print_byte:16 [ print_points::i#10 print_line_cursor#24 print_points::pointXpos1_$0#0 print_char_cursor#29 print_byte::$2 ] main:2::print_points:7::print_byte:21 [ print_points::i#10 print_line_cursor#24 print_char_cursor#29 print_byte::$2 ] ) always clobbers reg byte a +Statement [42] *((byte*) print_char_cursor#28) ← (byte) print_char::ch#2 [ print_char_cursor#28 ] ( main:2::print_points:7::print_byte:16::print_char:36 [ print_points::i#10 print_line_cursor#24 print_points::pointXpos1_$0#0 print_byte::b#2 print_char_cursor#28 ] main:2::print_points:7::print_byte:21::print_char:36 [ print_points::i#10 print_line_cursor#24 print_byte::b#2 print_char_cursor#28 ] main:2::print_points:7::print_byte:16::print_char:39 [ print_points::i#10 print_line_cursor#24 print_points::pointXpos1_$0#0 print_char_cursor#28 ] main:2::print_points:7::print_byte:21::print_char:39 [ print_points::i#10 print_line_cursor#24 print_char_cursor#28 ] ) always clobbers reg byte y +Statement [47] if(*((byte*) print_str::str#2)!=(byte) '@') goto print_str::@2 [ print_char_cursor#2 print_str::str#2 ] ( main:2::print_points:7::print_str:18 [ print_points::i#10 print_line_cursor#24 print_points::pointXpos1_$0#0 print_char_cursor#2 print_str::str#2 ] ) always clobbers reg byte a reg byte y +Statement [49] *((byte*) print_char_cursor#2) ← *((byte*) print_str::str#2) [ print_char_cursor#2 print_str::str#2 ] ( main:2::print_points:7::print_str:18 [ print_points::i#10 print_line_cursor#24 print_points::pointXpos1_$0#0 print_char_cursor#2 print_str::str#2 ] ) always clobbers reg byte a reg byte y +Statement [54] *((byte*) print_cls::sc#2) ← (byte) ' ' [ print_cls::sc#2 ] ( main:2::print_points:7::print_cls:10 [ print_cls::sc#2 ] ) always clobbers reg byte a reg byte y +Statement [56] if((byte*) print_cls::sc#1!=((byte*))(word/signed word/dword/signed dword) $400+(word/signed word/dword/signed dword) $3e8) goto print_cls::@1 [ print_cls::sc#1 ] ( main:2::print_points:7::print_cls:10 [ print_cls::sc#1 ] ) always clobbers reg byte a +Statement [60] (byte) init_points::getPoint1_$0#0 ← (byte) init_points::i#10 << (byte/signed byte/word/signed word/dword/signed dword) 1 [ init_points::i#10 init_points::pos#10 init_points::getPoint1_$0#0 ] ( main:2::init_points:5 [ init_points::i#10 init_points::pos#10 init_points::getPoint1_$0#0 ] ) always clobbers reg byte a +Statement [61] (byte*) init_points::pointXpos1_$0#0 ← (const byte[NUM_POINTS#0*SIZEOF_POINT#0]) points#0 + (byte) init_points::getPoint1_$0#0 [ init_points::i#10 init_points::pos#10 init_points::pointXpos1_$0#0 ] ( main:2::init_points:5 [ init_points::i#10 init_points::pos#10 init_points::pointXpos1_$0#0 ] ) always clobbers reg byte a +Statement [63] *((byte*) init_points::pointXpos1_$0#0) ← (byte) init_points::pos#10 [ init_points::i#10 init_points::pos#10 init_points::pointXpos1_$0#0 ] ( main:2::init_points:5 [ init_points::i#10 init_points::pos#10 init_points::pointXpos1_$0#0 ] ) always clobbers reg byte a reg byte y +Statement [64] (byte) init_points::pos#1 ← (byte) init_points::pos#10 + (byte/signed byte/word/signed word/dword/signed dword) $a [ init_points::i#10 init_points::pointXpos1_$0#0 init_points::pos#1 ] ( main:2::init_points:5 [ init_points::i#10 init_points::pointXpos1_$0#0 init_points::pos#1 ] ) always clobbers reg byte a reg byte x +Statement [65] (byte*) init_points::pointYpos1_return#0 ← (byte*) init_points::pointXpos1_$0#0 + (byte/signed byte/word/signed word/dword/signed dword) 1 [ init_points::i#10 init_points::pos#1 init_points::pointYpos1_return#0 ] ( main:2::init_points:5 [ init_points::i#10 init_points::pos#1 init_points::pointYpos1_return#0 ] ) always clobbers reg byte a +Statement [66] *((byte*) init_points::pointYpos1_return#0) ← (byte) init_points::pos#1 [ init_points::i#10 init_points::pos#1 ] ( main:2::init_points:5 [ init_points::i#10 init_points::pos#1 ] ) always clobbers reg byte a reg byte y +Statement [67] (byte) init_points::pos#2 ← (byte) init_points::pos#1 + (byte/signed byte/word/signed word/dword/signed dword) $a [ init_points::i#10 init_points::pos#2 ] ( main:2::init_points:5 [ init_points::i#10 init_points::pos#2 ] ) always clobbers reg byte a reg byte x +Statement [69] if((byte) init_points::i#1!=(const byte) NUM_POINTS#0-(byte/signed byte/word/signed word/dword/signed dword) 1+(byte/signed byte/word/signed word/dword/signed dword) 1) goto init_points::@1 [ init_points::i#1 init_points::pos#2 ] ( main:2::init_points:5 [ init_points::i#1 init_points::pos#2 ] ) always clobbers reg byte a +Potential registers zp ZP_BYTE:2 [ print_points::i#10 print_points::i#1 ] : zp ZP_BYTE:2 , reg byte x , +Potential registers zp ZP_WORD:3 [ print_line_cursor#11 print_line_cursor#24 print_line_cursor#1 ] : zp ZP_WORD:3 , +Potential registers zp ZP_BYTE:5 [ print_byte::b#2 print_byte::b#0 print_byte::b#1 ] : zp ZP_BYTE:5 , reg byte x , +Potential registers zp ZP_BYTE:6 [ print_char::ch#2 print_char::ch#0 print_char::ch#1 ] : zp ZP_BYTE:6 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_WORD:7 [ print_char_cursor#28 print_char_cursor#42 print_char_cursor#45 print_char_cursor#60 print_char_cursor#2 print_char_cursor#29 print_char_cursor#1 ] : zp ZP_WORD:7 , +Potential registers zp ZP_WORD:9 [ print_str::str#2 print_str::str#0 ] : zp ZP_WORD:9 , +Potential registers zp ZP_WORD:11 [ print_cls::sc#2 print_cls::sc#1 ] : zp ZP_WORD:11 , +Potential registers zp ZP_BYTE:13 [ init_points::i#10 init_points::i#1 ] : zp ZP_BYTE:13 , +Potential registers zp ZP_BYTE:14 [ init_points::pos#10 init_points::pos#2 ] : zp ZP_BYTE:14 , reg byte x , +Potential registers zp ZP_BYTE:15 [ print_points::getPoint1_$0#0 ] : zp ZP_BYTE:15 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_WORD:16 [ print_points::pointXpos1_$0#0 ] : zp ZP_WORD:16 , +Potential registers zp ZP_WORD:18 [ print_points::pointYpos1_return#0 ] : zp ZP_WORD:18 , +Potential registers zp ZP_BYTE:20 [ print_byte::$0 ] : zp ZP_BYTE:20 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:21 [ print_byte::$2 ] : zp ZP_BYTE:21 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:22 [ init_points::getPoint1_$0#0 ] : zp ZP_BYTE:22 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_WORD:23 [ init_points::pointXpos1_$0#0 ] : zp ZP_WORD:23 , +Potential registers zp ZP_BYTE:25 [ init_points::pos#1 ] : zp ZP_BYTE:25 , reg byte x , +Potential registers zp ZP_WORD:26 [ init_points::pointYpos1_return#0 ] : zp ZP_WORD:26 , + +REGISTER UPLIFT SCOPES +Uplift Scope [] 251.43: zp ZP_WORD:3 [ print_line_cursor#11 print_line_cursor#24 print_line_cursor#1 ] 191.23: zp ZP_WORD:7 [ print_char_cursor#28 print_char_cursor#42 print_char_cursor#45 print_char_cursor#60 print_char_cursor#2 print_char_cursor#29 print_char_cursor#1 ] +Uplift Scope [print_str] 303: zp ZP_WORD:9 [ print_str::str#2 print_str::str#0 ] +Uplift Scope [init_points] 22: zp ZP_BYTE:22 [ init_points::getPoint1_$0#0 ] 22: zp ZP_WORD:26 [ init_points::pointYpos1_return#0 ] 20.17: zp ZP_BYTE:13 [ init_points::i#10 init_points::i#1 ] 13.93: zp ZP_BYTE:14 [ init_points::pos#10 init_points::pos#2 ] 11: zp ZP_BYTE:25 [ init_points::pos#1 ] 8.25: zp ZP_WORD:23 [ init_points::pointXpos1_$0#0 ] +Uplift Scope [print_points] 22: zp ZP_BYTE:15 [ print_points::getPoint1_$0#0 ] 22: zp ZP_WORD:18 [ print_points::pointYpos1_return#0 ] 13.54: zp ZP_BYTE:2 [ print_points::i#10 print_points::i#1 ] 5.5: zp ZP_WORD:16 [ print_points::pointXpos1_$0#0 ] +Uplift Scope [print_byte] 50.5: zp ZP_BYTE:5 [ print_byte::b#2 print_byte::b#0 print_byte::b#1 ] 4: zp ZP_BYTE:20 [ print_byte::$0 ] 4: zp ZP_BYTE:21 [ print_byte::$2 ] +Uplift Scope [print_cls] 33: zp ZP_WORD:11 [ print_cls::sc#2 print_cls::sc#1 ] +Uplift Scope [print_char] 14: zp ZP_BYTE:6 [ print_char::ch#2 print_char::ch#0 print_char::ch#1 ] +Uplift Scope [print_ln] +Uplift Scope [main] + +Uplifting [] best 14895 combination zp ZP_WORD:3 [ print_line_cursor#11 print_line_cursor#24 print_line_cursor#1 ] zp ZP_WORD:7 [ print_char_cursor#28 print_char_cursor#42 print_char_cursor#45 print_char_cursor#60 print_char_cursor#2 print_char_cursor#29 print_char_cursor#1 ] +Uplifting [print_str] best 14895 combination zp ZP_WORD:9 [ print_str::str#2 print_str::str#0 ] +Uplifting [init_points] best 14705 combination reg byte a [ init_points::getPoint1_$0#0 ] zp ZP_WORD:26 [ init_points::pointYpos1_return#0 ] zp ZP_BYTE:13 [ init_points::i#10 init_points::i#1 ] reg byte x [ init_points::pos#10 init_points::pos#2 ] reg byte x [ init_points::pos#1 ] zp ZP_WORD:23 [ init_points::pointXpos1_$0#0 ] +Uplifting [print_points] best 14545 combination reg byte a [ print_points::getPoint1_$0#0 ] zp ZP_WORD:18 [ print_points::pointYpos1_return#0 ] reg byte x [ print_points::i#10 print_points::i#1 ] zp ZP_WORD:16 [ print_points::pointXpos1_$0#0 ] +Uplifting [print_byte] best 14537 combination zp ZP_BYTE:5 [ print_byte::b#2 print_byte::b#0 print_byte::b#1 ] reg byte a [ print_byte::$0 ] reg byte a [ print_byte::$2 ] +Uplifting [print_cls] best 14537 combination zp ZP_WORD:11 [ print_cls::sc#2 print_cls::sc#1 ] +Uplifting [print_char] best 14528 combination reg byte a [ print_char::ch#2 print_char::ch#0 print_char::ch#1 ] +Uplifting [print_ln] best 14528 combination +Uplifting [main] best 14528 combination +Attempting to uplift remaining variables inzp ZP_BYTE:5 [ print_byte::b#2 print_byte::b#0 print_byte::b#1 ] +Uplifting [print_byte] best 14528 combination zp ZP_BYTE:5 [ print_byte::b#2 print_byte::b#0 print_byte::b#1 ] +Attempting to uplift remaining variables inzp ZP_BYTE:13 [ init_points::i#10 init_points::i#1 ] +Uplifting [init_points] best 14528 combination zp ZP_BYTE:13 [ init_points::i#10 init_points::i#1 ] +Coalescing zero page register with common assignment [ zp ZP_WORD:16 [ print_points::pointXpos1_$0#0 ] ] with [ zp ZP_WORD:18 [ print_points::pointYpos1_return#0 ] ] - score: 1 +Coalescing zero page register with common assignment [ zp ZP_WORD:23 [ init_points::pointXpos1_$0#0 ] ] with [ zp ZP_WORD:26 [ init_points::pointYpos1_return#0 ] ] - score: 1 +Coalescing zero page register [ zp ZP_WORD:3 [ print_line_cursor#11 print_line_cursor#24 print_line_cursor#1 ] ] with [ zp ZP_WORD:11 [ print_cls::sc#2 print_cls::sc#1 ] ] +Coalescing zero page register [ zp ZP_WORD:3 [ print_line_cursor#11 print_line_cursor#24 print_line_cursor#1 print_cls::sc#2 print_cls::sc#1 ] ] with [ zp ZP_WORD:23 [ init_points::pointXpos1_$0#0 init_points::pointYpos1_return#0 ] ] +Coalescing zero page register [ zp ZP_BYTE:5 [ print_byte::b#2 print_byte::b#0 print_byte::b#1 ] ] with [ zp ZP_BYTE:13 [ init_points::i#10 init_points::i#1 ] ] +Allocated (was zp ZP_WORD:3) zp ZP_WORD:2 [ print_line_cursor#11 print_line_cursor#24 print_line_cursor#1 print_cls::sc#2 print_cls::sc#1 init_points::pointXpos1_$0#0 init_points::pointYpos1_return#0 ] +Allocated (was zp ZP_BYTE:5) zp ZP_BYTE:4 [ print_byte::b#2 print_byte::b#0 print_byte::b#1 init_points::i#10 init_points::i#1 ] +Allocated (was zp ZP_WORD:7) zp ZP_WORD:5 [ print_char_cursor#28 print_char_cursor#42 print_char_cursor#45 print_char_cursor#60 print_char_cursor#2 print_char_cursor#29 print_char_cursor#1 ] +Allocated (was zp ZP_WORD:9) zp ZP_WORD:7 [ print_str::str#2 print_str::str#0 ] +Allocated (was zp ZP_WORD:16) zp ZP_WORD:9 [ print_points::pointXpos1_$0#0 print_points::pointYpos1_return#0 ] + +ASSEMBLER BEFORE OPTIMIZATION +//SEG0 File Comments +// Implementing a semi-struct without the struct keyword by using pointer math and inline functions +// +// struct Point { +// byte xpos; // The x-position +// byte ypos; // The y-position +// }; +// Point[NUM_POINTS] points; +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels + // The size of a point + .const SIZEOF_POINT = 2 + // The number of points + .const NUM_POINTS = 4 + .label print_char_cursor = 5 + .label print_line_cursor = 2 +//SEG3 @begin +bbegin: +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 +//SEG5 @1 +b1: +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG9 @end +bend: +//SEG10 main +// Initialize some points and print them +main: { + //SEG11 [5] call init_points + //SEG12 [58] phi from main to init_points [phi:main->init_points] + init_points_from_main: + jsr init_points + //SEG13 [6] phi from main to main::@1 [phi:main->main::@1] + b1_from_main: + jmp b1 + //SEG14 main::@1 + b1: + //SEG15 [7] call print_points + //SEG16 [9] phi from main::@1 to print_points [phi:main::@1->print_points] + print_points_from_b1: + jsr print_points + jmp breturn + //SEG17 main::@return + breturn: + //SEG18 [8] return + rts +} +//SEG19 print_points +// Print points +print_points: { + .label pointXpos1__0 = 9 + .label pointYpos1_return = 9 + //SEG20 [10] call print_cls + //SEG21 [52] phi from print_points to print_cls [phi:print_points->print_cls] + print_cls_from_print_points: + jsr print_cls + //SEG22 [11] phi from print_points to print_points::@1 [phi:print_points->print_points::@1] + b1_from_print_points: + //SEG23 [11] phi (byte*) print_line_cursor#24 = ((byte*))(word/signed word/dword/signed dword) $400 [phi:print_points->print_points::@1#0] -- pbuz1=pbuc1 + lda #<$400 + sta print_line_cursor + lda #>$400 + sta print_line_cursor+1 + //SEG24 [11] phi (byte*) print_char_cursor#45 = ((byte*))(word/signed word/dword/signed dword) $400 [phi:print_points->print_points::@1#1] -- pbuz1=pbuc1 + lda #<$400 + sta print_char_cursor + lda #>$400 + sta print_char_cursor+1 + //SEG25 [11] phi (byte) print_points::i#10 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:print_points->print_points::@1#2] -- vbuxx=vbuc1 + ldx #0 + jmp b1 + //SEG26 print_points::@1 + b1: + jmp getPoint1 + //SEG27 print_points::getPoint1 + getPoint1: + //SEG28 [12] (byte) print_points::getPoint1_$0#0 ← (byte) print_points::i#10 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuaa=vbuxx_rol_1 + txa + asl + //SEG29 [13] (byte*) print_points::pointXpos1_$0#0 ← (const byte[NUM_POINTS#0*SIZEOF_POINT#0]) points#0 + (byte) print_points::getPoint1_$0#0 -- pbuz1=pbuc1_plus_vbuaa + clc + adc #points + adc #0 + sta pointXpos1__0+1 + //SEG30 [14] phi from print_points::getPoint1 to print_points::pointXpos1 [phi:print_points::getPoint1->print_points::pointXpos1] + pointXpos1_from_getPoint1: + jmp pointXpos1 + //SEG31 print_points::pointXpos1 + pointXpos1: + jmp b2 + //SEG32 print_points::@2 + b2: + //SEG33 [15] (byte) print_byte::b#0 ← *((byte*) print_points::pointXpos1_$0#0) -- vbuz1=_deref_pbuz2 + ldy #0 + lda (pointXpos1__0),y + sta print_byte.b + //SEG34 [16] call print_byte + //SEG35 [33] phi from print_points::@2 to print_byte [phi:print_points::@2->print_byte] + print_byte_from_b2: + //SEG36 [33] phi (byte*) print_char_cursor#42 = (byte*) print_char_cursor#45 [phi:print_points::@2->print_byte#0] -- register_copy + //SEG37 [33] phi (byte) print_byte::b#2 = (byte) print_byte::b#0 [phi:print_points::@2->print_byte#1] -- register_copy + jsr print_byte + //SEG38 [17] phi from print_points::@2 to print_points::@4 [phi:print_points::@2->print_points::@4] + b4_from_b2: + jmp b4 + //SEG39 print_points::@4 + b4: + //SEG40 [18] call print_str + //SEG41 [45] phi from print_points::@4 to print_str [phi:print_points::@4->print_str] + print_str_from_b4: + jsr print_str + jmp pointYpos1 + //SEG42 print_points::pointYpos1 + pointYpos1: + //SEG43 [19] (byte*) print_points::pointYpos1_return#0 ← (byte*) print_points::pointXpos1_$0#0 + (byte/signed byte/word/signed word/dword/signed dword) 1 -- pbuz1=pbuz1_plus_1 + inc pointYpos1_return + bne !+ + inc pointYpos1_return+1 + !: + jmp b3 + //SEG44 print_points::@3 + b3: + //SEG45 [20] (byte) print_byte::b#1 ← *((byte*) print_points::pointYpos1_return#0) -- vbuz1=_deref_pbuz2 + ldy #0 + lda (pointYpos1_return),y + sta print_byte.b + //SEG46 [21] call print_byte + //SEG47 [33] phi from print_points::@3 to print_byte [phi:print_points::@3->print_byte] + print_byte_from_b3: + //SEG48 [33] phi (byte*) print_char_cursor#42 = (byte*) print_char_cursor#2 [phi:print_points::@3->print_byte#0] -- register_copy + //SEG49 [33] phi (byte) print_byte::b#2 = (byte) print_byte::b#1 [phi:print_points::@3->print_byte#1] -- register_copy + jsr print_byte + //SEG50 [22] phi from print_points::@3 to print_points::@5 [phi:print_points::@3->print_points::@5] + b5_from_b3: + jmp b5 + //SEG51 print_points::@5 + b5: + //SEG52 [23] call print_ln + //SEG53 [28] phi from print_points::@5 to print_ln [phi:print_points::@5->print_ln] + print_ln_from_b5: + jsr print_ln + jmp b6 + //SEG54 print_points::@6 + b6: + //SEG55 [24] (byte) print_points::i#1 ← ++ (byte) print_points::i#10 -- vbuxx=_inc_vbuxx + inx + //SEG56 [25] if((byte) print_points::i#1!=(const byte) NUM_POINTS#0-(byte/signed byte/word/signed word/dword/signed dword) 1+(byte/signed byte/word/signed word/dword/signed dword) 1) goto print_points::@7 -- vbuxx_neq_vbuc1_then_la1 + cpx #NUM_POINTS-1+1 + bne b7 + jmp breturn + //SEG57 print_points::@return + breturn: + //SEG58 [26] return + rts + //SEG59 print_points::@7 + b7: + //SEG60 [27] (byte*~) print_char_cursor#60 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 + lda print_line_cursor + sta print_char_cursor + lda print_line_cursor+1 + sta print_char_cursor+1 + //SEG61 [11] phi from print_points::@7 to print_points::@1 [phi:print_points::@7->print_points::@1] + b1_from_b7: + //SEG62 [11] phi (byte*) print_line_cursor#24 = (byte*) print_line_cursor#1 [phi:print_points::@7->print_points::@1#0] -- register_copy + //SEG63 [11] phi (byte*) print_char_cursor#45 = (byte*~) print_char_cursor#60 [phi:print_points::@7->print_points::@1#1] -- register_copy + //SEG64 [11] phi (byte) print_points::i#10 = (byte) print_points::i#1 [phi:print_points::@7->print_points::@1#2] -- register_copy + jmp b1 + str: .text " @" +} +//SEG65 print_ln +// Print a newline +print_ln: { + //SEG66 [29] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] + b1_from_print_ln: + b1_from_b1: + //SEG67 [29] phi (byte*) print_line_cursor#11 = (byte*) print_line_cursor#24 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy + jmp b1 + //SEG68 print_ln::@1 + b1: + //SEG69 [30] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#11 + (byte/signed byte/word/signed word/dword/signed dword) $28 -- pbuz1=pbuz1_plus_vbuc1 + lda #$28 + clc + adc print_line_cursor + sta print_line_cursor + bcc !+ + inc print_line_cursor+1 + !: + //SEG70 [31] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#29) goto print_ln::@1 -- pbuz1_lt_pbuz2_then_la1 + lda print_line_cursor+1 + cmp print_char_cursor+1 + bcc b1_from_b1 + bne !+ + lda print_line_cursor + cmp print_char_cursor + bcc b1_from_b1 + !: + jmp breturn + //SEG71 print_ln::@return + breturn: + //SEG72 [32] return + rts +} +//SEG73 print_byte +// Print a byte as HEX +// print_byte(byte zeropage(4) b) +print_byte: { + .label b = 4 + //SEG74 [34] (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuz1_ror_4 + lda b + lsr + lsr + lsr + lsr + //SEG75 [35] (byte) print_char::ch#0 ← *((const byte[]) print_hextab#0 + (byte~) print_byte::$0) -- vbuaa=pbuc1_derefidx_vbuaa + tay + lda print_hextab,y + //SEG76 [36] call print_char + //SEG77 [41] phi from print_byte to print_char [phi:print_byte->print_char] + print_char_from_print_byte: + //SEG78 [41] phi (byte*) print_char_cursor#28 = (byte*) print_char_cursor#42 [phi:print_byte->print_char#0] -- register_copy + //SEG79 [41] phi (byte) print_char::ch#2 = (byte) print_char::ch#0 [phi:print_byte->print_char#1] -- register_copy + jsr print_char + jmp b1 + //SEG80 print_byte::@1 + b1: + //SEG81 [37] (byte~) print_byte::$2 ← (byte) print_byte::b#2 & (byte/signed byte/word/signed word/dword/signed dword) $f -- vbuaa=vbuz1_band_vbuc1 + lda #$f + and b + //SEG82 [38] (byte) print_char::ch#1 ← *((const byte[]) print_hextab#0 + (byte~) print_byte::$2) -- vbuaa=pbuc1_derefidx_vbuaa + tay + lda print_hextab,y + //SEG83 [39] call print_char + //SEG84 [41] phi from print_byte::@1 to print_char [phi:print_byte::@1->print_char] + print_char_from_b1: + //SEG85 [41] phi (byte*) print_char_cursor#28 = (byte*) print_char_cursor#29 [phi:print_byte::@1->print_char#0] -- register_copy + //SEG86 [41] phi (byte) print_char::ch#2 = (byte) print_char::ch#1 [phi:print_byte::@1->print_char#1] -- register_copy + jsr print_char + jmp breturn + //SEG87 print_byte::@return + breturn: + //SEG88 [40] return + rts +} +//SEG89 print_char +// Print a single char +// print_char(byte register(A) ch) +print_char: { + //SEG90 [42] *((byte*) print_char_cursor#28) ← (byte) print_char::ch#2 -- _deref_pbuz1=vbuaa + ldy #0 + sta (print_char_cursor),y + //SEG91 [43] (byte*) print_char_cursor#29 ← ++ (byte*) print_char_cursor#28 -- pbuz1=_inc_pbuz1 + inc print_char_cursor + bne !+ + inc print_char_cursor+1 + !: + jmp breturn + //SEG92 print_char::@return + breturn: + //SEG93 [44] return + rts +} +//SEG94 print_str +// Print a zero-terminated string +// print_str(byte* zeropage(7) str) +print_str: { + .label str = 7 + //SEG95 [46] phi from print_str to print_str::@1 [phi:print_str->print_str::@1] + b1_from_print_str: + //SEG96 [46] phi (byte*) print_char_cursor#2 = (byte*) print_char_cursor#29 [phi:print_str->print_str::@1#0] -- register_copy + //SEG97 [46] phi (byte*) print_str::str#2 = (const string) print_points::str [phi:print_str->print_str::@1#1] -- pbuz1=pbuc1 + lda #print_points.str + sta str+1 + jmp b1 + //SEG98 print_str::@1 + b1: + //SEG99 [47] if(*((byte*) print_str::str#2)!=(byte) '@') goto print_str::@2 -- _deref_pbuz1_neq_vbuc1_then_la1 + ldy #0 + lda (str),y + cmp #'@' + bne b2 + jmp breturn + //SEG100 print_str::@return + breturn: + //SEG101 [48] return + rts + //SEG102 print_str::@2 + b2: + //SEG103 [49] *((byte*) print_char_cursor#2) ← *((byte*) print_str::str#2) -- _deref_pbuz1=_deref_pbuz2 + ldy #0 + lda (str),y + ldy #0 + sta (print_char_cursor),y + //SEG104 [50] (byte*) print_char_cursor#1 ← ++ (byte*) print_char_cursor#2 -- pbuz1=_inc_pbuz1 + inc print_char_cursor + bne !+ + inc print_char_cursor+1 + !: + //SEG105 [51] (byte*) print_str::str#0 ← ++ (byte*) print_str::str#2 -- pbuz1=_inc_pbuz1 + inc str + bne !+ + inc str+1 + !: + //SEG106 [46] phi from print_str::@2 to print_str::@1 [phi:print_str::@2->print_str::@1] + b1_from_b2: + //SEG107 [46] phi (byte*) print_char_cursor#2 = (byte*) print_char_cursor#1 [phi:print_str::@2->print_str::@1#0] -- register_copy + //SEG108 [46] phi (byte*) print_str::str#2 = (byte*) print_str::str#0 [phi:print_str::@2->print_str::@1#1] -- register_copy + jmp b1 +} +//SEG109 print_cls +// Clear the screen. Also resets current line/char cursor. +print_cls: { + .label sc = 2 + //SEG110 [53] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] + b1_from_print_cls: + //SEG111 [53] phi (byte*) print_cls::sc#2 = ((byte*))(word/signed word/dword/signed dword) $400 [phi:print_cls->print_cls::@1#0] -- pbuz1=pbuc1 + lda #<$400 + sta sc + lda #>$400 + sta sc+1 + jmp b1 + //SEG112 [53] phi from print_cls::@1 to print_cls::@1 [phi:print_cls::@1->print_cls::@1] + b1_from_b1: + //SEG113 [53] phi (byte*) print_cls::sc#2 = (byte*) print_cls::sc#1 [phi:print_cls::@1->print_cls::@1#0] -- register_copy + jmp b1 + //SEG114 print_cls::@1 + b1: + //SEG115 [54] *((byte*) print_cls::sc#2) ← (byte) ' ' -- _deref_pbuz1=vbuc1 + lda #' ' + ldy #0 + sta (sc),y + //SEG116 [55] (byte*) print_cls::sc#1 ← ++ (byte*) print_cls::sc#2 -- pbuz1=_inc_pbuz1 + inc sc + bne !+ + inc sc+1 + !: + //SEG117 [56] if((byte*) print_cls::sc#1!=((byte*))(word/signed word/dword/signed dword) $400+(word/signed word/dword/signed dword) $3e8) goto print_cls::@1 -- pbuz1_neq_pbuc1_then_la1 + lda sc+1 + cmp #>$400+$3e8 + bne b1_from_b1 + lda sc + cmp #<$400+$3e8 + bne b1_from_b1 + jmp breturn + //SEG118 print_cls::@return + breturn: + //SEG119 [57] return + rts +} +//SEG120 init_points +// Initialize points +init_points: { + .label pointXpos1__0 = 2 + .label pointYpos1_return = 2 + .label i = 4 + //SEG121 [59] phi from init_points to init_points::@1 [phi:init_points->init_points::@1] + b1_from_init_points: + //SEG122 [59] phi (byte) init_points::pos#10 = (byte/signed byte/word/signed word/dword/signed dword) $a [phi:init_points->init_points::@1#0] -- vbuxx=vbuc1 + ldx #$a + //SEG123 [59] phi (byte) init_points::i#10 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:init_points->init_points::@1#1] -- vbuz1=vbuc1 + lda #0 + sta i + jmp b1 + //SEG124 [59] phi from init_points::@3 to init_points::@1 [phi:init_points::@3->init_points::@1] + b1_from_b3: + //SEG125 [59] phi (byte) init_points::pos#10 = (byte) init_points::pos#2 [phi:init_points::@3->init_points::@1#0] -- register_copy + //SEG126 [59] phi (byte) init_points::i#10 = (byte) init_points::i#1 [phi:init_points::@3->init_points::@1#1] -- register_copy + jmp b1 + //SEG127 init_points::@1 + b1: + jmp getPoint1 + //SEG128 init_points::getPoint1 + getPoint1: + //SEG129 [60] (byte) init_points::getPoint1_$0#0 ← (byte) init_points::i#10 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuaa=vbuz1_rol_1 + lda i + asl + //SEG130 [61] (byte*) init_points::pointXpos1_$0#0 ← (const byte[NUM_POINTS#0*SIZEOF_POINT#0]) points#0 + (byte) init_points::getPoint1_$0#0 -- pbuz1=pbuc1_plus_vbuaa + clc + adc #points + adc #0 + sta pointXpos1__0+1 + //SEG131 [62] phi from init_points::getPoint1 to init_points::pointXpos1 [phi:init_points::getPoint1->init_points::pointXpos1] + pointXpos1_from_getPoint1: + jmp pointXpos1 + //SEG132 init_points::pointXpos1 + pointXpos1: + jmp b2 + //SEG133 init_points::@2 + b2: + //SEG134 [63] *((byte*) init_points::pointXpos1_$0#0) ← (byte) init_points::pos#10 -- _deref_pbuz1=vbuxx + txa + ldy #0 + sta (pointXpos1__0),y + //SEG135 [64] (byte) init_points::pos#1 ← (byte) init_points::pos#10 + (byte/signed byte/word/signed word/dword/signed dword) $a -- vbuxx=vbuxx_plus_vbuc1 + txa + axs #-[$a] + jmp pointYpos1 + //SEG136 init_points::pointYpos1 + pointYpos1: + //SEG137 [65] (byte*) init_points::pointYpos1_return#0 ← (byte*) init_points::pointXpos1_$0#0 + (byte/signed byte/word/signed word/dword/signed dword) 1 -- pbuz1=pbuz1_plus_1 + inc pointYpos1_return + bne !+ + inc pointYpos1_return+1 + !: + jmp b3 + //SEG138 init_points::@3 + b3: + //SEG139 [66] *((byte*) init_points::pointYpos1_return#0) ← (byte) init_points::pos#1 -- _deref_pbuz1=vbuxx + txa + ldy #0 + sta (pointYpos1_return),y + //SEG140 [67] (byte) init_points::pos#2 ← (byte) init_points::pos#1 + (byte/signed byte/word/signed word/dword/signed dword) $a -- vbuxx=vbuxx_plus_vbuc1 + txa + axs #-[$a] + //SEG141 [68] (byte) init_points::i#1 ← ++ (byte) init_points::i#10 -- vbuz1=_inc_vbuz1 + inc i + //SEG142 [69] if((byte) init_points::i#1!=(const byte) NUM_POINTS#0-(byte/signed byte/word/signed word/dword/signed dword) 1+(byte/signed byte/word/signed word/dword/signed dword) 1) goto init_points::@1 -- vbuz1_neq_vbuc1_then_la1 + lda #NUM_POINTS-1+1 + cmp i + bne b1_from_b3 + jmp breturn + //SEG143 init_points::@return + breturn: + //SEG144 [70] return + rts +} + print_hextab: .text "0123456789abcdef" + // All points + points: .fill NUM_POINTS*SIZEOF_POINT, 0 + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp b1 +Removing instruction jmp bend +Removing instruction jmp b1 +Removing instruction jmp breturn +Removing instruction jmp b1 +Removing instruction jmp getPoint1 +Removing instruction jmp pointXpos1 +Removing instruction jmp b2 +Removing instruction jmp b4 +Removing instruction jmp pointYpos1 +Removing instruction jmp b3 +Removing instruction jmp b5 +Removing instruction jmp b6 +Removing instruction jmp breturn +Removing instruction jmp b1 +Removing instruction jmp breturn +Removing instruction jmp b1 +Removing instruction jmp breturn +Removing instruction jmp breturn +Removing instruction jmp b1 +Removing instruction jmp breturn +Removing instruction jmp b1 +Removing instruction jmp breturn +Removing instruction jmp b1 +Removing instruction jmp getPoint1 +Removing instruction jmp pointXpos1 +Removing instruction jmp b2 +Removing instruction jmp pointYpos1 +Removing instruction jmp b3 +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction ldy #0 +Succesful ASM optimization Pass5UnnecesaryLoadElimination +Replacing label b1_from_b1 with b1 +Replacing label b1_from_b1 with b1 +Replacing label b1_from_b1 with b1 +Replacing label b1_from_b1 with b1 +Replacing label b1_from_b3 with b1 +Removing instruction b1_from_bbegin: +Removing instruction b1: +Removing instruction main_from_b1: +Removing instruction bend_from_b1: +Removing instruction b1_from_main: +Removing instruction print_points_from_b1: +Removing instruction getPoint1: +Removing instruction pointXpos1_from_getPoint1: +Removing instruction pointXpos1: +Removing instruction b4_from_b2: +Removing instruction print_str_from_b4: +Removing instruction b5_from_b3: +Removing instruction print_ln_from_b5: +Removing instruction b1_from_print_ln: +Removing instruction b1_from_b1: +Removing instruction b1_from_b1: +Removing instruction b1_from_b3: +Removing instruction getPoint1: +Removing instruction pointXpos1_from_getPoint1: +Removing instruction pointXpos1: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction bend: +Removing instruction init_points_from_main: +Removing instruction b1: +Removing instruction breturn: +Removing instruction print_cls_from_print_points: +Removing instruction b1_from_print_points: +Removing instruction b2: +Removing instruction print_byte_from_b2: +Removing instruction b4: +Removing instruction pointYpos1: +Removing instruction b3: +Removing instruction print_byte_from_b3: +Removing instruction b5: +Removing instruction b6: +Removing instruction breturn: +Removing instruction b1_from_b7: +Removing instruction breturn: +Removing instruction print_char_from_print_byte: +Removing instruction b1: +Removing instruction print_char_from_b1: +Removing instruction breturn: +Removing instruction breturn: +Removing instruction b1_from_print_str: +Removing instruction breturn: +Removing instruction b1_from_b2: +Removing instruction b1_from_print_cls: +Removing instruction breturn: +Removing instruction b1_from_init_points: +Removing instruction b2: +Removing instruction pointYpos1: +Removing instruction b3: +Removing instruction breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Updating BasicUpstart to call main directly +Removing instruction jsr main +Succesful ASM optimization Pass5SkipBegin +Removing instruction jmp b1 +Removing instruction jmp b1 +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction bbegin: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +(label) @1 +(label) @begin +(label) @end +(byte) NUM_POINTS +(const byte) NUM_POINTS#0 NUM_POINTS = (byte/signed byte/word/signed word/dword/signed dword) 4 +(byte) SIZEOF_POINT +(const byte) SIZEOF_POINT#0 SIZEOF_POINT = (byte/signed byte/word/signed word/dword/signed dword) 2 +(void()) init_points() +(label) init_points::@1 +(label) init_points::@2 +(label) init_points::@3 +(label) init_points::@return +(label) init_points::getPoint1 +(byte~) init_points::getPoint1_$0 +(byte) init_points::getPoint1_$0#0 reg byte a 22.0 +(byte*~) init_points::getPoint1_$1 +(byte) init_points::getPoint1_idx +(byte*) init_points::getPoint1_return +(byte) init_points::i +(byte) init_points::i#1 i zp ZP_BYTE:4 16.5 +(byte) init_points::i#10 i zp ZP_BYTE:4 3.666666666666667 +(byte*) init_points::point +(label) init_points::pointXpos1 +(byte*~) init_points::pointXpos1_$0 +(byte*) init_points::pointXpos1_$0#0 pointXpos1_$0 zp ZP_WORD:2 8.25 +(byte*~) init_points::pointXpos1_$1 +(byte*) init_points::pointXpos1_point +(byte*) init_points::pointXpos1_return +(label) init_points::pointYpos1 +(byte*~) init_points::pointYpos1_$0 +(byte*~) init_points::pointYpos1_$1 +(byte*) init_points::pointYpos1_point +(byte*) init_points::pointYpos1_return +(byte*) init_points::pointYpos1_return#0 pointYpos1_return zp ZP_WORD:2 22.0 +(byte) init_points::pos +(byte) init_points::pos#1 reg byte x 11.0 +(byte) init_points::pos#10 reg byte x 6.6000000000000005 +(byte) init_points::pos#2 reg byte x 7.333333333333333 +(void()) main() +(label) main::@1 +(label) main::@return +(byte[NUM_POINTS#0*SIZEOF_POINT#0]) points +(const byte[NUM_POINTS#0*SIZEOF_POINT#0]) points#0 points = { fill( NUM_POINTS#0*SIZEOF_POINT#0, 0) } +(void()) print_byte((byte) print_byte::b) +(byte~) print_byte::$0 reg byte a 4.0 +(byte~) print_byte::$2 reg byte a 4.0 +(label) print_byte::@1 +(label) print_byte::@return +(byte) print_byte::b +(byte) print_byte::b#0 b zp ZP_BYTE:4 22.0 +(byte) print_byte::b#1 b zp ZP_BYTE:4 22.0 +(byte) print_byte::b#2 b zp ZP_BYTE:4 6.5 +(void()) print_char((byte) print_char::ch) +(label) print_char::@return +(byte) print_char::ch +(byte) print_char::ch#0 reg byte a 4.0 +(byte) print_char::ch#1 reg byte a 4.0 +(byte) print_char::ch#2 reg byte a 6.0 +(byte*) print_char_cursor +(byte*) print_char_cursor#1 print_char_cursor zp ZP_WORD:5 101.0 +(byte*) print_char_cursor#2 print_char_cursor zp ZP_WORD:5 45.142857142857146 +(byte*) print_char_cursor#28 print_char_cursor zp ZP_WORD:5 4.0 +(byte*) print_char_cursor#29 print_char_cursor zp ZP_WORD:5 6.6875 +(byte*) print_char_cursor#42 print_char_cursor zp ZP_WORD:5 8.0 +(byte*) print_char_cursor#45 print_char_cursor zp ZP_WORD:5 4.4 +(byte*~) print_char_cursor#60 print_char_cursor zp ZP_WORD:5 22.0 +(void()) print_cls() +(label) print_cls::@1 +(label) print_cls::@return +(byte*) print_cls::sc +(byte*) print_cls::sc#1 sc zp ZP_WORD:2 16.5 +(byte*) print_cls::sc#2 sc zp ZP_WORD:2 16.5 +(byte[]) print_hextab +(const byte[]) print_hextab#0 print_hextab = (string) "0123456789abcdef" +(byte*) print_line_cursor +(byte*) print_line_cursor#1 print_line_cursor zp ZP_WORD:2 46.42857142857143 +(byte*) print_line_cursor#11 print_line_cursor zp ZP_WORD:2 204.0 +(byte*) print_line_cursor#24 print_line_cursor zp ZP_WORD:2 1.0 +(void()) print_ln() +(label) print_ln::@1 +(label) print_ln::@return +(void()) print_points() +(label) print_points::@1 +(label) print_points::@2 +(label) print_points::@3 +(label) print_points::@4 +(label) print_points::@5 +(label) print_points::@6 +(label) print_points::@7 +(label) print_points::@return +(label) print_points::getPoint1 +(byte~) print_points::getPoint1_$0 +(byte) print_points::getPoint1_$0#0 reg byte a 22.0 +(byte*~) print_points::getPoint1_$1 +(byte) print_points::getPoint1_idx +(byte*) print_points::getPoint1_return +(byte) print_points::i +(byte) print_points::i#1 reg byte x 11.0 +(byte) print_points::i#10 reg byte x 2.5384615384615383 +(byte*) print_points::point +(label) print_points::pointXpos1 +(byte*~) print_points::pointXpos1_$0 +(byte*) print_points::pointXpos1_$0#0 pointXpos1_$0 zp ZP_WORD:9 5.5 +(byte*~) print_points::pointXpos1_$1 +(byte*) print_points::pointXpos1_point +(byte*) print_points::pointXpos1_return +(label) print_points::pointYpos1 +(byte*~) print_points::pointYpos1_$0 +(byte*~) print_points::pointYpos1_$1 +(byte*) print_points::pointYpos1_point +(byte*) print_points::pointYpos1_return +(byte*) print_points::pointYpos1_return#0 pointYpos1_return zp ZP_WORD:9 22.0 +(const string) print_points::str str = (string) " @" +(byte*) print_screen +(void()) print_str((byte*) print_str::str) +(label) print_str::@1 +(label) print_str::@2 +(label) print_str::@return +(byte*) print_str::str +(byte*) print_str::str#0 str zp ZP_WORD:7 202.0 +(byte*) print_str::str#2 str zp ZP_WORD:7 101.0 + +reg byte x [ print_points::i#10 print_points::i#1 ] +zp ZP_WORD:2 [ print_line_cursor#11 print_line_cursor#24 print_line_cursor#1 print_cls::sc#2 print_cls::sc#1 init_points::pointXpos1_$0#0 init_points::pointYpos1_return#0 ] +zp ZP_BYTE:4 [ print_byte::b#2 print_byte::b#0 print_byte::b#1 init_points::i#10 init_points::i#1 ] +reg byte a [ print_char::ch#2 print_char::ch#0 print_char::ch#1 ] +zp ZP_WORD:5 [ print_char_cursor#28 print_char_cursor#42 print_char_cursor#45 print_char_cursor#60 print_char_cursor#2 print_char_cursor#29 print_char_cursor#1 ] +zp ZP_WORD:7 [ print_str::str#2 print_str::str#0 ] +reg byte x [ init_points::pos#10 init_points::pos#2 ] +reg byte a [ print_points::getPoint1_$0#0 ] +zp ZP_WORD:9 [ print_points::pointXpos1_$0#0 print_points::pointYpos1_return#0 ] +reg byte a [ print_byte::$0 ] +reg byte a [ print_byte::$2 ] +reg byte a [ init_points::getPoint1_$0#0 ] +reg byte x [ init_points::pos#1 ] + + +FINAL ASSEMBLER +Score: 12415 + +//SEG0 File Comments +// Implementing a semi-struct without the struct keyword by using pointer math and inline functions +// +// struct Point { +// byte xpos; // The x-position +// byte ypos; // The y-position +// }; +// Point[NUM_POINTS] points; +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG2 Global Constants & labels + // The size of a point + .const SIZEOF_POINT = 2 + // The number of points + .const NUM_POINTS = 4 + .label print_char_cursor = 5 + .label print_line_cursor = 2 +//SEG3 @begin +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +//SEG5 @1 +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +//SEG9 @end +//SEG10 main +// Initialize some points and print them +main: { + //SEG11 [5] call init_points + //SEG12 [58] phi from main to init_points [phi:main->init_points] + jsr init_points + //SEG13 [6] phi from main to main::@1 [phi:main->main::@1] + //SEG14 main::@1 + //SEG15 [7] call print_points + //SEG16 [9] phi from main::@1 to print_points [phi:main::@1->print_points] + jsr print_points + //SEG17 main::@return + //SEG18 [8] return + rts +} +//SEG19 print_points +// Print points +print_points: { + .label pointXpos1__0 = 9 + .label pointYpos1_return = 9 + //SEG20 [10] call print_cls + //SEG21 [52] phi from print_points to print_cls [phi:print_points->print_cls] + jsr print_cls + //SEG22 [11] phi from print_points to print_points::@1 [phi:print_points->print_points::@1] + //SEG23 [11] phi (byte*) print_line_cursor#24 = ((byte*))(word/signed word/dword/signed dword) $400 [phi:print_points->print_points::@1#0] -- pbuz1=pbuc1 + lda #<$400 + sta print_line_cursor + lda #>$400 + sta print_line_cursor+1 + //SEG24 [11] phi (byte*) print_char_cursor#45 = ((byte*))(word/signed word/dword/signed dword) $400 [phi:print_points->print_points::@1#1] -- pbuz1=pbuc1 + lda #<$400 + sta print_char_cursor + lda #>$400 + sta print_char_cursor+1 + //SEG25 [11] phi (byte) print_points::i#10 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:print_points->print_points::@1#2] -- vbuxx=vbuc1 + ldx #0 + //SEG26 print_points::@1 + b1: + //SEG27 print_points::getPoint1 + //SEG28 [12] (byte) print_points::getPoint1_$0#0 ← (byte) print_points::i#10 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuaa=vbuxx_rol_1 + txa + asl + //SEG29 [13] (byte*) print_points::pointXpos1_$0#0 ← (const byte[NUM_POINTS#0*SIZEOF_POINT#0]) points#0 + (byte) print_points::getPoint1_$0#0 -- pbuz1=pbuc1_plus_vbuaa + clc + adc #points + adc #0 + sta pointXpos1__0+1 + //SEG30 [14] phi from print_points::getPoint1 to print_points::pointXpos1 [phi:print_points::getPoint1->print_points::pointXpos1] + //SEG31 print_points::pointXpos1 + //SEG32 print_points::@2 + //SEG33 [15] (byte) print_byte::b#0 ← *((byte*) print_points::pointXpos1_$0#0) -- vbuz1=_deref_pbuz2 + ldy #0 + lda (pointXpos1__0),y + sta print_byte.b + //SEG34 [16] call print_byte + //SEG35 [33] phi from print_points::@2 to print_byte [phi:print_points::@2->print_byte] + //SEG36 [33] phi (byte*) print_char_cursor#42 = (byte*) print_char_cursor#45 [phi:print_points::@2->print_byte#0] -- register_copy + //SEG37 [33] phi (byte) print_byte::b#2 = (byte) print_byte::b#0 [phi:print_points::@2->print_byte#1] -- register_copy + jsr print_byte + //SEG38 [17] phi from print_points::@2 to print_points::@4 [phi:print_points::@2->print_points::@4] + //SEG39 print_points::@4 + //SEG40 [18] call print_str + //SEG41 [45] phi from print_points::@4 to print_str [phi:print_points::@4->print_str] + jsr print_str + //SEG42 print_points::pointYpos1 + //SEG43 [19] (byte*) print_points::pointYpos1_return#0 ← (byte*) print_points::pointXpos1_$0#0 + (byte/signed byte/word/signed word/dword/signed dword) 1 -- pbuz1=pbuz1_plus_1 + inc pointYpos1_return + bne !+ + inc pointYpos1_return+1 + !: + //SEG44 print_points::@3 + //SEG45 [20] (byte) print_byte::b#1 ← *((byte*) print_points::pointYpos1_return#0) -- vbuz1=_deref_pbuz2 + ldy #0 + lda (pointYpos1_return),y + sta print_byte.b + //SEG46 [21] call print_byte + //SEG47 [33] phi from print_points::@3 to print_byte [phi:print_points::@3->print_byte] + //SEG48 [33] phi (byte*) print_char_cursor#42 = (byte*) print_char_cursor#2 [phi:print_points::@3->print_byte#0] -- register_copy + //SEG49 [33] phi (byte) print_byte::b#2 = (byte) print_byte::b#1 [phi:print_points::@3->print_byte#1] -- register_copy + jsr print_byte + //SEG50 [22] phi from print_points::@3 to print_points::@5 [phi:print_points::@3->print_points::@5] + //SEG51 print_points::@5 + //SEG52 [23] call print_ln + //SEG53 [28] phi from print_points::@5 to print_ln [phi:print_points::@5->print_ln] + jsr print_ln + //SEG54 print_points::@6 + //SEG55 [24] (byte) print_points::i#1 ← ++ (byte) print_points::i#10 -- vbuxx=_inc_vbuxx + inx + //SEG56 [25] if((byte) print_points::i#1!=(const byte) NUM_POINTS#0-(byte/signed byte/word/signed word/dword/signed dword) 1+(byte/signed byte/word/signed word/dword/signed dword) 1) goto print_points::@7 -- vbuxx_neq_vbuc1_then_la1 + cpx #NUM_POINTS-1+1 + bne b7 + //SEG57 print_points::@return + //SEG58 [26] return + rts + //SEG59 print_points::@7 + b7: + //SEG60 [27] (byte*~) print_char_cursor#60 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 + lda print_line_cursor + sta print_char_cursor + lda print_line_cursor+1 + sta print_char_cursor+1 + //SEG61 [11] phi from print_points::@7 to print_points::@1 [phi:print_points::@7->print_points::@1] + //SEG62 [11] phi (byte*) print_line_cursor#24 = (byte*) print_line_cursor#1 [phi:print_points::@7->print_points::@1#0] -- register_copy + //SEG63 [11] phi (byte*) print_char_cursor#45 = (byte*~) print_char_cursor#60 [phi:print_points::@7->print_points::@1#1] -- register_copy + //SEG64 [11] phi (byte) print_points::i#10 = (byte) print_points::i#1 [phi:print_points::@7->print_points::@1#2] -- register_copy + jmp b1 + str: .text " @" +} +//SEG65 print_ln +// Print a newline +print_ln: { + //SEG66 [29] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] + //SEG67 [29] phi (byte*) print_line_cursor#11 = (byte*) print_line_cursor#24 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy + //SEG68 print_ln::@1 + b1: + //SEG69 [30] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#11 + (byte/signed byte/word/signed word/dword/signed dword) $28 -- pbuz1=pbuz1_plus_vbuc1 + lda #$28 + clc + adc print_line_cursor + sta print_line_cursor + bcc !+ + inc print_line_cursor+1 + !: + //SEG70 [31] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#29) goto print_ln::@1 -- pbuz1_lt_pbuz2_then_la1 + lda print_line_cursor+1 + cmp print_char_cursor+1 + bcc b1 + bne !+ + lda print_line_cursor + cmp print_char_cursor + bcc b1 + !: + //SEG71 print_ln::@return + //SEG72 [32] return + rts +} +//SEG73 print_byte +// Print a byte as HEX +// print_byte(byte zeropage(4) b) +print_byte: { + .label b = 4 + //SEG74 [34] (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuz1_ror_4 + lda b + lsr + lsr + lsr + lsr + //SEG75 [35] (byte) print_char::ch#0 ← *((const byte[]) print_hextab#0 + (byte~) print_byte::$0) -- vbuaa=pbuc1_derefidx_vbuaa + tay + lda print_hextab,y + //SEG76 [36] call print_char + //SEG77 [41] phi from print_byte to print_char [phi:print_byte->print_char] + //SEG78 [41] phi (byte*) print_char_cursor#28 = (byte*) print_char_cursor#42 [phi:print_byte->print_char#0] -- register_copy + //SEG79 [41] phi (byte) print_char::ch#2 = (byte) print_char::ch#0 [phi:print_byte->print_char#1] -- register_copy + jsr print_char + //SEG80 print_byte::@1 + //SEG81 [37] (byte~) print_byte::$2 ← (byte) print_byte::b#2 & (byte/signed byte/word/signed word/dword/signed dword) $f -- vbuaa=vbuz1_band_vbuc1 + lda #$f + and b + //SEG82 [38] (byte) print_char::ch#1 ← *((const byte[]) print_hextab#0 + (byte~) print_byte::$2) -- vbuaa=pbuc1_derefidx_vbuaa + tay + lda print_hextab,y + //SEG83 [39] call print_char + //SEG84 [41] phi from print_byte::@1 to print_char [phi:print_byte::@1->print_char] + //SEG85 [41] phi (byte*) print_char_cursor#28 = (byte*) print_char_cursor#29 [phi:print_byte::@1->print_char#0] -- register_copy + //SEG86 [41] phi (byte) print_char::ch#2 = (byte) print_char::ch#1 [phi:print_byte::@1->print_char#1] -- register_copy + jsr print_char + //SEG87 print_byte::@return + //SEG88 [40] return + rts +} +//SEG89 print_char +// Print a single char +// print_char(byte register(A) ch) +print_char: { + //SEG90 [42] *((byte*) print_char_cursor#28) ← (byte) print_char::ch#2 -- _deref_pbuz1=vbuaa + ldy #0 + sta (print_char_cursor),y + //SEG91 [43] (byte*) print_char_cursor#29 ← ++ (byte*) print_char_cursor#28 -- pbuz1=_inc_pbuz1 + inc print_char_cursor + bne !+ + inc print_char_cursor+1 + !: + //SEG92 print_char::@return + //SEG93 [44] return + rts +} +//SEG94 print_str +// Print a zero-terminated string +// print_str(byte* zeropage(7) str) +print_str: { + .label str = 7 + //SEG95 [46] phi from print_str to print_str::@1 [phi:print_str->print_str::@1] + //SEG96 [46] phi (byte*) print_char_cursor#2 = (byte*) print_char_cursor#29 [phi:print_str->print_str::@1#0] -- register_copy + //SEG97 [46] phi (byte*) print_str::str#2 = (const string) print_points::str [phi:print_str->print_str::@1#1] -- pbuz1=pbuc1 + lda #print_points.str + sta str+1 + //SEG98 print_str::@1 + b1: + //SEG99 [47] if(*((byte*) print_str::str#2)!=(byte) '@') goto print_str::@2 -- _deref_pbuz1_neq_vbuc1_then_la1 + ldy #0 + lda (str),y + cmp #'@' + bne b2 + //SEG100 print_str::@return + //SEG101 [48] return + rts + //SEG102 print_str::@2 + b2: + //SEG103 [49] *((byte*) print_char_cursor#2) ← *((byte*) print_str::str#2) -- _deref_pbuz1=_deref_pbuz2 + ldy #0 + lda (str),y + sta (print_char_cursor),y + //SEG104 [50] (byte*) print_char_cursor#1 ← ++ (byte*) print_char_cursor#2 -- pbuz1=_inc_pbuz1 + inc print_char_cursor + bne !+ + inc print_char_cursor+1 + !: + //SEG105 [51] (byte*) print_str::str#0 ← ++ (byte*) print_str::str#2 -- pbuz1=_inc_pbuz1 + inc str + bne !+ + inc str+1 + !: + //SEG106 [46] phi from print_str::@2 to print_str::@1 [phi:print_str::@2->print_str::@1] + //SEG107 [46] phi (byte*) print_char_cursor#2 = (byte*) print_char_cursor#1 [phi:print_str::@2->print_str::@1#0] -- register_copy + //SEG108 [46] phi (byte*) print_str::str#2 = (byte*) print_str::str#0 [phi:print_str::@2->print_str::@1#1] -- register_copy + jmp b1 +} +//SEG109 print_cls +// Clear the screen. Also resets current line/char cursor. +print_cls: { + .label sc = 2 + //SEG110 [53] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] + //SEG111 [53] phi (byte*) print_cls::sc#2 = ((byte*))(word/signed word/dword/signed dword) $400 [phi:print_cls->print_cls::@1#0] -- pbuz1=pbuc1 + lda #<$400 + sta sc + lda #>$400 + sta sc+1 + //SEG112 [53] phi from print_cls::@1 to print_cls::@1 [phi:print_cls::@1->print_cls::@1] + //SEG113 [53] phi (byte*) print_cls::sc#2 = (byte*) print_cls::sc#1 [phi:print_cls::@1->print_cls::@1#0] -- register_copy + //SEG114 print_cls::@1 + b1: + //SEG115 [54] *((byte*) print_cls::sc#2) ← (byte) ' ' -- _deref_pbuz1=vbuc1 + lda #' ' + ldy #0 + sta (sc),y + //SEG116 [55] (byte*) print_cls::sc#1 ← ++ (byte*) print_cls::sc#2 -- pbuz1=_inc_pbuz1 + inc sc + bne !+ + inc sc+1 + !: + //SEG117 [56] if((byte*) print_cls::sc#1!=((byte*))(word/signed word/dword/signed dword) $400+(word/signed word/dword/signed dword) $3e8) goto print_cls::@1 -- pbuz1_neq_pbuc1_then_la1 + lda sc+1 + cmp #>$400+$3e8 + bne b1 + lda sc + cmp #<$400+$3e8 + bne b1 + //SEG118 print_cls::@return + //SEG119 [57] return + rts +} +//SEG120 init_points +// Initialize points +init_points: { + .label pointXpos1__0 = 2 + .label pointYpos1_return = 2 + .label i = 4 + //SEG121 [59] phi from init_points to init_points::@1 [phi:init_points->init_points::@1] + //SEG122 [59] phi (byte) init_points::pos#10 = (byte/signed byte/word/signed word/dword/signed dword) $a [phi:init_points->init_points::@1#0] -- vbuxx=vbuc1 + ldx #$a + //SEG123 [59] phi (byte) init_points::i#10 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:init_points->init_points::@1#1] -- vbuz1=vbuc1 + lda #0 + sta i + //SEG124 [59] phi from init_points::@3 to init_points::@1 [phi:init_points::@3->init_points::@1] + //SEG125 [59] phi (byte) init_points::pos#10 = (byte) init_points::pos#2 [phi:init_points::@3->init_points::@1#0] -- register_copy + //SEG126 [59] phi (byte) init_points::i#10 = (byte) init_points::i#1 [phi:init_points::@3->init_points::@1#1] -- register_copy + //SEG127 init_points::@1 + b1: + //SEG128 init_points::getPoint1 + //SEG129 [60] (byte) init_points::getPoint1_$0#0 ← (byte) init_points::i#10 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuaa=vbuz1_rol_1 + lda i + asl + //SEG130 [61] (byte*) init_points::pointXpos1_$0#0 ← (const byte[NUM_POINTS#0*SIZEOF_POINT#0]) points#0 + (byte) init_points::getPoint1_$0#0 -- pbuz1=pbuc1_plus_vbuaa + clc + adc #points + adc #0 + sta pointXpos1__0+1 + //SEG131 [62] phi from init_points::getPoint1 to init_points::pointXpos1 [phi:init_points::getPoint1->init_points::pointXpos1] + //SEG132 init_points::pointXpos1 + //SEG133 init_points::@2 + //SEG134 [63] *((byte*) init_points::pointXpos1_$0#0) ← (byte) init_points::pos#10 -- _deref_pbuz1=vbuxx + txa + ldy #0 + sta (pointXpos1__0),y + //SEG135 [64] (byte) init_points::pos#1 ← (byte) init_points::pos#10 + (byte/signed byte/word/signed word/dword/signed dword) $a -- vbuxx=vbuxx_plus_vbuc1 + txa + axs #-[$a] + //SEG136 init_points::pointYpos1 + //SEG137 [65] (byte*) init_points::pointYpos1_return#0 ← (byte*) init_points::pointXpos1_$0#0 + (byte/signed byte/word/signed word/dword/signed dword) 1 -- pbuz1=pbuz1_plus_1 + inc pointYpos1_return + bne !+ + inc pointYpos1_return+1 + !: + //SEG138 init_points::@3 + //SEG139 [66] *((byte*) init_points::pointYpos1_return#0) ← (byte) init_points::pos#1 -- _deref_pbuz1=vbuxx + txa + ldy #0 + sta (pointYpos1_return),y + //SEG140 [67] (byte) init_points::pos#2 ← (byte) init_points::pos#1 + (byte/signed byte/word/signed word/dword/signed dword) $a -- vbuxx=vbuxx_plus_vbuc1 + txa + axs #-[$a] + //SEG141 [68] (byte) init_points::i#1 ← ++ (byte) init_points::i#10 -- vbuz1=_inc_vbuz1 + inc i + //SEG142 [69] if((byte) init_points::i#1!=(const byte) NUM_POINTS#0-(byte/signed byte/word/signed word/dword/signed dword) 1+(byte/signed byte/word/signed word/dword/signed dword) 1) goto init_points::@1 -- vbuz1_neq_vbuc1_then_la1 + lda #NUM_POINTS-1+1 + cmp i + bne b1 + //SEG143 init_points::@return + //SEG144 [70] return + rts +} + print_hextab: .text "0123456789abcdef" + // All points + points: .fill NUM_POINTS*SIZEOF_POINT, 0 + diff --git a/src/test/ref/semi-struct-1.sym b/src/test/ref/semi-struct-1.sym new file mode 100644 index 000000000..c6981bd3c --- /dev/null +++ b/src/test/ref/semi-struct-1.sym @@ -0,0 +1,135 @@ +(label) @1 +(label) @begin +(label) @end +(byte) NUM_POINTS +(const byte) NUM_POINTS#0 NUM_POINTS = (byte/signed byte/word/signed word/dword/signed dword) 4 +(byte) SIZEOF_POINT +(const byte) SIZEOF_POINT#0 SIZEOF_POINT = (byte/signed byte/word/signed word/dword/signed dword) 2 +(void()) init_points() +(label) init_points::@1 +(label) init_points::@2 +(label) init_points::@3 +(label) init_points::@return +(label) init_points::getPoint1 +(byte~) init_points::getPoint1_$0 +(byte) init_points::getPoint1_$0#0 reg byte a 22.0 +(byte*~) init_points::getPoint1_$1 +(byte) init_points::getPoint1_idx +(byte*) init_points::getPoint1_return +(byte) init_points::i +(byte) init_points::i#1 i zp ZP_BYTE:4 16.5 +(byte) init_points::i#10 i zp ZP_BYTE:4 3.666666666666667 +(byte*) init_points::point +(label) init_points::pointXpos1 +(byte*~) init_points::pointXpos1_$0 +(byte*) init_points::pointXpos1_$0#0 pointXpos1_$0 zp ZP_WORD:2 8.25 +(byte*~) init_points::pointXpos1_$1 +(byte*) init_points::pointXpos1_point +(byte*) init_points::pointXpos1_return +(label) init_points::pointYpos1 +(byte*~) init_points::pointYpos1_$0 +(byte*~) init_points::pointYpos1_$1 +(byte*) init_points::pointYpos1_point +(byte*) init_points::pointYpos1_return +(byte*) init_points::pointYpos1_return#0 pointYpos1_return zp ZP_WORD:2 22.0 +(byte) init_points::pos +(byte) init_points::pos#1 reg byte x 11.0 +(byte) init_points::pos#10 reg byte x 6.6000000000000005 +(byte) init_points::pos#2 reg byte x 7.333333333333333 +(void()) main() +(label) main::@1 +(label) main::@return +(byte[NUM_POINTS#0*SIZEOF_POINT#0]) points +(const byte[NUM_POINTS#0*SIZEOF_POINT#0]) points#0 points = { fill( NUM_POINTS#0*SIZEOF_POINT#0, 0) } +(void()) print_byte((byte) print_byte::b) +(byte~) print_byte::$0 reg byte a 4.0 +(byte~) print_byte::$2 reg byte a 4.0 +(label) print_byte::@1 +(label) print_byte::@return +(byte) print_byte::b +(byte) print_byte::b#0 b zp ZP_BYTE:4 22.0 +(byte) print_byte::b#1 b zp ZP_BYTE:4 22.0 +(byte) print_byte::b#2 b zp ZP_BYTE:4 6.5 +(void()) print_char((byte) print_char::ch) +(label) print_char::@return +(byte) print_char::ch +(byte) print_char::ch#0 reg byte a 4.0 +(byte) print_char::ch#1 reg byte a 4.0 +(byte) print_char::ch#2 reg byte a 6.0 +(byte*) print_char_cursor +(byte*) print_char_cursor#1 print_char_cursor zp ZP_WORD:5 101.0 +(byte*) print_char_cursor#2 print_char_cursor zp ZP_WORD:5 45.142857142857146 +(byte*) print_char_cursor#28 print_char_cursor zp ZP_WORD:5 4.0 +(byte*) print_char_cursor#29 print_char_cursor zp ZP_WORD:5 6.6875 +(byte*) print_char_cursor#42 print_char_cursor zp ZP_WORD:5 8.0 +(byte*) print_char_cursor#45 print_char_cursor zp ZP_WORD:5 4.4 +(byte*~) print_char_cursor#60 print_char_cursor zp ZP_WORD:5 22.0 +(void()) print_cls() +(label) print_cls::@1 +(label) print_cls::@return +(byte*) print_cls::sc +(byte*) print_cls::sc#1 sc zp ZP_WORD:2 16.5 +(byte*) print_cls::sc#2 sc zp ZP_WORD:2 16.5 +(byte[]) print_hextab +(const byte[]) print_hextab#0 print_hextab = (string) "0123456789abcdef" +(byte*) print_line_cursor +(byte*) print_line_cursor#1 print_line_cursor zp ZP_WORD:2 46.42857142857143 +(byte*) print_line_cursor#11 print_line_cursor zp ZP_WORD:2 204.0 +(byte*) print_line_cursor#24 print_line_cursor zp ZP_WORD:2 1.0 +(void()) print_ln() +(label) print_ln::@1 +(label) print_ln::@return +(void()) print_points() +(label) print_points::@1 +(label) print_points::@2 +(label) print_points::@3 +(label) print_points::@4 +(label) print_points::@5 +(label) print_points::@6 +(label) print_points::@7 +(label) print_points::@return +(label) print_points::getPoint1 +(byte~) print_points::getPoint1_$0 +(byte) print_points::getPoint1_$0#0 reg byte a 22.0 +(byte*~) print_points::getPoint1_$1 +(byte) print_points::getPoint1_idx +(byte*) print_points::getPoint1_return +(byte) print_points::i +(byte) print_points::i#1 reg byte x 11.0 +(byte) print_points::i#10 reg byte x 2.5384615384615383 +(byte*) print_points::point +(label) print_points::pointXpos1 +(byte*~) print_points::pointXpos1_$0 +(byte*) print_points::pointXpos1_$0#0 pointXpos1_$0 zp ZP_WORD:9 5.5 +(byte*~) print_points::pointXpos1_$1 +(byte*) print_points::pointXpos1_point +(byte*) print_points::pointXpos1_return +(label) print_points::pointYpos1 +(byte*~) print_points::pointYpos1_$0 +(byte*~) print_points::pointYpos1_$1 +(byte*) print_points::pointYpos1_point +(byte*) print_points::pointYpos1_return +(byte*) print_points::pointYpos1_return#0 pointYpos1_return zp ZP_WORD:9 22.0 +(const string) print_points::str str = (string) " @" +(byte*) print_screen +(void()) print_str((byte*) print_str::str) +(label) print_str::@1 +(label) print_str::@2 +(label) print_str::@return +(byte*) print_str::str +(byte*) print_str::str#0 str zp ZP_WORD:7 202.0 +(byte*) print_str::str#2 str zp ZP_WORD:7 101.0 + +reg byte x [ print_points::i#10 print_points::i#1 ] +zp ZP_WORD:2 [ print_line_cursor#11 print_line_cursor#24 print_line_cursor#1 print_cls::sc#2 print_cls::sc#1 init_points::pointXpos1_$0#0 init_points::pointYpos1_return#0 ] +zp ZP_BYTE:4 [ print_byte::b#2 print_byte::b#0 print_byte::b#1 init_points::i#10 init_points::i#1 ] +reg byte a [ print_char::ch#2 print_char::ch#0 print_char::ch#1 ] +zp ZP_WORD:5 [ print_char_cursor#28 print_char_cursor#42 print_char_cursor#45 print_char_cursor#60 print_char_cursor#2 print_char_cursor#29 print_char_cursor#1 ] +zp ZP_WORD:7 [ print_str::str#2 print_str::str#0 ] +reg byte x [ init_points::pos#10 init_points::pos#2 ] +reg byte a [ print_points::getPoint1_$0#0 ] +zp ZP_WORD:9 [ print_points::pointXpos1_$0#0 print_points::pointYpos1_return#0 ] +reg byte a [ print_byte::$0 ] +reg byte a [ print_byte::$2 ] +reg byte a [ init_points::getPoint1_$0#0 ] +reg byte x [ init_points::pos#1 ] diff --git a/src/test/ref/semi-struct-2.asm b/src/test/ref/semi-struct-2.asm index e94954217..c42f38cb9 100644 --- a/src/test/ref/semi-struct-2.asm +++ b/src/test/ref/semi-struct-2.asm @@ -30,7 +30,7 @@ .label CIA1_PORT_B_DDR = $dc03 .const KEY_SPACE = $3c // The size of a file ENTRY - .const ENTRY_SIZE = $12 + .const SIZEOF_ENTRY = $12 // The maximal number of files .const MAX_FILES = $90 .label print_char_cursor = 6 @@ -912,7 +912,7 @@ mul8u: { .label mb = 2 .label res = 9 .label return = 9 - lda #ENTRY_SIZE + lda #SIZEOF_ENTRY sta mb lda #0 sta mb+1 @@ -958,4 +958,4 @@ keyboard_init: { // Keyboard matrix column bitmasks for a specific keybooard matrix column when reading the keyboard. (columns are numbered 0-7) keyboard_matrix_col_bitmask: .byte 1, 2, 4, 8, $10, $20, $40, $80 // All files - files: .fill MAX_FILES*ENTRY_SIZE, 0 + files: .fill MAX_FILES*SIZEOF_ENTRY, 0 diff --git a/src/test/ref/semi-struct-2.cfg b/src/test/ref/semi-struct-2.cfg index a4e98b21a..6b7f70c48 100644 --- a/src/test/ref/semi-struct-2.cfg +++ b/src/test/ref/semi-struct-2.cfg @@ -18,7 +18,7 @@ main::fileEntry1: scope:[main] from main to:main::@6 main::@6: scope:[main] from main::fileEntry1 [9] (word) main::fileEntry1_$0#0 ← (word) mul8u::return#2 - [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry1_$0#0 + [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry1_$0#0 to:main::fileEntry2 main::fileEntry2: scope:[main] from main::@6 [11] phi() @@ -27,7 +27,7 @@ main::fileEntry2: scope:[main] from main::@6 to:main::@7 main::@7: scope:[main] from main::fileEntry2 [14] (word) main::fileEntry2_$0#0 ← (word) mul8u::return#3 - [15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry2_$0#0 + [15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry2_$0#0 to:main::@5 main::@5: scope:[main] from main::@7 [16] (byte*) initEntry::entry#0 ← (byte*) main::entry1#0 @@ -530,7 +530,7 @@ mul8u: scope:[mul8u] from main::fileEntry1 main::fileEntry2 [253] (byte) mul8u::a#6 ← phi( main::fileEntry1/(const byte) main::fileEntry1_idx#0 main::fileEntry2/(const byte) main::fileEntry2_idx#0 ) to:mul8u::@1 mul8u::@1: scope:[mul8u] from mul8u mul8u::@3 - [254] (word) mul8u::mb#2 ← phi( mul8u/((word))(const byte) ENTRY_SIZE#0 mul8u::@3/(word) mul8u::mb#1 ) + [254] (word) mul8u::mb#2 ← phi( mul8u/((word))(const byte) SIZEOF_ENTRY#0 mul8u::@3/(word) mul8u::mb#1 ) [254] (word) mul8u::res#2 ← phi( mul8u/(byte/signed byte/word/signed word/dword/signed dword) 0 mul8u::@3/(word) mul8u::res#6 ) [254] (byte) mul8u::a#3 ← phi( mul8u/(byte) mul8u::a#6 mul8u::@3/(byte) mul8u::a#0 ) [255] if((byte) mul8u::a#3!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto mul8u::@2 diff --git a/src/test/ref/semi-struct-2.log b/src/test/ref/semi-struct-2.log index 3344a2ed7..1630e5a11 100644 --- a/src/test/ref/semi-struct-2.log +++ b/src/test/ref/semi-struct-2.log @@ -280,10 +280,10 @@ keyboard_key_pressed::@return: scope:[keyboard_key_pressed] from keyboard_key_p (byte*) print_screen#39 ← phi( @28/(byte*) print_screen#40 ) (byte*) print_char_cursor#181 ← phi( @28/(byte*) print_char_cursor#182 ) (byte*) print_line_cursor#99 ← phi( @28/(byte*) print_line_cursor#100 ) - (byte) ENTRY_SIZE#0 ← (byte/signed byte/word/signed word/dword/signed dword) $12 + (byte) SIZEOF_ENTRY#0 ← (byte/signed byte/word/signed word/dword/signed dword) $12 (byte) MAX_FILES#0 ← (byte/word/signed word/dword/signed dword) $90 (word~) $1 ← ((word)) (byte) MAX_FILES#0 - (word~) $2 ← (word~) $1 * (byte) ENTRY_SIZE#0 + (word~) $2 ← (word~) $1 * (byte) SIZEOF_ENTRY#0 (byte[$2]) files#0 ← { fill( $2, 0) } to:@52 main: scope:[main] from @52 @@ -304,7 +304,7 @@ main::fileEntry1: scope:[main] from main::@15 (byte*) print_screen#33 ← phi( main::@15/(byte*) print_screen#36 ) (byte) main::fileEntry1_idx#1 ← phi( main::@15/(byte) main::fileEntry1_idx#0 ) (byte) mul8u::a#1 ← (byte) main::fileEntry1_idx#1 - (byte) mul8u::b#0 ← (byte) ENTRY_SIZE#0 + (byte) mul8u::b#0 ← (byte) SIZEOF_ENTRY#0 call mul8u (word) mul8u::return#2 ← (word) mul8u::return#1 to:main::@16 @@ -340,7 +340,7 @@ main::fileEntry2: scope:[main] from main::@13 (byte*) main::entry1#7 ← phi( main::@13/(byte*) main::entry1#0 ) (byte) main::fileEntry2_idx#1 ← phi( main::@13/(byte) main::fileEntry2_idx#0 ) (byte) mul8u::a#2 ← (byte) main::fileEntry2_idx#1 - (byte) mul8u::b#1 ← (byte) ENTRY_SIZE#0 + (byte) mul8u::b#1 ← (byte) SIZEOF_ENTRY#0 call mul8u (word) mul8u::return#3 ← (word) mul8u::return#1 to:main::@17 @@ -1548,12 +1548,12 @@ SYMBOL TABLE SSA (byte*) CIA1_PORT_B#0 (byte*) CIA1_PORT_B_DDR (byte*) CIA1_PORT_B_DDR#0 -(byte) ENTRY_SIZE -(byte) ENTRY_SIZE#0 (byte) KEY_SPACE (byte) KEY_SPACE#0 (byte) MAX_FILES (byte) MAX_FILES#0 +(byte) SIZEOF_ENTRY +(byte) SIZEOF_ENTRY#0 (byte[$2]) files (byte[$2]) files#0 (void()) initEntry((byte*) initEntry::entry , (byte) initEntry::n) @@ -3162,7 +3162,7 @@ Constant (const byte*) CIA1_PORT_B_DDR#0 = ((byte*))$dc03 Constant (const byte) KEY_SPACE#0 = $3c Constant (const byte[8]) keyboard_matrix_row_bitmask#0 = { $fe, $fd, $fb, $f7, $ef, $df, $bf, $7f } Constant (const byte[8]) keyboard_matrix_col_bitmask#0 = { 1, 2, 4, 8, $10, $20, $40, $80 } -Constant (const byte) ENTRY_SIZE#0 = $12 +Constant (const byte) SIZEOF_ENTRY#0 = $12 Constant (const byte) MAX_FILES#0 = $90 Constant (const byte) main::fileEntry1_idx#0 = 1 Constant (const byte) main::fileEntry2_idx#0 = 2 @@ -3190,13 +3190,13 @@ Constant (const byte*) print_cls::sc#0 = print_line_cursor#0 Constant (const byte*) print_cls::$0 = print_line_cursor#0+$3e8 Constant (const word) $1 = ((word))MAX_FILES#0 Constant (const byte) mul8u::a#1 = main::fileEntry1_idx#0 -Constant (const byte) mul8u::b#0 = ENTRY_SIZE#0 +Constant (const byte) mul8u::b#0 = SIZEOF_ENTRY#0 Constant (const byte) mul8u::a#2 = main::fileEntry2_idx#0 -Constant (const byte) mul8u::b#1 = ENTRY_SIZE#0 +Constant (const byte) mul8u::b#1 = SIZEOF_ENTRY#0 Constant (const byte) keyboard_key_pressed::key#0 = KEY_SPACE#0 Constant (const byte) keyboard_key_pressed::key#1 = KEY_SPACE#0 Successful SSA optimization Pass2ConstantIdentification -Constant (const word) $2 = $1*ENTRY_SIZE#0 +Constant (const word) $2 = $1*SIZEOF_ENTRY#0 Successful SSA optimization Pass2ConstantIdentification Constant (const byte[$2]) files#0 = { fill( $2, 0) } Successful SSA optimization Pass2ConstantIdentification @@ -3308,7 +3308,7 @@ Constant inlined print_str::str#10 = (const string) printEntry::str5 Constant inlined print_str::str#17 = (const string) printEntry::str12 Constant inlined $1 = ((word))(const byte) MAX_FILES#0 Constant inlined print_str::str#16 = (const string) printEntry::str11 -Constant inlined $2 = ((word))(const byte) MAX_FILES#0*(const byte) ENTRY_SIZE#0 +Constant inlined $2 = ((word))(const byte) MAX_FILES#0*(const byte) SIZEOF_ENTRY#0 Constant inlined print_str::str#15 = (const string) printEntry::str10 Constant inlined print_str::str#14 = (const string) printEntry::str9 Constant inlined $3 = (const byte[]) print_hextab#0 @@ -3321,9 +3321,9 @@ Constant inlined print_cls::sc#0 = ((byte*))(word/signed word/dword/signed dword Constant inlined print_str::str#9 = (const string) printEntry::str4 Constant inlined mul8u::res#0 = (byte/signed byte/word/signed word/dword/signed dword) 0 Constant inlined mul8u::a#2 = (const byte) main::fileEntry2_idx#0 -Constant inlined mul8u::b#1 = (const byte) ENTRY_SIZE#0 +Constant inlined mul8u::b#1 = (const byte) SIZEOF_ENTRY#0 Constant inlined mul8u::a#1 = (const byte) main::fileEntry1_idx#0 -Constant inlined mul8u::b#0 = (const byte) ENTRY_SIZE#0 +Constant inlined mul8u::b#0 = (const byte) SIZEOF_ENTRY#0 Constant inlined print_str::str#4 = (const string) main::str1 Constant inlined print_str::str#3 = (const string) main::str2 Constant inlined print_str::str#2 = (const string) main::str1 @@ -3333,10 +3333,10 @@ Constant inlined print_str::str#7 = (const string) printEntry::str2 Constant inlined print_str::str#6 = (const string) printEntry::str1 Constant inlined print_str::str#5 = (const string) printEntry::str Successful SSA optimization Pass2ConstantInlining -Identical Phi Values (byte) mul8u::b#2 (const byte) ENTRY_SIZE#0 +Identical Phi Values (byte) mul8u::b#2 (const byte) SIZEOF_ENTRY#0 Identical Phi Values (byte) keyboard_key_pressed::key#2 (const byte) KEY_SPACE#0 Successful SSA optimization Pass2IdenticalPhiElimination -Constant (const word) mul8u::mb#0 = ((word))ENTRY_SIZE#0 +Constant (const word) mul8u::mb#0 = ((word))SIZEOF_ENTRY#0 Constant (const byte) keyboard_key_pressed::colidx#0 = KEY_SPACE#0&7 Constant (const byte) keyboard_key_pressed::rowidx#0 = KEY_SPACE#0>>3 Successful SSA optimization Pass2ConstantIdentification @@ -3346,7 +3346,7 @@ Consolidated array index constant in *(keyboard_matrix_row_bitmask#0+keyboard_ma Consolidated array index constant in *(keyboard_matrix_col_bitmask#0+keyboard_key_pressed::colidx#0) Successful SSA optimization Pass2ConstantAdditionElimination Inlining constant with var siblings (const word) mul8u::mb#0 -Constant inlined mul8u::mb#0 = ((word))(const byte) ENTRY_SIZE#0 +Constant inlined mul8u::mb#0 = ((word))(const byte) SIZEOF_ENTRY#0 Constant inlined keyboard_matrix_read::rowid#0 = (const byte) keyboard_key_pressed::rowidx#0 Successful SSA optimization Pass2ConstantInlining Added new block during phi lifting print_cls::@3(between print_cls::@1 and print_cls::@1) @@ -3564,7 +3564,7 @@ main::fileEntry1: scope:[main] from main to:main::@6 main::@6: scope:[main] from main::fileEntry1 [9] (word) main::fileEntry1_$0#0 ← (word) mul8u::return#2 - [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry1_$0#0 + [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry1_$0#0 to:main::fileEntry2 main::fileEntry2: scope:[main] from main::@6 [11] phi() @@ -3573,7 +3573,7 @@ main::fileEntry2: scope:[main] from main::@6 to:main::@7 main::@7: scope:[main] from main::fileEntry2 [14] (word) main::fileEntry2_$0#0 ← (word) mul8u::return#3 - [15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry2_$0#0 + [15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry2_$0#0 to:main::@5 main::@5: scope:[main] from main::@7 [16] (byte*) initEntry::entry#0 ← (byte*) main::entry1#0 @@ -4076,7 +4076,7 @@ mul8u: scope:[mul8u] from main::fileEntry1 main::fileEntry2 [253] (byte) mul8u::a#6 ← phi( main::fileEntry1/(const byte) main::fileEntry1_idx#0 main::fileEntry2/(const byte) main::fileEntry2_idx#0 ) to:mul8u::@1 mul8u::@1: scope:[mul8u] from mul8u mul8u::@3 - [254] (word) mul8u::mb#2 ← phi( mul8u/((word))(const byte) ENTRY_SIZE#0 mul8u::@3/(word) mul8u::mb#1 ) + [254] (word) mul8u::mb#2 ← phi( mul8u/((word))(const byte) SIZEOF_ENTRY#0 mul8u::@3/(word) mul8u::mb#1 ) [254] (word) mul8u::res#2 ← phi( mul8u/(byte/signed byte/word/signed word/dword/signed dword) 0 mul8u::@3/(word) mul8u::res#6 ) [254] (byte) mul8u::a#3 ← phi( mul8u/(byte) mul8u::a#6 mul8u::@3/(byte) mul8u::a#0 ) [255] if((byte) mul8u::a#3!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto mul8u::@2 @@ -4110,10 +4110,10 @@ VARIABLE REGISTER WEIGHTS (byte*) CIA1_PORT_A_DDR (byte*) CIA1_PORT_B (byte*) CIA1_PORT_B_DDR -(byte) ENTRY_SIZE (byte) KEY_SPACE (byte) MAX_FILES -(byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files +(byte) SIZEOF_ENTRY +(byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files (void()) initEntry((byte*) initEntry::entry , (byte) initEntry::n) (byte/signed word/word/dword/signed dword~) initEntry::$1 4.0 (byte/signed word/word/dword/signed dword~) initEntry::$11 4.0 @@ -4676,7 +4676,7 @@ INITIAL ASM .label CIA1_PORT_B_DDR = $dc03 .const KEY_SPACE = $3c // The size of a file ENTRY - .const ENTRY_SIZE = $12 + .const SIZEOF_ENTRY = $12 // The maximal number of files .const MAX_FILES = $90 .label print_char_cursor = $c @@ -4755,7 +4755,7 @@ main: { sta fileEntry1__0 lda mul8u.return+1 sta fileEntry1__0+1 - //SEG20 [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry1_$0#0 -- pbuz1=pbuc1_plus_vwuz2 + //SEG20 [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry1_$0#0 -- pbuz1=pbuc1_plus_vwuz2 lda fileEntry1__0 clc adc #mul8u::@1] b1_from_mul8u: - //SEG562 [254] phi (word) mul8u::mb#2 = ((word))(const byte) ENTRY_SIZE#0 [phi:mul8u->mul8u::@1#0] -- vwuz1=vbuc1 - lda #ENTRY_SIZE + //SEG562 [254] phi (word) mul8u::mb#2 = ((word))(const byte) SIZEOF_ENTRY#0 [phi:mul8u->mul8u::@1#0] -- vwuz1=vbuc1 + lda #SIZEOF_ENTRY sta mb lda #0 sta mb+1 @@ -6648,15 +6648,15 @@ keyboard_init: { // Keyboard matrix column bitmasks for a specific keybooard matrix column when reading the keyboard. (columns are numbered 0-7) keyboard_matrix_col_bitmask: .byte 1, 2, 4, 8, $10, $20, $40, $80 // All files - files: .fill MAX_FILES*ENTRY_SIZE, 0 + files: .fill MAX_FILES*SIZEOF_ENTRY, 0 REGISTER UPLIFT POTENTIAL REGISTERS Statement [8] (word) mul8u::return#2 ← (word) mul8u::res#2 [ mul8u::return#2 ] ( main:2 [ mul8u::return#2 ] ) always clobbers reg byte a Statement [9] (word) main::fileEntry1_$0#0 ← (word) mul8u::return#2 [ main::fileEntry1_$0#0 ] ( main:2 [ main::fileEntry1_$0#0 ] ) always clobbers reg byte a -Statement [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry1_$0#0 [ main::entry1#0 ] ( main:2 [ main::entry1#0 ] ) always clobbers reg byte a +Statement [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry1_$0#0 [ main::entry1#0 ] ( main:2 [ main::entry1#0 ] ) always clobbers reg byte a Statement [13] (word) mul8u::return#3 ← (word) mul8u::res#2 [ main::entry1#0 mul8u::return#3 ] ( main:2 [ main::entry1#0 mul8u::return#3 ] ) always clobbers reg byte a Statement [14] (word) main::fileEntry2_$0#0 ← (word) mul8u::return#3 [ main::entry1#0 main::fileEntry2_$0#0 ] ( main:2 [ main::entry1#0 main::fileEntry2_$0#0 ] ) always clobbers reg byte a -Statement [15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry2_$0#0 [ main::entry1#0 main::entry2#0 ] ( main:2 [ main::entry1#0 main::entry2#0 ] ) always clobbers reg byte a +Statement [15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry2_$0#0 [ main::entry1#0 main::entry2#0 ] ( main:2 [ main::entry1#0 main::entry2#0 ] ) always clobbers reg byte a Statement [16] (byte*) initEntry::entry#0 ← (byte*) main::entry1#0 [ main::entry1#0 main::entry2#0 initEntry::entry#0 ] ( main:2 [ main::entry1#0 main::entry2#0 initEntry::entry#0 ] ) always clobbers reg byte a Statement [18] (byte*) initEntry::entry#1 ← (byte*) main::entry2#0 [ main::entry1#0 main::entry2#0 initEntry::entry#1 ] ( main:2 [ main::entry1#0 main::entry2#0 initEntry::entry#1 ] ) always clobbers reg byte a Statement [26] (byte*~) print_line_cursor#159 ← (byte*) print_line_cursor#1 [ main::entry1#0 main::entry2#0 print_line_cursor#159 print_line_cursor#1 ] ( main:2 [ main::entry1#0 main::entry2#0 print_line_cursor#159 print_line_cursor#1 ] ) always clobbers reg byte a @@ -6792,10 +6792,10 @@ Statement [263] *((const byte*) CIA1_PORT_A_DDR#0) ← (byte/word/signed word/dw Statement [264] *((const byte*) CIA1_PORT_B_DDR#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2::keyboard_init:5 [ ] ) always clobbers reg byte a Statement [8] (word) mul8u::return#2 ← (word) mul8u::res#2 [ mul8u::return#2 ] ( main:2 [ mul8u::return#2 ] ) always clobbers reg byte a Statement [9] (word) main::fileEntry1_$0#0 ← (word) mul8u::return#2 [ main::fileEntry1_$0#0 ] ( main:2 [ main::fileEntry1_$0#0 ] ) always clobbers reg byte a -Statement [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry1_$0#0 [ main::entry1#0 ] ( main:2 [ main::entry1#0 ] ) always clobbers reg byte a +Statement [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry1_$0#0 [ main::entry1#0 ] ( main:2 [ main::entry1#0 ] ) always clobbers reg byte a Statement [13] (word) mul8u::return#3 ← (word) mul8u::res#2 [ main::entry1#0 mul8u::return#3 ] ( main:2 [ main::entry1#0 mul8u::return#3 ] ) always clobbers reg byte a Statement [14] (word) main::fileEntry2_$0#0 ← (word) mul8u::return#3 [ main::entry1#0 main::fileEntry2_$0#0 ] ( main:2 [ main::entry1#0 main::fileEntry2_$0#0 ] ) always clobbers reg byte a -Statement [15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry2_$0#0 [ main::entry1#0 main::entry2#0 ] ( main:2 [ main::entry1#0 main::entry2#0 ] ) always clobbers reg byte a +Statement [15] (byte*) main::entry2#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry2_$0#0 [ main::entry1#0 main::entry2#0 ] ( main:2 [ main::entry1#0 main::entry2#0 ] ) always clobbers reg byte a Statement [16] (byte*) initEntry::entry#0 ← (byte*) main::entry1#0 [ main::entry1#0 main::entry2#0 initEntry::entry#0 ] ( main:2 [ main::entry1#0 main::entry2#0 initEntry::entry#0 ] ) always clobbers reg byte a Statement [18] (byte*) initEntry::entry#1 ← (byte*) main::entry2#0 [ main::entry1#0 main::entry2#0 initEntry::entry#1 ] ( main:2 [ main::entry1#0 main::entry2#0 initEntry::entry#1 ] ) always clobbers reg byte a Statement [26] (byte*~) print_line_cursor#159 ← (byte*) print_line_cursor#1 [ main::entry1#0 main::entry2#0 print_line_cursor#159 print_line_cursor#1 ] ( main:2 [ main::entry1#0 main::entry2#0 print_line_cursor#159 print_line_cursor#1 ] ) always clobbers reg byte a @@ -7143,7 +7143,7 @@ ASSEMBLER BEFORE OPTIMIZATION .label CIA1_PORT_B_DDR = $dc03 .const KEY_SPACE = $3c // The size of a file ENTRY - .const ENTRY_SIZE = $12 + .const SIZEOF_ENTRY = $12 // The maximal number of files .const MAX_FILES = $90 .label print_char_cursor = 6 @@ -7215,7 +7215,7 @@ main: { sta fileEntry1__0 lda mul8u.return+1 sta fileEntry1__0+1 - //SEG20 [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry1_$0#0 -- pbuz1=pbuc1_plus_vwuz1 + //SEG20 [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry1_$0#0 -- pbuz1=pbuc1_plus_vwuz1 clc lda entry1 adc #mul8u::@1] b1_from_mul8u: - //SEG562 [254] phi (word) mul8u::mb#2 = ((word))(const byte) ENTRY_SIZE#0 [phi:mul8u->mul8u::@1#0] -- vwuz1=vbuc1 - lda #ENTRY_SIZE + //SEG562 [254] phi (word) mul8u::mb#2 = ((word))(const byte) SIZEOF_ENTRY#0 [phi:mul8u->mul8u::@1#0] -- vwuz1=vbuc1 + lda #SIZEOF_ENTRY sta mb lda #0 sta mb+1 @@ -9004,7 +9004,7 @@ keyboard_init: { // Keyboard matrix column bitmasks for a specific keybooard matrix column when reading the keyboard. (columns are numbered 0-7) keyboard_matrix_col_bitmask: .byte 1, 2, 4, 8, $10, $20, $40, $80 // All files - files: .fill MAX_FILES*ENTRY_SIZE, 0 + files: .fill MAX_FILES*SIZEOF_ENTRY, 0 ASSEMBLER OPTIMIZATIONS Removing instruction jmp b1 @@ -9390,14 +9390,14 @@ FINAL SYMBOL TABLE (const byte*) CIA1_PORT_B#0 CIA1_PORT_B = ((byte*))(word/dword/signed dword) $dc01 (byte*) CIA1_PORT_B_DDR (const byte*) CIA1_PORT_B_DDR#0 CIA1_PORT_B_DDR = ((byte*))(word/dword/signed dword) $dc03 -(byte) ENTRY_SIZE -(const byte) ENTRY_SIZE#0 ENTRY_SIZE = (byte/signed byte/word/signed word/dword/signed dword) $12 (byte) KEY_SPACE (const byte) KEY_SPACE#0 KEY_SPACE = (byte/signed byte/word/signed word/dword/signed dword) $3c (byte) MAX_FILES (const byte) MAX_FILES#0 MAX_FILES = (byte/word/signed word/dword/signed dword) $90 -(byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files -(const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 files = { fill( ((word))MAX_FILES#0*ENTRY_SIZE#0, 0) } +(byte) SIZEOF_ENTRY +(const byte) SIZEOF_ENTRY#0 SIZEOF_ENTRY = (byte/signed byte/word/signed word/dword/signed dword) $12 +(byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files +(const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 files = { fill( ((word))MAX_FILES#0*SIZEOF_ENTRY#0, 0) } (void()) initEntry((byte*) initEntry::entry , (byte) initEntry::n) (byte/signed word/word/dword/signed dword~) initEntry::$1 reg byte a 4.0 (byte/signed word/word/dword/signed dword~) initEntry::$11 reg byte a 4.0 @@ -9910,7 +9910,7 @@ Score: 4447 .label CIA1_PORT_B_DDR = $dc03 .const KEY_SPACE = $3c // The size of a file ENTRY - .const ENTRY_SIZE = $12 + .const SIZEOF_ENTRY = $12 // The maximal number of files .const MAX_FILES = $90 .label print_char_cursor = 6 @@ -9967,7 +9967,7 @@ main: { sta fileEntry1__0 lda mul8u.return+1 sta fileEntry1__0+1 - //SEG20 [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 + (word) main::fileEntry1_$0#0 -- pbuz1=pbuc1_plus_vwuz1 + //SEG20 [10] (byte*) main::entry1#0 ← (const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 + (word) main::fileEntry1_$0#0 -- pbuz1=pbuc1_plus_vwuz1 clc lda entry1 adc #mul8u::@1] - //SEG562 [254] phi (word) mul8u::mb#2 = ((word))(const byte) ENTRY_SIZE#0 [phi:mul8u->mul8u::@1#0] -- vwuz1=vbuc1 - lda #ENTRY_SIZE + //SEG562 [254] phi (word) mul8u::mb#2 = ((word))(const byte) SIZEOF_ENTRY#0 [phi:mul8u->mul8u::@1#0] -- vwuz1=vbuc1 + lda #SIZEOF_ENTRY sta mb lda #0 sta mb+1 @@ -11423,5 +11423,5 @@ keyboard_init: { // Keyboard matrix column bitmasks for a specific keybooard matrix column when reading the keyboard. (columns are numbered 0-7) keyboard_matrix_col_bitmask: .byte 1, 2, 4, 8, $10, $20, $40, $80 // All files - files: .fill MAX_FILES*ENTRY_SIZE, 0 + files: .fill MAX_FILES*SIZEOF_ENTRY, 0 diff --git a/src/test/ref/semi-struct-2.sym b/src/test/ref/semi-struct-2.sym index 07d75b243..3e8ab26a2 100644 --- a/src/test/ref/semi-struct-2.sym +++ b/src/test/ref/semi-struct-2.sym @@ -9,14 +9,14 @@ (const byte*) CIA1_PORT_B#0 CIA1_PORT_B = ((byte*))(word/dword/signed dword) $dc01 (byte*) CIA1_PORT_B_DDR (const byte*) CIA1_PORT_B_DDR#0 CIA1_PORT_B_DDR = ((byte*))(word/dword/signed dword) $dc03 -(byte) ENTRY_SIZE -(const byte) ENTRY_SIZE#0 ENTRY_SIZE = (byte/signed byte/word/signed word/dword/signed dword) $12 (byte) KEY_SPACE (const byte) KEY_SPACE#0 KEY_SPACE = (byte/signed byte/word/signed word/dword/signed dword) $3c (byte) MAX_FILES (const byte) MAX_FILES#0 MAX_FILES = (byte/word/signed word/dword/signed dword) $90 -(byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files -(const byte[((word))MAX_FILES#0*ENTRY_SIZE#0]) files#0 files = { fill( ((word))MAX_FILES#0*ENTRY_SIZE#0, 0) } +(byte) SIZEOF_ENTRY +(const byte) SIZEOF_ENTRY#0 SIZEOF_ENTRY = (byte/signed byte/word/signed word/dword/signed dword) $12 +(byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files +(const byte[((word))MAX_FILES#0*SIZEOF_ENTRY#0]) files#0 files = { fill( ((word))MAX_FILES#0*SIZEOF_ENTRY#0, 0) } (void()) initEntry((byte*) initEntry::entry , (byte) initEntry::n) (byte/signed word/word/dword/signed dword~) initEntry::$1 reg byte a 4.0 (byte/signed word/word/dword/signed dword~) initEntry::$11 reg byte a 4.0